Form.rst 186 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
.. ==================================================
.. ==================================================
.. ==================================================
.. Header hierarchy
.. ==
..  --
..   ^^
..    ""
..     ;;
..      ,,
..
.. --------------------------------------------used to the update the records specified ------
.. Best Practice T3 reST: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/CheatSheet.html
..             Reference: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/Index.html
.. Italic *italic*
.. Bold **bold**
.. Code ``text``
.. External Links: `Bootstrap <http://getbootstrap.com/>`_
.. Add Images:    .. image:: ../Images/a4.jpg
..
..
.. Admonitions
..           .. note::   .. important::     .. tip::     .. warning::
.. Color:   (blue)       (orange)           (green)      (red)
..
.. Definition:
.. some text becomes strong (only one line)
..      description has to indented

.. -*- coding: utf-8 -*- with BOM.

.. include:: Includes.txt


Form
====

General
-------

* Forms will be created by using the *Form Editor* on the Typo3 frontend (HTML form).
* The *Form editor* itself consist of two predefined QFQ forms: *form* and *formElement* - these forms are often updated
  during the installation of new QFQ versions.
* Every form consist of a) a *Form* record and b) multiple *FormElement* records.
* A form is assigned to a  *table*. Such a table is called the *primary table* for this form.
* Forms can roughly categorized into:

  * *Simple* form: the form acts on one record, stored in one table.

    * The form will create necessary SQL commands for insert, update and delete (only primary record) automatically.

  * *Advanced* form: the form acts on multiple records, stored in more than one table.

    * Fields of the primary table acts like a *simple* form, all other fields have to be specified with *action/afterSave* records.

  * *Multi* form: (multi-form_) the form acts simultaneously on more than one record. All records use the same *FormElements*.

    * The *FormElements* are defined as a regular *simple* / or *advanced* form, plus an SQL Query, which selects and
      iterates over all records. Those records will be loaded at the same time.

  * *Delete* form: any form can be used as a form to :ref:`delete-record`.

* Form mode: The parameter 'r' (given via URL or via SIP) decide if the form is in mode:

  * `New`:

    * Missing parameter 'r' or 'r=0'
    * On form load, no record is displayed.
    * Saving the form creates a new primary record.
    * E.g.: `http://example.com/index.php?id=home&form=Person`  or `http://example.com/index.php?id=home&form=Person&r=0`

  * `Edit`:

    * Parameter 'r>0'
    * On form load, the specified record (<tablename>.id= <r>) will be loaded and displayed.
    * Saving the form will update the existing record.
    * E.g.: `http://example.com/index.php?id=home&form=Person&r=123`

  * Providing additional parameter:

    Often, it is necessary to store additional, for the user not visible, parameter in a record. See :ref:`form-magic`.

* Display a form:

  * Create a QFQ tt_content record on a Typo 3 page.
  * Inside the QFQ record: `form  = <formname>`. E.g.:

    * Static: `form = Person`
    * Dynamic 1: `form  = {{form:SE}}`  (the left `form` is a keyword for QFQ, the right `form` is a variable name)
    * Dynamic 2: `form  = {{SELECT f.name FROM Form AS f WHERE f.id=...}}`  (the left `form` is a keyword for QFQ, the right `form` is a variable name)

  * With the `Dynamic` option, it's easily possible to use one Typo3 page and display different forms on that specific
    page.

Marc Egger's avatar
Marc Egger committed
95
96
* Forms are synced between the database and form files. See :ref:`formAsfile`.

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
Form process order
------------------

Depending on `form load / save` or `record delete`, different tasks are performed. Processing is divided into:

* Native FormElements like: `input`, `select list`, `checkbox`, `radio`, ....

  * `upload` elements are categorized as native FormElement, but will be processed later.
  * `pill`, `fieldset` and `subrecord` elements are only processed during form load, they do not impact `save` or `delete`.

* Action FormElement like `before...`, `after...`, `sendmail` ...

Each FormElement has an order.

Native FormElements which 'name':

* corresponds to a column in the form primary table: are grouped together in one insert or update query.
* do not correspond to a column in the primary table: needs an explicit defined Action FormElement to be handled.

FormElement processing order:

.. image:: Images/FormProcess.png

.. _record_locking:

Record locking
--------------

Forms and 'record delete'-function support basic record locking. A user opens a form: starting with the first change of content, a
record lock will be acquired in the background. If the lock is denied (e.g. another user already owns a lock on the record) an
alert is shown.
By default the record lock mode is 'exclusive' and the default timeout is 15 minutes. Both can be configured per form.
The general timeout can also be configured in :ref:`configuration` (will be copied to the form during creating the form).

The lock timeout counts from the first change, not from the last modification on the form.

If a timeout expires, the lock becomes invalid. During the next change in a form, the lock is acquired again.

A lock is assigned to a record of a table. Multiple forms, with the same primary table, uses the same lock for a given record.

If a `Form` acts on further records (e.g. via FE action), those further records are not protected by this basic record locking.

If a user tries to delete a record and another user already owns a lock on that record, the delete action is denied.

If there are different locking modes in multiple forms, the most restricting mode applies for the current lock.

Exclusive
^^^^^^^^^

An existing lock on a record forbids any write action on that record.

Advisory
^^^^^^^^

An existing lock on a record informs the user that another user is currently working on that record. Nevertheless,
writing is allowed.

None
^^^^

No locking at all.

.. _comment-space-character:

Comment- and space-character
----------------------------

The following applies to the fields `Form.parameter` and `FormElement.parameter`:

* Lines will be trimmed - leading and trailing spaces will be removed.
* If a leading and/or trailing space is needed, escape it: \\ hello world \\ > ' hello world '.
* Lines starting with a '#' are treated as a comment and will not be parsed. Such lines are treated as 'empty lines'.
* The comment sign can be escaped with \\ .

.. _form-main:

173
174
Form Settings
-------------
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Name                    | Description                                                                                                                                        |
+=========================+====================================================================================================================================================+
|Name                     | Unique and speaking name of the *Form*. Form will be identified by this name. Use only '[a-zA-Z0-9._+-]'. _`form-name`                             |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Title                    | Title, shown on/above the form. _`form-title`                                                                                                      |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Note                     | Personal editor notes. _`form-note`                                                                                                                |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Table                    | Primary table of the form. _`form-tablename`                                                                                                       |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Primary Key              | Primary key of the indicated table. Only needed if != 'id'. _`form-primary-key`                                                                    |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Required Parameter NEW   | Name of required SIP parameter to create a new record (r=0), separated by comma. '#' as comment delimiter. See :ref:`form-requiredParameter`       |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Required Parameter EDIT  | Name of required SIP parameter to edit an existing record (r>0), separated by comma. '#' as comment delimiter. See :ref:`form-requiredParameter`   |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Permit New               | 'sip, logged_in, logged_out, always, never' (Default: sip): See :ref:`form-permitNewEdit`                                                          |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Permit Edit              | 'sip, logged_in, logged_out, always, never' (Default: sip): See :ref:`form-permitNewEdit`                                                          |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
197
198
|Permit REST              | See :ref:`restApi`                                                                                                                                 |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
199
200
201
202
203
204
205
206
207
|Escape Type Default      | See :ref:`variable-escape`.                                                                                                                        |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Show button              | 'new, delete, close, save' (Default: 'new,delete,close,save'): Shown named buttons in the upper right corner of the form.                          |
|                         | See :ref:`form-showButton`                                                                                                                         |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Forward Mode             | 'auto | close | no | url | url-skip-history | url-sip | url-sip-skip-history' (Default: auto): See :ref:`form-forward`.                            |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Forward (Mode) Page      | a) URL / Typo3 page id/alias or b) Forward Mode (via '{{...}}') or combination of a) & b). See :ref:`form-forward`.                                |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
208
|labelAlign               | Label align (default/left/center/right)/ Default: 'default' (defined by Config). _`form-label-align`                                               |
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Parameter                |  Misc additional parameters. See :ref:`form-parameter`.                                                                                            |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|BS Label Columns         | The bootstrap grid system is based on 12 columns. The sum of *bsLabelColumns*,                                                                     |
+-------------------------+ *bsInputColumns* and *bsNoteColumns* should be 12. These values here are the base values                                                           |
|BS Input Columns         | for all *FormElements*. Exceptions per *FormElement* can be specified per *FormElement*.                                                           |
+-------------------------+ Default: label=col-md-3, input=col-md-6, note=col-md-3. See :ref:`form-layout`.                                                                    |
|BS Note Columns          |                                                                                                                                                    |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|multiMode                | NOT IMPLEMENTED - 'none, horizontal, vertical' (Default 'none')                                                                                    |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|multiSql                 | NOT IMPLEMENTED - Optional. SQL Query which selects all records to edit.                                                                           |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|multiDetailForm          | NOT IMPLEMENTED - Optional. Form to open, if a record is selected to edit (double click on record line)                                            |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|multiDetailFormParameter | NOT IMPLEMENTED - Optional. Translated Parameter submitted to detailform (like subrecord parameter)                                                |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+

.. _`form-permitNewEdit`:

permitNew & permitEdit
^^^^^^^^^^^^^^^^^^^^^^

Depending on `r`, the following access permission will be taken:

* `r=0` - permitNew
* `r>0` - permitEdit


+------------+---------------------------------------------------------------------------------------------------+
| Option     | Description                                                                                       |
+============+===================================================================================================+
| sip        | The parameter 'form' and 'r' must be supplied via SIP or hard coded in the QFQ tt_content record. |
+------------+---------------------------------------------------------------------------------------------------+
| logged_in  | The form will only be shown if the current User is logged in as a FE User                         |
+------------+---------------------------------------------------------------------------------------------------+
| logged_out | The form will only be shown if the current User is *not* logged in as a FE User                   |
+------------+---------------------------------------------------------------------------------------------------+
| always     | No access restriction, the form will always be shown                                              |
+------------+---------------------------------------------------------------------------------------------------+
| never      | The form will never be shown                                                                      |
+------------+---------------------------------------------------------------------------------------------------+


* `sip`

  * is *always* the preferred way. With 'sip' it's not necessary to differ between logged in or not, cause the SIP
    only  exist and is only valid, if it's created via QFQ/report earlier. This means 'creating' the SIP implies
    'access granted'. The grant will be revoked when the QFQ session is destroyed - this happens when a user loggs out or
    the web browser is closed.

* `logged_in` / `logged_out`: for forms which might be displayed without a SIP, but maybe on a protected or even
  unprotected page. *The option is probably not often used.*

* `always`: such a form is always allowed to be loaded.

  * `permitNew=always`: Public accessible forms (e.g. for registration) will allow users to fill and save
    the form.

  * `permitEdit=always`: Public accessible forms will allow users to update existing data. This
    is dangerous, cause the URL parameter (recordId) 'r' might be changed by the user (URL manipulating) and therefore
    the user might see and/or change data from other users. *The option is probably not often used.*

* `never`: such a form is not allowed to be loaded.

  * `permitNew=never`: Public accessible forms. It's not possible to create new records.

  * `permitEdit=none`: Public accessible forms. It's not possible to update records.


.. _`form-requiredParameter`:

Required Parameter New|Edit
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Comma separated list of variable names. On form load, an error message will be shown in case of missing parameters.
The parameters must be given by SIP.

The list of required parameter has to be defined for `New` (r=0, create a new record) and for `Edit` (r>0, edit existing
record).

Optional a comment might be attached after the parameter definition.

E.g.: ::

  New: grId, pId # Always specify a person, grId2
  Edit: pId

.. _`form-showButton`:

showButton
^^^^^^^^^^

Display or hide the button `new`, `delete`, `close`, `save`.

* *new*: Creates a new record. If the form needs any special parameter via SIP or Client (=browser), hide this 'new' button - the necessary parameter are not provided.
* *delete*: This either deletes the current record only, or (if defined via action *FormElement* 'beforeDelete' ) any specified subrecords.
* *close*: Close the current form. If there are changes, a popup opens and ask to save / close / cancel. The last page from the history will be shown.
* *save*: Save the form.

* Default: show all buttons.

.. _`form-forward`:

Forward: Save / Close
^^^^^^^^^^^^^^^^^^^^^

Forward (=forwardMode)
""""""""""""""""""""""

After the user presses *Save*, *Close*, *Delete* or *New*, different actions are possible where the browser redirects to.

* `auto` (default) - the QFQ browser Javascript logic, decides to stay on the page or to force a redirection
  to a previous page. The decision depends on:

  * *Close* goes back (feels like close) to the previous page. Note: if there is no history, QFQ won't close the tab,
    instead a message is shown.
  * *Save* stays on the current page.

* `close` - goes back (feels like close) to the previous page. Note: if there is no history, QFQ won't close the tab,
  instead a message is shown.
* `no` - no change, the browser remains on the current side. Close does not close the page. It just triggers a save if
  there are modified data.
* `url` - the browser redirects to the URL or T3 page named in `Forward URL / Page`. Independent if the user presses `save` or `close`.
* `url-skip-history` - same as `url`, but the current location won't saved in the browser history.
* `url-sip` - like `url`, but any given parameter will be SIP encoded. Only useful if `url` points to current web instance.
* `url-sip-skip-history` - like `url-sip`, but skips the Browser history.


Only with `Forward` == `url` | `url-skip-history`, the definition of `Forward URL / Page` becomes active.

Forward URL / Page (=forwardPage)
"""""""""""""""""""""""""""""""""

Format: [<url>] or [<mode>|<url>]

* `<url>`:

  * `http://www.example.com/index.html?a=123#bottom`
  * `website.html?a=123#bottom`
  * `?id=<T3 Alias pageid>&a=123#bottom, ?id=<T3 page id>&a=123#bottom`
  * `{{SELECT ...}}`
  * `<mode>|<url>`

* `<mode>` - Valid keywords are as above: `auto|close|no|url|url-skip-history|url-sip|url-sip-skip-history`

Specifying the mode in `forwardPage` overwrites `formMode` (but only if `formMode` is `url...`).

Also regular QFQ statements like {{var}} or {{SELECT ...}} are possible in `forwardPage`. This is useful to dynamically
redirect to different targets, depending on user input or any other dependencies.

If a forwardMode 'url...' is specified and there is no `forwardPage`, QFQ falls down to `auto` mode.

On a form, the user might click 'save' or 'save,close' or 'close' (with modified data this leads to 'save,close').
The CLIENT `submit_reason` shows the user action:

* `{{submit_reason:CE:alnumx}}` = `save` or `save,close`

Example forwardPage
^^^^^^^^^^^^^^^^^^^

* `{{SELECT IF('{{formModeGlobal:S}}'='requiredOff', 'no', 'auto') }}`
* `{{SELECT IF('{{submit_reason:CE:alnumx}}'='save', 'no', 'url'), '|http://example.com' }}`

Type: combined dynamic mode & URL/page
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax: `forwardPage=<mode>|<page>`

* `forwardPage={{SELECT IF(a.url='','no','url'), '|', a.url FROM Address AS a }}`


.. _form-parameter:

Parameter
^^^^^^^^^

* The following parameter are optional and can be configured in the *Form.parameter* field.

+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| Name                        | Type   | Description                                                                                              |
+=============================+========+==========================================================================================================+
| dbIndex                     | int    | Database credential index, given via :ref:`config-qfq-php` to let the current `Form`                     |
|                             |        | operate on the database.                                                                                 |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| bsColumns                   | string | Wrap the whole form in '<div class="col-md-.. col-lg-..">. See  :ref:`bs-custom-field-width`.            |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| maxVisiblePill              | int    | Show pills upto <maxVisiblePill> as button, all further in a drop-down menu. Eg.: maxVisiblePill=3.      |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| class                       | string | HTML div with given class, surrounding the whole form. Eg.: class=container-fluid.                       |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| classTitle                  | string | CSS class inside of the `title` div. Default 'qfq-form-title'.                                           |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| classPill                   | string | HTML div with given class, surrounding the `pill` title line.                                            |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| classBody                   | string | HTML div with given class, surrounding all *FormElement*.                                                |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| extraDeleteForm             | string | Name of a form which specifies how to delete the primary record and optional slave records.              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| data-pattern-error          | string | Pattern violation: Text for error message used for all FormElements of current form.                     |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| data-required-error         | string | Required violation: Text for error message used for all FormElements of current form.                    |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| data-match-error            | string | Match violation: Text for error message used for all FormElements of current form.                       |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| data-error                  | string | If none specific is defined: Text for error message used for all FormElements of current form.           |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| buttonOnChangeClass         | string | Color for save button after user modified some content or current form. E.g.: 'btn-info alert-info'.     |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| ldapServer                  | string | FQDN Ldap Server. E.g.: directory.example.com.                                                           |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| ldapBaseDn                  | string | E.g.: `ou=Addressbook,dc=example,dc=com`.                                                                |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| ldapAttributes              | string | List of attributes to fill STORE_LDAP with. E.g.: cn, email.                                             |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| ldapSearch                  | string | E.g.: `(mail={{email::alnumx:l}})`                                                                       |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| ldapTimeLimit               | int    | Maximum time to wait for an answer of the LDAP Server.                                                   |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadLdap               |        | Enable LDAP as 'Typeahead' data source.                                                                  |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadLdapSearch         | string | Regular LDAP search expression. E.g.:  `(|(cn=*?*)(mail=*?*))`                                           |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadLdapValuePrintf    | string | Value formatting of LDAP result, per entry. E.g.: `'%s / %s / %s', mail, roomnumber, telephonenumber`    |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadLdapIdPrintf       | string | Key formatting of LDAP result, per entry. E.g.: `'%s', mail`                                             |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadLdapSearchPerToken |        | Split search value in token and OR-combine every search with the individual tokens.                      |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadLimit              | int    | Maximum number of entries. The limit is applied to the server (LDAP or SQL) and the Client.              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| typeAheadMinLength          | int    | Minimum number of characters which have to typed to start the search.                                    |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| mode                        | string | The value `readonly` will activate a global readonly mode of the form - the user can't change any data.  |
|                             |        | See :ref:`form-mode-global`                                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| activateFirstRequiredTab    | digit  | 0: off, 1: (default) - with formModeGlobal=requiredOffButMark bring pill to front on save.               |
|                             |        | See :ref:`form-mode-global`                                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| enterAsSubmit               | digit  | 0: off, 1: Pressing *enter* in a form means *save* and *close*. Takes default from :ref:`configuration`. |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| submitButtonText            | string | Show a save button at the bottom of the form, with <submitButtonText> . See :ref:`submitButtonText`.     |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| saveButtonActive            |        | 0: off, 1: Make the 'save'-button active on *Form* load (instead of waiting for the first user change).  |
|                             |        | The save button is still 'gray' (record not dirty), but the user can click 'save'.                       |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| saveButtonText              | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| saveButtonTooltip           | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| saveButtonClass             | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| saveButtonGlyphIcon         | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| closeButtonText             | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| closeButtonTooltip          | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| closeButtonClass            | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| closeButtonGlyphIcon        | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| deleteButtonText            | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| deleteButtonTooltip         | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| deleteButtonClass           | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| deleteButtonGlyphIcon       | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| newButtonText               | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| newButtonTooltip            | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| newButtonClass              | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| newButtonGlyphIcon          | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| extraButtonInfoClass        | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| extraButtonInfoMinWidth     | string | See :ref:`extraButtonInfo`                                                                               |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| fillStoreVar                | string | Fill the STORE_VAR with custom values. See :ref:`STORE_VARS`.                                            |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| showIdInFormTitle           | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| formSubmitLogMode           | string | Overwrite default from :ref:`configuration`                                                              |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| sessionTimeoutSeconds       | int    | Overwrite default from :ref:`configuration` . See :ref:`sessionTimeoutSeconds`.                          |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| maxFileSize                 | int    | Overwrite default from :ref:`configuration` .                                                            |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+
| requiredPosition            | int    | See :ref:`requiredPosition` .                                                                            |
+-----------------------------+--------+----------------------------------------------------------------------------------------------------------+

* Example:

  * maxVisiblePill = 5
  * class = container-fluid
  * classBody = qfq-form-right

.. _submitButtonText:

submitButtonText
""""""""""""""""

If specified and non empty, display a regular submit button at the bottom of the page with the given text.
This gives the form a ordinary HTML-form look'n' feel. With this option, the standard buttons on the top right border
should be hided to not confuse the user.

* Optional.
* Default: Empty

class
"""""

* Optional.
* Default: `container`
* Any CSS class name(s) can be specified.
* Check `typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css` for predefined classes.
* Typical use: adjust the floating rules of the form.

  * See: http://getbootstrap.com/docs/3.4/css/#overview-container
  * Expand the form over the whole area: `container-fluid`

classPill
"""""""""

* Optional.
* Default: `qfq-color-grey-1`
* Any CSS class name(s) can be specified.
* Check `typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css` for predefined classes.
* Typical use: adjust the background color of the `pill title` area.
* Predefined background colors: `qfq-color-white`, `qfq-color-grey-1` (dark), `qfq-color-grey-2` (light),
  `qfq-color-blue-1` (dark), `qfq-color-blue-2`. (light)
* `classPill` is only visible on forms with container elements of type 'Pill'.

classBody
"""""""""

* Optional.
* Default: `qfq-color-grey-2`
* Any CSS class name(s) can be specified.
* Check `typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css` for predefined classes.
* Typical use:

  * adjust the background color of the *FormElement* area.
  * make all form labels right align: `qfq-form-right`.

* Predefined background colors: `qfq-color-white`, `qfq-color-grey-1` (dark), `qfq-color-grey-2` (light),
  `qfq-color-blue-1` (dark), `qfq-color-blue-2`. (light)

extraDeleteForm
"""""""""""""""

Depending on the database definition, it might be necessary to delete the primary record *and* corresponding slave records.
To not repeat such 'slave record delete definition', an 'extraDeleteForm' can be specified. If the user opens a record
in a form and clicks on the 'delete' button, a defined 'extraDeleteForm'-form will be used to delete primary and slave
records instead of using the current form.
E.g. if there are multiple different forms to work on the same table, all of theses forms might reference to the same
'extraDeleteForm'-form. This simplifies the maintenance.

The 'extraDeleteForm' parameter might be specified for a 'form' and/or for 'subrecords'

See also: :ref:`delete-record`.

.. _form-mode-global:

Form mode global
""""""""""""""""

A form can be operated in modes: *standard* | **readonly** | **requiredOff** | **requiredOffButMark**.

Mode *standard* is given if none of the others are defined.

The `mode` is given via (in this priority):

* Via STORE_USER: {{formModeGlobal:U}}
* Via STORE_SIP: {{formModeGlobal:S}}
* Via Form: `form.parameter.formModeGlobal=...`

Mode
;;;;

593
* **standard**:
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889

  * The form will behave like defined in the form editor.
  * Missing required values will a) be indicated and b) block saving the record.

* **readonly**: all `FormElement` of the whole form are temporarily in `readonly` mode.

  * Fast way to display the form data, without a possibility for the user to change any data of the form.
  * The mode will be be inherited to all subforms.

* **requiredOff**:

  * All `FormElement` with `mode=required`, will be handled as `mode=show`.
  * The user can save the form without filling all required inputs!
  * Required inputs are indicated by a red star - missing values **won't** be complained.

* **requiredOffButMark**:

  * All `FormElement` with `mode=required`, will be handled as `mode=show`.
  * The user can save the form without filling all required inputs!
  * Missing required inputs will be marked:

    * On lost focus.
    * When the user saves the record.

      * After saving the record, by default the first pill with a missing input comes to front.
      * This behaviour can be switch on/off with `form.parameter.activateFirstRequiredTab=0`

Extra
;;;;;

Via :ref:`STORE_VARS` the variable `{{allRequiredGiven:V}}` shows, if the form has been filled completely - independent of
the mode. The variable is only accessible during form save.

Usage example
;;;;;;;;;;;;;

*Readonly*

Code: ``SELECT 'p:{{pageAlias}}&form=person&r=1&formModeGlobal=readonly|s|t:View|s|b' AS _link``

* The form is called with SIP parameter ``formModeGlobal=readonly`` or ``form.parameter.mode=readonly``.
* The user can't change any data.

*Readonly systemwide*

Code (somewhere): ``SELECT 'requiredoff' AS '_=formModeGlobal'``

Code: ``SELECT 'p:{{pageAlias}}&form=person&r=1|s|t:View|s|b' AS _link``

* The STORE_USER variable is set `formModeGlobal=readonly`.
* All forms will be shown in readonly mode - fast option to give a user access to the website, without the possibility to
  change any data.

*Draft Mode 1*

Code: ``SELECT 'p:{{pageAlias}}&form=person&r=1&formModeGlobal=readquiredOff|s|t:View|s|b' AS _link``

* A form has one or more FormElement with 'fe.type=required'.
* Opening the form with `formModeGlobal=requiredOff` will allow the user to save the form, even if not all
  FE.type=required elements are given. This can be called 'draft' mode.
* Opening the form without `formModeGlobal` (that's the default), forces the user to fill out
  all FE.type=required fields. This can be called 'final submit' mode.

*Draft Mode 2*

Code: ``SELECT 'p:{{pageAlias}}&form=person&r=1&formModeGlobal=readquiredOff|s|t:View|s|b' AS _link``

* A form has one or more FormElement with 'fe.type=required'.
* Calling the form with `formModeGlobal=requiredOff` will allow the user to save the form, even if not all
  FE.type=required elements are given.
* Define an FE-Action 'afterSave', and do some action on `{{allRequiredGiven:V0}}` like::

  {{UPDATE <table> SET dataValid={{allRequiredGiven:V0}} WHERE id={{id:R}} }}

* In the application logic, open the next process step if all data is given by evaluating `dataValid`.

FormElements
------------

* Each *form* contains one or more *FormElement*.
* The *FormElements* are divided in three categories:

  * :ref:`class-container`
  * :ref:`class-native`
  * :ref:`class-action`

* Ordering and grouping: Native *FormElements* and Container-Elements (both with feIdContainer=0) will be ordered by 'ord'.
* Inside of a container, all nested elements will be displayed.
* Technical, it's *not* necessary to configure a FormElement for the primary index column `id`.
* Additional options to a *FormElement* will be configured via the *FormElement.parameter* field (analog to *Form.parameter*
  for *Forms* ).

  * See also: :ref:`comment-space-character`

.. _class-container:

Class: Container
----------------

* Pills are containers for 'fieldset' *and* / *or* 'native' *FormElements*.
* Fieldsets are containers for 'native' *FormElements*.
* TemplateGroups are containers for 'fieldset' *and* / *or* 'native' *FormElements*.

Type: fieldset
^^^^^^^^^^^^^^

* Native *FormElements* can be assigned to a fieldset.
* FormElement settings:

  * *name*: technical name, used as HTML identifier.
  * *label*: Shown title of the fieldset.

Type: pill (tab)
^^^^^^^^^^^^^^^^

* Pill is synonymous for a tab and looks like a tab.
* If there is at least one pill defined:

  * every native *FormElement* needs to be assigned to a pill or to a fieldset.
  * every *fieldset* needs to be assigned to a pill.

* Mode:

  * `show`: all child elements will be shown.
  * `required`: same as 'show'. This mode has no other meaning than 'show'.
  * `readonly`: technical it's like HTML/CSS `disabled`.

    * The pill title is shown, but not clickable.
    * The `FormElements` on the pill still exist, but are not reachable for the user via UI.

  * `hidden`:

    * The pill is invisible.
    * The `FormElements` on the pill still exist, but are not reachable for the user via UI.


  * Note: Independent of the *mode*, all child elements are always rendered and processed by the client/server.

* Pills are 'dynamicUpdate' aware. `title` and `mode` are optional recalculated during 'dynamicUpdate'.

* FormElement settings:

  * *name*: technical name, used as HTML identifier.
  * *label*: Label shown on the corresponding pill button or inside the drop-down menu.
  * *mode*:

    * *show*, *required*: regular mode. The pill will be shown.
    * *readonly*: the pill and it's name is visible, but not clickable.
    * *hidden*: the pill is not shown at all.

  * *modeSql*:
  * *type*: *pill*
  * *feIdContainer*: `0`  - Pill's can't be nested.
  * *tooltip*: Optional tooltip on hover. Especially helpful if the pill is set to *readonly*.
  * *parameter*:

    * *maxVisiblePill*: `<nr>` - Number of Pill-Buttons shown. Undefined means unlimited. Excess Pill buttons will be
      displayed as a drop-down menu.

Type: templateGroup
^^^^^^^^^^^^^^^^^^^

*TemplateGroups* will be used to create a series of grouped (by the given *templateGroup*) *FormElements*.

*FormElements* can be assigned to a *templateGroup*. These *templateGroup* will be rendered upto *n*-times. On 'form load'
only a single (=first) copy of the *templateGroup* will be shown. Below the last copy of the *templateGroup* an 'add'-button is
shown. If the user click on it, an additional copy of the *templateGroup* is displayed. This can be repeated up to
*templateGroup.maxLength* times. Also, the user can 'remove' previously created copies by clicking on a remove button near
beside every *templateGroup*. The first copy of a templateGroup can't be removed.

* FormElement settings:

  * *label*: Shown in the FormElement-editor *container* field.
  * *maxLength*: Maximum number of copies of the current *templateGroup*. Default: 5.
  * *bsLabelColumn*, *bsInputColumn*, *bsNoteColumn*: column widths for row with the 'Add' button.
  * *parameter*:

    * *tgAddClass*: Class of the 'add' button. Default: `btn btn-default`.
    * *tgAddText*: Text shown on the button. Default: `Add`.
    * *tgRemoveClass*: Class of the 'remove' button. Default: `btn btn-default`.
    * *tgRemoveText*: Text shown on the button. Default: `Remove`.
    * *tgClass*: Class wrapped around every copy of the *templateGroup*.
      E.g. the class `qfq-child-margin-top` adds a margin between two copies of the *templateGroup*. Default: empty

Multiple *templateGroups* per form are allowed.

The name of the native FormElements, inside the templateGroup, which represents the effective table columns, uses the placeholder
`%d`. E.g. the columns `grade1`, `grade2`, `grade3` needs a *FormElement.name* = `grade%d`. The counting will always start with 1.
The placeholder `%d` can also be used in the *FormElement.label*

Example of styling the Add/ Delete Button: :ref:`example_class_template_group`

Column: primary record
""""""""""""""""""""""

If the columns `<name>%d` are real columns on the primary table, saving and delete (=empty string) are done automatically.
E.g. if there are up to five elements `grade1, ..., grade5` and the user inputs only the first three, the remaining will be set
to an empty string.

Column: non primary record
""""""""""""""""""""""""""

Additional logic is required to load, update, insert and/or delete slave records.

Load
;;;;

On each native *FormElement* of the *templateGroup* define an SQL query in the *FormElement.value* field. The query has to
select **all** values of all possible existing copies of the *FormElement* - therefore the exclamation mark is necessary.
Also define the order. E.g. *FormElement.value*::

   {{!SELECT street FROM Address WHERE personId={{id}} ORDER BY id}}

Insert / Update / Delete
;;;;;;;;;;;;;;;;;;;;;;;;

Add an *action* record, type='afterSave', and assign the record to the given *templateGroup*.

In the parameter field define: ::

    slaveId = {{SELECT id FROM Address WHERE personId={{id}} ORDER BY id LIMIT %D,1}}
    sqlHonorFormElements = city%d, street%d
    sqlUpdate = {{UPDATE Address SET city='{{city%d:FE:alnumx:s}}', street='{{street%d:FE:alnumx:s}}'  WHERE id={{slaveId}} LIMIT 1}}
    sqlInsert = {{INSERT INTO Address (`personId`, `city`, `street`) VALUES ({{id}}, '{{city%d:FE:alnumx:s}}' , '{{street%d:FE:alnumx:s}}') }}
    sqlDelete = {{DELETE FROM Address WHERE id={{slaveId}} LIMIT 1}}

The `slaveId` needs attention: the placeholder `%d` starts always at 1. The `LIMIT` directive starts at 0 - therefore
use `%D` instead of `%d`, cause `%D` is always one below `%d` - but can **only** be used on the action element.

.. _class-native:

Class: Native
-------------

Fields:

+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
| Name                | Type                        | Description                                                                                         |
+=====================+=============================+=====================================================================================================+
|Container            | int                         | 0 or *FormElement*.id of container element (pill, fieldSet, templateGroup) part the current *Form*  |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Enabled              | enum('yes'|'no')            | Process the current FormElement                                                                     |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Dynamic Update       | enum('yes'|'no')            | In the browser, *FormElements* with "dynamicUpdate='yes'"  will be updated depending on user        |
|                     |                             | input. :ref:`dynamic-update`                                                                        |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Name                 | string                      |                                                                                                     |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Label                | string                      | Label of *FormElement*. Depending on layout model, left or on top of the *FormElement*              |
|                     |                             | Additional label description can be added by wrapping in HTML tag '<small>'                         |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Mode                 | enum('show', 'readonly',    | | *Show*: regular user input field. This is the default.                                            |
|                     | 'required',                 | | *Required*: User has to specify a value. Typically, an <empty string> represents 'no value'.      |
|                     | 'hidden' )                  | | *Readonly*: User can't change. Data is not saved, except for FormElement with 'processReadOnly'   |
|                     |                             | | *Hidden*: *FormElement* is not visible.                                                           |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Mode sql             | `SELECT` statement with     | A value given here overwrites the setting from `mode`. Most useful with :ref:`dynamic-update`.      |
|                     | a value like in `mode`      | E.g.: {{SELECT IF( '{{otherFunding:FR:alnumx}}'='yes' ,'show', 'hidden' }}                          |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Class                | enum('native', 'action',    | Details below.                                                                                      |
|                     | 'container')                |                                                                                                     |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Type                 | enum('checkbox', 'date', 'time', 'datetime',  'dateJQW', 'datetimeJQW', 'extra', 'gridJQW', 'text', 'editor', 'annotate',         |
|                     | 'imageCut', 'note', 'password', 'radio', 'select', 'subrecord', 'upload', 'fieldset', 'pill', 'beforeLoad', 'beforeSave',         |
|                     | 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterLoad', 'afterSave', 'afterInsert', 'afterUpdate', 'afterDelete',            |
|                     | 'sendMail')                                                                                                                       |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Encode               | 'none', 'specialchar'       | With 'specialchar' (default) the chars <>"'& will be encoded to their htmlentity. _`field-encode`   |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Check Type           | enum('auto', 'alnumx',      | See: :ref:`sanitize-class`                                                                          |
|                     | 'digit', 'numerical',       |                                                                                                     |
|                     | 'email', 'pattern',         |                                                                                                     |
|                     | 'allbut', 'all')            |                                                                                                     |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Check Pattern        | 'regexp'                    | _`field-checktype`: If $checkType=='pattern': pattern to match                                      |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Order                | string                      | Display order of *FormElements* ('order' is a reserved keyword)  _`field-ord`                       |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|labelAlign           | left                        | Label align (default/left/center/right)/ Default: 'default' (defined by Form).                      |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Size                 | string                      | Depends on the FormElement type. E.g. visible length (and height) of input                          |
|                     |                             | element :ref:`input-text`. Might be omitted, depending on the chosen form layout.                   |
|                     |                             | Format: <width>[,<(min) height>[,<max height]] (in characters).                                     |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|BS Label Columns     | string                      | Number of bootstrap grid columns. By default empty, value inherits from the form.                   |
|                     |                             | _`field-bsLabelColumns`. See :ref:`bs-custom-field-width`                                           |
+---------------------+-----------------------------+                                                                                                     |
|BS Input Columns     | string                      |                                                                                                     |
+---------------------+-----------------------------+                                                                                                     |
|BS Note Columns      | string                      |                                                                                                     |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Label / Input / Note | enum(...)                   | Switch on/off opening|closing of bootstrap form classes _`field-rowLabelInputNote`                  |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Maxlength            | string                      | Maximum characters for input. _`field-maxLength`                                                    |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Note                 | string                      | Note of *FormElement*. Depending on layout model, right or below of the *FormElement*.              |
890
|                     |                             | Report syntax can also be used, see :ref:`report-notation`. _`field-note`                           |
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Tooltip              | text                        | Display this text as tooltip on mouse over.  _`field-tooltip`                                       |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Placeholder          | string                      | Text, displayed inside the input element in light grey. _`field-placeholder`                        |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|value                | text                        | Default value: See :ref:`field-value`                                                               |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|sql1                 | text                        | SQL query. See individual `FormEelement`. _`sql1`                                                   |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Parameter            | text                        | Might contain misc parameter. See :ref:`fe-parameter-attributes`                                    |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|feGroup              | string                      | Comma-separated list of Typo3 FE Group ID. NOT SURE IF THIS WILL BE IMPLEMENTED. Native             |
|                     |                             | *FormElements*, fieldsets and pills can be assigned to feGroups. Group status: show, hidden,        |
|                     |                             | hidden. Group Access: FE-Groups. User will be assigned to FE-Groups and the form definition         |
|                     |                             | reference such FE-groups. Easy way of granting permission.                                          |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Deleted              | string                      | 'yes'|'no'.                                                                                         |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+

.. _`field-value`:

FE: Value
^^^^^^^^^

By default this field is empty: QFQ will fill it with the corresponding existing column value on form load.
For a customized default value define: ::

  {{SELECT IF('{{column:RE}}'='','custom default', '{{column:R}}') }}

For non primary records, this is the place to load an existing value. E.g. we're on a 'Person' detail form and would like
to edit, on the same form, a corresponding person email address (which is in a separate table): ::

  {{SELECT a.email FROM Address AS a WHERE a.pId={{id:R0}} ORDER BY a.id LIMIT 1}}

Report syntax can also be used, see :ref:`report-notation`.

.. _`report-notation`:

FE: 'Report' notation
^^^^^^^^^^^^^^^^^^^^^

The FE fields 'value' and 'note' understand the :ref:`Report` syntax. Nested SQL queries as well as links with SIP encoding
are possible. To distinguish between 'Form' and 'Report' syntax, the first line has to be `#!report`::

    #!report

    10.sql = SELECT ...

    20 {
      sql = SELECT ...
      5.sql = SELECT ...
    }

.. _fe-parameter-attributes:

Attributes defined in the parameter field
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

See also at specific *FormElement* definitions.

+---------------------------------+----------------------------------------------------------------------------------------------------------+
| Name                            | Note                                                                                                     |
+=================================+==========================================================================================================+
| acceptZeroAsRequired            | 0|1 - Accept a '0' as a valid input. Default '0' (=0 is not a valid input)                               |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| autofocus                       | See :ref:`input-option-autofocus`                                                                        |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| capture,                        | See :ref:`input-upload`                                                                                  |
| accept,                         |                                                                                                          |
| maxFileSize,                    |                                                                                                          |
| fileDestination,                |                                                                                                          |
| fileTrash,                      |                                                                                                          |
| fileTrashText,                  |                                                                                                          |
| fileReplace,                    |                                                                                                          |
| autoOrient,                     |                                                                                                          |
| autoOrientCmd,                  |                                                                                                          |
| autoOrientMimeType,             |                                                                                                          |
| chmodFile, chmodDir,            |                                                                                                          |
| slaveId,                        |                                                                                                          |
| sqlBefore,                      |                                                                                                          |
| sqlInsert,                      |                                                                                                          |
| sqlUpdate,                      |                                                                                                          |
| sqlDelete,                      |                                                                                                          |
| sqlAfter,                       |                                                                                                          |
| importToTable,                  |                                                                                                          |
| importToColumns,                |                                                                                                          |
| importRegion,                   |                                                                                                          |
| importMode,                     |                                                                                                          |
| importType,                     |                                                                                                          |
| importNamedSheetsOnly,          |                                                                                                          |
| importSetReadDataOnly,          |                                                                                                          |
| importListSheetNames,           |                                                                                                          |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| checkBoxMode                    | See :ref:`input-checkbox`, :ref:`input-radio`, :ref:`input-select`                                       |
| checked                         |                                                                                                          |
| unchecked                       |                                                                                                          |
| label2                          |                                                                                                          |
| itemList                        |                                                                                                          |
| emptyHide                       |                                                                                                          |
| emptyItemAtStart                |                                                                                                          |
| emptyItemAtEnd                  |                                                                                                          |
| buttonClass                     |                                                                                                          |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| dateFormat                      | yyyy-mm-dd / dd.mm.yyyy                                                                                  |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| data-pattern-error              | Pattern violation: Text for error message                                                                |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| data-required-error             | Required violation: Text for error message                                                               |
+---------------------------------+----------------------------------------------------------------------------------------------------------+
| data-match-error                | Match violation: Text for error message                                                                  |