-
Jan Haller authored
Update Documentation/Form.rst: Fixed typos
Jan Haller authoredUpdate Documentation/Form.rst: Fixed typos
Form
General
Important
Primary key: QFQ expect that each table, which will be loaded into a form, contains a primary key called id. That one should be autoincrement. It's not necessary to create a FormElement id in a form.
-
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 regular updated during installation of newer 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`.
-
Simple form: the form acts on one record, stored in one table.
-
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.
-
If a form is edited using the JSON form editor then a backup of the previous version is saved. See :ref:`formAsFile`.
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:

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- 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 Settings
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` |
Permit REST | See :ref:`restApi` |
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 |
|
labelAlign | Label align (default/left/center/right)/ Default: 'default' (defined by Config). form-label-align |
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 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 Input Columns | |
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) |
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.
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
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.
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
- <T3 page slug>&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
- The following parameter are optional.
- Each parameter has to be on a single line.
- If a parameter is defined multiple time, the last one is the final one.
- Comment lines have to start with
#
.
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` |
clearMe | 0 / 1 | Overwrite default from :ref:`configuration`. Show a small 'x' in every input or textarea to clear field. |
rememberLastPill | 0 / 1 | Overwrite default from :ref:`configuration`. On form load, bring last used pill to front |
doNotLogColumn | string | Overwrite default from :ref:`configuration`. Comma separated list of Form-Element names. |
fieldsetClass | string | Overwrite default from :ref:`configuration`. |
-
Example in field Form.parameter:
maxVisiblePill = 5 class = container-fluid classBody = qfq-form-right
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 hidden to not confuse the user.
- Optional.
- Default: Empty