` tag, configure in *FormElement.parameter*::
editor-forced_root_block=false
This might have impacts on the editor. See https://www.tinymce.com/docs/configure/content-filtering/#forced_root_block
* *FormElement.size*:
*
tail = * of the subrecord table.
* The column itself is not rendered.
* By using Bootstrap, the following predefined classes are available:
* Text color: *text-muted|text-primary|text-success|text-info|text-warning|text-danger* (http://getbootstrap.com/css/#helper-classes)
* Row background: *active|success|info|warning|danger* (http://getbootstrap.com/css/#tables-contextual-classes)
* *_rowTooltip*
* Defines the title attribute (=tooltip) of a subrecord table row.
* Examples::
{{!SELECT id, note1 AS 'Comment', note2 AS 'Comment|50' , note3 AS 'title=Comment|maxLength=100|nostrip', note4 AS '50|Comment',
'checked.png' AS 'Status|icon', email AS 'mailto', CONCAT(homepage, '|Homepage') AS 'url',
ELT(status,'info','warning','danger') AS '_rowClass', help AS '_rowTooltip' ...}}
* *FormElement.parameter*
* *form*: Target form, e.g. *form=person*
* *page*: Target page with detail form. If none specified, use the current page.
* *title*: Title displayed over the table in the current form.
* *extraDeleteForm*: Optional. The per row delete Button will reference the form specified here (for deleting) instead of the default (*form*).
* *detail*: Mapping of values from a) the primary form, b) the current row, c) any constant or '{{...}}' - to the target form (defined via `form=...`).
* Syntax::
tail =
rbeg =
rend =
fbeg =
fend =
}
Form: compute next free 'ord' automatically
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Requirement: new records should automatically get the highest number plus 10 for their 'ord' value. Existing records
should not be altered.
Version 1
'''''''''
Compute the next 'ord' in advance in the subrecord field of the primary form. Submit that value to the new record
via SIP parameter to the secondary form.
On the secondary form: for 'new' records choose the computed value, for existing records leave the value
unchanged.
* Master form, `subrecord` *FormElement*, field `parameter`: set ::
detail=id:formId,{{SELECT '&', IFNULL(fe.ord,0)+10 FROM Form AS f LEFT JOIN *FormElement* AS fe ON fe.formId=f.id WHERE
f.id={{r:S0}} ORDER BY fe.ord DESC LIMIT 1}}:ord
* Slave form, `ord` *FormElement*, field `value`: set
::
`{{ord:RS0}}`.
Version 2
'''''''''
Compute the next 'ord' as default value direct inside the secondary form. No change is needed for the primary form.
* Secondary form, `ord` *FormElement*, field `value`: set `{{SELECT IF({{ord:R0}}=0, MAX(IFNULL(fe.ord,0))+10,{{ord:R0}}) FROM (SELECT 1) AS a LEFT JOIN FormElement AS fe ON fe.formId={{formId:S0}} GROUP BY fe.formId}}`.
Form: Person Wizard - firstname, city
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Requirement: A form that displays the column 'firstname' from table 'Person' and 'city' from table 'Address'. If the
records not exist, the form should create it.
Form primary table: Person
Form slave table: Address
Relation: `Person.id = Address.personId`
* Form: wizard
* Name: wizard
* Title: Person Wizard
* Table: Person
* Render: bootstrap
* *FormElement*: firstname
* Class: **native**
* Type: **text**
* Name: firstname
* Label: Firstname
* *FormElement*: email, text, 20
* Class: **native**
* Type: **text**
* Name: city
* Label: City
* Value: `{{SELECT city FROM Address WHERE personId={{r}} ORDER BY id LIMIT 1}}`
* *FormElement*: insert/update address record
* Class: **action**
* Type: **afterSave**
* Label: Manage Address
* Parameter:
* `slaveId={{SELECT id FROM Address WHERE personId={{r}} ORDER BY id LIMIT 1}}`
* `sqlInsert={{INSERT INTO Address (personId, city) VALUES ({{r}}, '{{city:F:allbut:s}}') }}`
* `sqlUpdate={{UPDATE Address SET city='{{city:F:allbut:s}}' WHERE id={{slaveId:V}} }}`
* `sqlDelete={{DELETE FROM Address WHERE id={{slaveId:V}} AND ''='{{city:F:allbut:s}}' LIMIT 1}}`
Form: Person Wizard - firstname, single note
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Requirement: A form that displays the column 'firstname' from table 'Person' and 'note' from table 'Note'.
If the records don't exist, the form should create it.
Column Person.noteId points to Note.id
Form primary table: Person
Form slave table: Address
Relation: `Person.id = Address.personId`
* Form: wizard
* Name: wizard
* Title: Person Wizard
* Table: Person
* Render: bootstrap
* *FormElement*: firstname
* Class: **native**
* Type: **text**
* Name: firstname
* Label: Firstname
* *FormElement*: email, text, 20
* Class: **native**
* Type: **text**
* Name: note
* Label: Note
* Value: `{{SELECT Note FROM Note AS n, Person AS p WHERE p.id={{r}} AND p.noteId=n.id ORDER BY id }}`
* *FormElement*: insert/update address record
* Class: **action**
* Type: **afterSave**
* Name: noteId
* Label: Manage Note
* Parameter:
* `sqlInsert={{INSERT INTO Note (note) VALUES ('{{note:F:allbut:s}}') }}`
* `sqlUpdate={{UPDATE Note SET note='{{note:F:allbut:s}}' WHERE id={{slaveId:V}} }}`
.. _example_class_template_group:
Icons Template Group
^^^^^^^^^^^^^^^^^^^^
This example will display grafics instead of text 'add' and 'remove'. Also there is a distance between the templateGroups.
* FormElement.parameter::
tgClass = qfq-child-margin-top
tgAddClass = btn alert-success
tgAddText =
tgRemoveClass = btn btn-danger alert-danger
tgRemoveText =
Chart
^^^^^
* QFQ delivers a chart JavaScript lib: https://github.com/nnnick/Chart.js.git. Docs: http://www.chartjs.org/docs/
* The library is not sourced in the HTML page automatically. To do it, either include the lib
`typo3conf/ext/qfq/Resources/Public/JavaScript/Chart.min.js`:
* in the specific tt_content record (shown below in the example) or
* system wide via Typo3 Template record.
* By splitting HTML and JavaScript code over several lines, take care not accidently to create a 'nesting'-end token.
Check the line after `10.tail =`. It's '}' alone on one line. This is a valid 'nesting'-end token!. There are two options
to circumvent this:
* Don't nest the HTML & JavaScript code - bad workaround, this is not human readable.
* Select different nesting token, e.g. '<' / '>' (check the first line on the following example).
::
# <
10.sql = SELECT '_'
10.head =
Distribution of FormElement types over all forms
Email: {{mail:LE}}
* dynamicUpdate: checked
* Parameter::
# Typeahead
typeAheadLdapSearch = (|(cn=*?*)(mail=*?*))
typeAheadLdapValuePrintf ‘%s / %s’, cn, email
typeAheadLdapIdPrintf ‘%s’, email
# dynamicUpdate: show note
fillStoreLdap
ldapSearch = (mail={{email::alnumx}})
ldapAttributes = cn, email
* Name: fillLdapValues
* Class: action
* Type: afterSave
* Parameter::
fillStoreLdap
ldapSearch = (mail={{email::alnumx}})
ldapAttributes = cn, email
slaveId={{id:R0}}
sqlUpdate={{ UPDATE Person AS p SET p.name='{{cn:L:alnumx:s}}' WHERE p.id={{slaveId}} LIMIT 1 }}
FAQ
---
* Q: A variable {{}} is shown as empty string, but there should be a value.
* A: The sanitize rule is violeted and therefore the value has been removed. Set {{:
for example tells QFQ to seperate the rows of the result by a HTML-line break. The final result in this case is:
::
10.sql = SELECT id AS personId, CONCAT(firstName, " ", lastName, " ") AS name FROM person
10.sep =
HTML output:
::
John Doe
Jane Miller
Frank Star
..
.. _`syntax-of-report`:
Syntax of `report`
------------------
All **root level queries** will be fired in the order specified by 'level' (Integer value).
For **each** row of a query (this means *all* queries), all subqueries will be fired once.
* E.g. if the outer query selects 5 rows, and a nested query always select 3 rows, than the total number of rows are 5 x 3 = 15 rows.
There is a set of **variables** that will get replaced before the SQL-Query gets executed:
Column values of the recent rows: {{
10.10.sql = SELECT CONCAT(postal_code, " ", city) FROM address WHERE pId = {{10.pId}}
10.10.rbeg = (
10.10.rend = )
..
This would result in
::
John Doe (3004 Bern)
Jane Miller (8008 Zürich)
Frank Star (3012 Bern)
..
Text across several lines
^^^^^^^^^^^^^^^^^^^^^^^^^
To make SQL queries, or QFQ records in general, more readable, it's possible to split a line across several lines. Lines
with keywords are on their own (`QFQ Keywords (Bodytext)`_ start a new line). If a line is not a 'keyword' line, it will
be appended to the last keyword line. 'Keyword' lines are detected on:
*
20.tail =
Nesting of levels
^^^^^^^^^^^^^^^^^
Levels can be nested. E.g.: ::
10 {
sql = SELECT ...
5 {
sql = SELECT ...
head = ...
}
}
This is equal to: ::
10.sql = SELECT ...
10.5.sql = SELECT ...
10.5.head = ...
By default, curly braces '{}' are used for nesting. Alternatively angle braces '<>', round braces '()' or square
braces '[]' are also possible. To define the braces to use, the **first line** of the bodytext has to be a comment line and the
last character of that line must be one of '{}[]()<>'. The corresponding braces are used for that QFQ record. E.g.: ::
# Specific code. >
10 <
sql = SELECT
head =
>
Per QFQ tt-content record, only one type of nesting braces can be used.
Be careful to:
* write nothing else than whitespaces/newline behind an **open brace**
* the **closing brace** has to be alone on a line. ::
10.sql = SELECT 'Yearly Report'
20 {
sql = SELECT companyName FORM Company LIMIT 1
head =
tail =
}
30 {
sql = SELECT depName FROM Department
head =
`. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| _striptags |HTML Tags will be stripped. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| _htmlentities |Characters will be encoded to their HTML entity representation. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| _+??? |The content will be wrapped in the tag '???'. Example: SELECT 'example' AS '_+a href="http://example.com"' creates 'example' |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|_', default link class: internal. |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Edit |E |E |Show 'edit' icon as image |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |New |N |N |Show 'new' icon as image |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Delete |D |D |Show 'delete' icon as image (only the icon, no database record 'delete' functionality) |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Help |H |H |Show 'help' icon as image |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Info |I |I |Show 'information' icon as image |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Show |S |S |Show 'show' icon as image |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Glyph |G:
|
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "p:form_person|E|g:_blank" AS _link |
|
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "p:form_person|C" AS _link |
|
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "p:form_person|C:green" AS _link |
|
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "U:form=Person&r=123|x|D" as _link | "> |
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "U:form=Person&r=123|x|t:Delete" as _link | Delete |
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "s:1|d:full.pdf|M:pdf|U:id=det1&r=12|U:id=det2|f:cv.pdf| | Download |
| t:Download|a:Create complete PDF - please wait" as _link | |
+-----------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
.. _question:
Question
^^^^^^^^
**Syntax**
::
q[: