Commit e42eef41 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Index.rst: Describe attribute 'FormElement'.

AbstractBuildForm.php: Implement HTML Formelement attribute 'autofocus'. Add function checkAutoFocus().
parent 0768b92d
......@@ -228,7 +228,7 @@ Only variables that are known in a specified store can be substituted.
+-----+----------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
|Name |Description | Content |
+=====+========================================================================================+============================================================================+
| F | :ref:`STORE_FORM`: data not saved in database yet. | All native form elements. Recent values from the Browser. |
| F | :ref:`STORE_FORM`: data not saved in database yet. | All native *FormElements*. Recent values from the Browser. |
+-----+----------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
| S | :ref:`STORE_SIP`: Client parameter 's' will indicate the current SIP, which will be | sip, r (record_id), form |
| | loaded from the SESSION repo to the SIP-Store. | |
......@@ -277,14 +277,14 @@ Store: *FORM* - F
* Represents the values in the form, typically before saving them.
* Used for:
* Formelements who will be rerendered, after a parent element has been changed by the user.
* Formelement actions, before saving the form.
* Values will be sanitized by the class configured in corresponding the formelement. By default, the sanitize class is `alnumx`.
* *FormElements* who will be rerendered, after a parent *FormElement* has been changed by the user.
* *FormElement* actions, before saving the form.
* Values will be sanitized by the class configured in corresponding the *FormElement*. By default, the sanitize class is `alnumx`.
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| Name | Explanation |
+=========================+============================================================================================================================================+
| FormElement name | Name of native formelement. To get, exactly and only, the specified form element (for 'p_id'): *{{p_id:F}}* |
| FormElement name | Name of native *FormElement*. To get, exactly and only, the specified *FormElement* (for 'p_id'): *{{p_id:F}}* |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
.. _STORE_SIP:
......@@ -321,11 +321,11 @@ Store: *RECORD* - R
* Current record loaded in Form.
* If r=0, alle values are empty.
+------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| Name | Explanation |
+========================+============================================================================================================================================+
| <column name> | Name of a column of the primary table (as defined in the current form). To get, exactly and only, the specified form element: *{{p_id:R}}* |
+------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
+------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
| Name | Explanation |
+========================+==================================================================================================================================================+
| <column name> | Name of a column of the primary table (as defined in the current form). To get, exactly and only, the specified form *FormElement*: *{{p_id:R}}* |
+------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
.. _STORE_CLIENT:
......@@ -386,7 +386,7 @@ Store: *TYPO3* (Bodytext) - T
* **note**: not available
* in 'dynamicUpdate' or
* by FormElement class 'action' with type 'beforeSave', 'afterSave', 'beforeDelete', 'afterDelete'.
* by *FormElement* class 'action' with type 'beforeSave', 'afterSave', 'beforeDelete', 'afterDelete'.
.. _STORE_VARS:
......@@ -398,7 +398,7 @@ Store: *VARS* - V
+=========================+============================================================================================================================================+
| random | random string with length of 32 chars, alphanum |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| slaveId | see FormElement `action` |
| slaveId | see *FormElement* `action` |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
......@@ -512,7 +512,7 @@ Form: main
+------------------------+----------------------------------------------------------+-----------------------------------------------------------------------------------------+
|bsLabelColumns | string | 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|
|bsInputColumns | string | for all formelements. Exceptions per formelement can be specified per formelement. |
|bsInputColumns | string | for all *FormElements*. Exceptions per *FormElement* can be specified per *FormElement*.|
+------------------------+----------------------------------------------------------+ Default: label=3, input=6, note=3 |
|bsNoteColumns | string | |
+------------------------+----------------------------------------------------------+-----------------------------------------------------------------------------------------+
......@@ -531,7 +531,7 @@ 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, hide this 'new' button - the necessary parameter are not provided.
* *delete*: This either deletes the current record only, or (if defined via action form element 'before Delete' ) any specified subrecords.
* *delete*: This either deletes the current record only, or (if defined via action *FormElement* 'before Delete' ) 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.
......@@ -553,7 +553,7 @@ parameter
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| classPill | string | HTML div with given class, surrounding the `pill` title line. |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| classBody | string | HTML div with given class, surrounding all `form elements`. |
| classBody | string | HTML div with given class, surrounding all *FormElement*. |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| submitButtonText | string | Show save button, with the <submitButtonText> at the bottom of the form |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
......@@ -607,7 +607,7 @@ classBody
* Check `typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css` for predefined classes.
* Typical use:
1) adjust the background color of the `form element` area.
1) adjust the background color of the *FormElement* area.
1) 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),
......@@ -641,7 +641,7 @@ FormElements
* :ref:`class-native`
* :ref:`class-action`
* Ordering and grouping: Native Form-Elements and Container-Elements (both with feIdContainer=0) will be ordered by 'ord'.
* 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.
.. _class-container:
......@@ -649,13 +649,13 @@ FormElements
Class: Container
----------------
* Pills are containers for 'fieldset' *and* / *or* 'native' Form-Elements.
* Fieldsets are containers for 'native' Form-Elements
* Pills are containers for 'fieldset' *and* / *or* 'native' *FormElements*.
* Fieldsets are containers for 'native' *FormElements*.
Type: fieldset
^^^^^^^^^^^^^^
* Native Formelements can be assigned to a fieldset.
* Native *FormElements* can be assigned to a fieldset.
* name: technical name, used as HTML identifier.
* label: Shown title of the fieldset.
......@@ -664,15 +664,15 @@ Type: pill
* Pill is synonymous for a tab. A pill looks like a tab.
* Pills are only available with mode render='bootstrap'.
* If there is at least one pill defined, every native Formelement needs to be assigned to a pill or to a fieldset.
* If there is at least one pill defined, every native *FormElement* needs to be assigned to a pill or to a fieldset.
* If there is at least one pill defined, every fieldset needs to be assigned to a pill.
* Parameter:
* FormElement.'''name''': technical name, used as HTML identifier.
* FormElement.'''label''': Label shown on the corresponding pill button or inside the dropdown menu.
* FormElement.'''type''': *pill*
* FormElement.'''feIdContainer''': 0 # Pill's can't be nested.
* FormElement.*name*: technical name, used as HTML identifier.
* FormElement.*label*: Label shown on the corresponding pill button or inside the dropdown menu.
* FormElement.*type*: *pill*
* FormElement.*feIdContainer*: 0 # Pill's can't be nested.
* Form.'''Parameter''': *maxVisiblePill=<nr>* Number of Pill-Buttons shown. Undefined means unlimited. Excess Pill buttons will be displayed as a dropdown menu.
.. _class-native:
......@@ -693,17 +693,17 @@ Fields:
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|enabled | enum('yes'|'no') | |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|dynamicUpdate | enum('yes'|'no') | In the browser, formelements with "dynamicUpdate='yes'" will be updated depending on user input. |
| | | :ref:`dynamic-update` |
|dynamicUpdate | 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 |
|label | string | Label of *FormElement*. Depending on layout model, left or on top of the *FormElement* |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|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'. |
| | 'disabled' ) | *Readonly*: user can't change any data. Data not saved. |
| | | *Disabled*: form element is not visible. |
| | | *Disabled*: *FormElement* is not visible. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|class | enum('native', 'action', | Details below. |
| | 'container') | |
......@@ -716,12 +716,12 @@ Fields:
|checkType | enum('min|max', 'pattern', | |
| | 'number', 'email') | |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|checkPattern | 'regexp' |if $check_type=='pattern': pattern to match |
|checkPattern | 'regexp' |If $check_type=='pattern': pattern to match |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|onChange | string |list of 'form element names' of current form, separated by ', ', If one of the named form elements |
|onChange | string |List of *FormElement*-names of current form, separated by ', ', If one of the named *FormElements* |
| | | change, reload own data / status / mode |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|ord | string |display order of form elements ('order' is a reserved keyword) |
|ord | string | Display order of *FormElements* ('order' is a reserved keyword) |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|tabindex | string |HTML tabindex attribute |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
......@@ -736,30 +736,30 @@ Fields:
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|maxLength | string |Maximum characters for input. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|note | string |Note of formelement. Depending on layout model, right or below of the formelement |
|note | string |Note of *FormElement*. Depending on layout model, right or below of the *FormElement*. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|tooltip | text |Display this text as tooltip on mouse over |
|tooltip | text |Display this text as tooltip on mouse over. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|placeholder | string |Text, displayed inside the input element in light grey |
|placeholder | string |Text, displayed inside the input element in light grey. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|clientJs | text |Javascript called on 'on change' formelements |
|clientJs | text |Javascript called on 'on change' *FormElement* |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|value | text |Default value |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|sql1 | text |SQL query ('sql' is a reserved keyword) |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|sql2 | text |second SQL query |
|sql2 | text |Second SQL query |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|parameter | text |might contain misc parameter. Depends on the type of formelement. |
|parameter | text |Might contain misc parameter. Depends on the type of *FormElement*. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|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, |
| | | disabled. Group Access: FE-Groups. User will be assigned to FE-Groups and the form defintion |
| | | *FormElements*, fieldsets and pills can be assigned to feGroups. Group status: show, hidden, |
| | | disabled. 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'. |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|modified | timestamp |updated autmatically through stored procedure |
|modified | timestamp |updated automatically through stored procedure |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
|created | datetime |set once through QFQ |
+---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
......@@ -773,11 +773,11 @@ Implications
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
|formId |Form | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
|containerId |Assign the Formelement to user defined fieldSet or pill | |
|containerId |Assign the *FormElement* to user defined fieldSet or pill | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
|enabled |Formelement is active or not | |
|enabled |*FormElement* is active or not | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
|name |Name of a column of the primary table. Formelements with a corresponding table will be saved automatically. | |
|name |Name of a column of the primary table. *FormElements* with a corresponding table will be saved automatically. | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
|label |Label shown to the user. | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
......@@ -823,7 +823,7 @@ Implications
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
| autocomplete | | - | - | | | - | | | | | | - | | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
| autofocus=1 | - | - | - | | | - | | - | - | - | | - | - | - |
| autofocus | - | - | - | | | - | | - | - | - | | - | - | - |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
| checkBoxMode | - | - | | | | | | | | | | | | |
+------------------+----------+---------+-------------+----------+--------+-------+------+----------+-------+--------+-----------+---------+--------+--------+
......@@ -848,9 +848,14 @@ Implications
* 2: Any number >1 makes the 'select' input 'multiple' ready.
* See: https://www.w3.org/TR/html5/forms.html#file-upload-state-(type=file)
* All 'native' Formelements like 'input', 'checkbox', ...
* All 'native' *FormElements* like 'input', 'checkbox', ...
'autofocus': if there is no 'autofocus=1' in the formelements
'autofocus': The first *FormElement* with this attribute will get the focus after form load. If there is no such attribute
given to any *FormElement*, the attribute will be automatically assigned to the first editable *FormElement*.
To disable 'autofocus' on a form, set 'autofocus=0' on the first editable *FormElement*.
Note: If there are multiple pills defined on a form, only the first pill will be set with 'autofocus'.
Type: checkbox
^^^^^^^^^^^^^^
......@@ -890,7 +895,7 @@ Checkboxes can be rendered in mode:
* ``itemList=1:red,2:blue,3:orange``
* ``itemList={{!SELECT id, value FROM someTable}}``
* FormElement '''Maxlength''' - vertical or horizontal alignment:
* *FormElement* Maxlength - vertical or horizontal alignment:
* Value: '', 0, 1 - The radios will be aligned vertical.
* Value: >1 - The readios will be aligned horizontal, with a linebreak every 'value' elements.
......@@ -914,7 +919,7 @@ Type: datetime
Type: extra
^^^^^^^^^^^
* Element is not shown in the browser.
* The element can be used to define / precalculate values for a column, which do not already exist as a native FormElement.
* The element can be used to define / precalculate values for a column, which do not already exist as a native *FormElement*.
* The element is build /computed on form load.
Type: text
......@@ -973,18 +978,18 @@ Type: radio
* One column in resultset >> first column represents *label*
* Two or more columns in resultset >> first column represents *id* and second column represents *label*.
* b) FormElement.'''parameter''':
* b) *FormElement*.'''parameter''':
* '''itemList''' attribute. E.g.: *itemList=red,blue,orange* or *itemList=1:red,2:blue:3:orange*
* c) Definition of the *enum* or *set* field (only labels, no ids are possible).
* FormElement '''Maxlength''' - *vertical* or *horizontal* alignment:
* *FormElement* '''Maxlength''' - *vertical* or *horizontal* alignment:
* Value: '', 0, 1 - The radios will be aligned vertical.
* Value: >1 - The readios will be aligned horizontal, with a linebreak every 'value' elements.
* FormElement.'''parameter''':
* *FormElement*.'''parameter''':
* '''emptyItemAtStart''': Existence of this item inserts an empty entry at the beginning of the selectlist.
* '''emptyItemAtEnd''': Existence of this item inserts an empty entry at the end of the selectlist.
......@@ -1004,18 +1009,18 @@ Type: select
* One column in resultset >> first column represents *label*
* Two or more columns in resultset >> first column represents *id* and second column represents *label*.
* b) FormElement.'''parameter''':
* b) *FormElement*.'''parameter''':
* '''itemList''' attribute. E.g.: *itemList=red,blue,orange* or *itemList=1:red,2:blue:3:orange*
* c) Definition of the *enum* or *set* field (only labels, no ids are possible).
* FormElement.'''size''':
* *FormElement*.'''size''':
* <empty>|0|1: Dropdown list.
* >1: Select field with 'size' rows height. Multiple selection of items is possible.
* FormElement.'''parameter''':
* *FormElement*.'''parameter''':
* '''emptyItemAtStart''': Existence of this item inserts an empty entry at the beginning of the selectlist.
* '''emptyItemAtEnd''': Existence of this item inserts an empty entry at the end of the selectlist.
......@@ -1025,8 +1030,8 @@ Type: select
Type: subrecord
^^^^^^^^^^^^^^^
The FormElement type 'subrecord' renders a list of records (so called secondary records), typically to show, edit, delete
or add new records. The list is defined as a SQL query. The number of records shown is not limited. These FormElement
The *FormElement* type 'subrecord' renders a list of records (so called secondary records), typically to show, edit, delete
or add new records. The list is defined as a SQL query. The number of records shown is not limited. These *FormElement*
will be rendered inside the form as a HTML table.
* *sql1*: SQL query to select records. E.g.::
......@@ -1083,7 +1088,7 @@ will be rendered inside the form as a HTML table.
* Example: *detail=id:personId,&12:xId,&{{a}}:personId*
* By default, the given value will overwrite values on the target record. In most situations, this is the wished behaviour.
* Exceptions of the default behaviour have to be defined on the target form in the corresponding formelement in the
* Exceptions of the default behaviour have to be defined on the target form in the corresponding *FormElement* in the
field *value* by changing the default Store priority definition. E.g. `{{<columnname>:RS0}}` - For existing records,
the store `R` will provide a value. For new records, store `R` is empty and store S will be searched for a value:
the value defined in `detail` will be choosen. At last the store '0' is defined as a fallback.
......@@ -1117,7 +1122,7 @@ Either the user is satisfied now or the user can delete the uploaded file (and m
Until this point, the file is cached on the server but not copied to the final destination. The user have to save the
current record, either to finalize the upload or to delete a previous uploaded file.
* FormElement. *parameter*:
* *FormElement*. *parameter*:
* *fileDestination*: Destination where to copy the file. A good practice is to specify a relative `fileDestination` - such an
installation (filesystem and database) are moveable.
......@@ -1154,7 +1159,7 @@ Class: Action
Type: before... | after...
^^^^^^^^^^^^^^^^^^^^^^^^^^
These type of 'action' formelements will be used to implement data validation or creating/updating additional records.
These type of 'action' *FormElements* will be used to implement data validation or creating/updating additional records.
Types:
......@@ -1183,15 +1188,15 @@ Validate
Perform checks by fireing a SQL query and expecting a predefined number of selected records.
* OK: the `expectRecords` number of records has been selected. Continue processing the next FormElement.
* OK: the `expectRecords` number of records has been selected. Continue processing the next *FormElement*.
* Fail: the `expectRecords` number of records has not been selected (less or more): Display the error message
`messageFail` and abort the whole (!) current form load or save.
FormElement.’‘’parameter’‘’:
*FormElement*.’‘’parameter’‘’:
* `requiredList` - List of `native`-formelement names: only if all of those elements are filled (!=0 and !=''), the *current*
`action`-FormElement will be processed. This will enable or disable the check, based on the user input! If no
`native`-formelement names are given, the specified check will always be performed.
* `requiredList` - List of `native`-*FormElement* names: only if all of those elements are filled (!=0 and !=''), the *current*
`action`-*FormElement* will be processed. This will enable or disable the check, based on the user input! If no
`native`-*FormElement* names are given, the specified check will always be performed.
* `sqlValidate` - validation query. E.g.: `sqlValidate={{!SELECT id FROM Person AS p WHERE p.name LIKE {{name:F:all}} AND p.firstname LIKE {{firstname:F:all}} }}`
* Pay attention to '{{!...' after the equal sign.
......@@ -1209,13 +1214,13 @@ sqlInsert / sqlUpdate / sqlDelete
* Save values of a form to different record(s), optionally on different table(s).
* Typically useful on 'afterSave' - be careful when using it earlier, e.g. beforeLoad.
FormElement.’‘’parameter’‘’:
*FormElement*.’‘’parameter’‘’:
* `requiredList` - List of `native`-FormElements: only if all of those elements are filled, the current
`action`-FormElement will be processed.
* `requiredList` - List of `native`-*FormElement*: only if all of those elements are filled, the current
`action`-*FormElement* will be processed.
* `slaveId`:
* Auto fill: name the action `action`-FormElement equal to an existing column (table from the current form definition).
* Auto fill: name the action `action`-*FormElement* equal to an existing column (table from the current form definition).
`slaveId` will be automatically filled with the value of the named column.
* If there is no such named columnname, set `slaveId=0`.
......@@ -1231,7 +1236,7 @@ Note:
* `{{slaveId:V}}` can be used in any query as the current slaveId. It's *important* to Specify Store V!
* If the `action`-FormElement name exist as a column in the master record: Update that column *automatically* with the
* If the `action`-*FormElement* name exist as a column in the master record: Update that column *automatically* with the
recent slaveId (after an INSERT the last_insert_id() acts as the new `slaveId`).
......@@ -1265,9 +1270,9 @@ Type: sendmail
* Send mail(s) after saving the record.
* FormElement.'''value''': Body of the email.
* *FormElement*.'''value''': Body of the email.
* FormElement.’‘’parameter’‘’:
* *FormElement*.’‘’parameter’‘’:
* ‘’‘sendMailTo‘’‘ - Comma-separated list of receiver email addresses. Optional: 'realname <john@doe.com>. If there
is no recipient email address, no mail will be sent.
......@@ -1290,7 +1295,7 @@ Type: sendmail
Dynamic Update
--------------
The 'Dynamic Update' feature makes a form more interactive. If a user change a FormElement who is tagged with
The 'Dynamic Update' feature makes a form more interactive. If a user change a *FormElement* who is tagged with
'dynamicUpdate', *all* elements who are tagged with 'DynamicUpdate', will be recalculated and rerendered.
The following fields will be recalculated during 'Dynamic Update'
......@@ -1300,13 +1305,13 @@ The following fields will be recalculated during 'Dynamic Update'
To make a form dynamic:
* Mark all FormElements with {dynamic update}=enabled, which should send **or** receive a 'do update' signal.
* Define the receiving FormElements in a way, that they will interpret the recent user change. The form variable of the
specific sender FormElement `{{<sender element>:F:<sanitize>}}` should be part of one of the above fields to get an
* Mark all *FormElements* with {dynamic update}=enabled, which should send **or** receive a 'do update' signal.
* Define the receiving *FormElements* in a way, that they will interpret the recent user change. The form variable of the
specific sender *FormElement* `{{<sender element>:F:<sanitize>}}` should be part of one of the above fields to get an
impact. E.g.:
::
[receiving formElement].parameter: itemList={{ SELECT IF({{carPriceRange:FE:alnumx}}='expensive','Ferrari,Tesla,Jaguar','General Motors,Honda,Seat,Fiat') }}
[receiving *FormElement*].parameter: itemList={{ SELECT IF({{carPriceRange:FE:alnumx}}='expensive','Ferrari,Tesla,Jaguar','General Motors,Honda,Seat,Fiat') }}
* Label and Description are not 'Dynamic Update' aware (Feature Request #2081).
......@@ -1906,7 +1911,7 @@ Mode: form
* `r=<record id>`
Deletes the record with id '<record id>' from the table specified in form '<form name>' as primary table.
Additional action *formElement* of type *beforeDelete* or *afterDelete* will be fired too.
Additional action *FormElement* of type *beforeDelete* or *afterDelete* will be fired too.
Examples:
'''''''''
......@@ -2705,13 +2710,13 @@ via SIP parameter to the secondary form.
On the secondary form: for 'new' records choose the computed value, for existing records leave the value
unchanged.
* Primary form, `subrecord` formelement, field `parameter`: set ::
* Primary form, `subrecord` *FormElement*, field `parameter`: set ::
detail=id:formId,{{SELECT '&', IFNULL(fe.ord,0)+10 FROM Form AS f LEFT JOIN FormElement AS fe ON fe.formId=f.id WHERE
detail=id:formId,{{SELECT '&', IFNULL(fe.ord,0)+10 FROM Form AS f LEFT JOIN *FormElement* AS fe ON fe.formId=f.id WHERE
f.id={{r:S0}} ORDER BY fe.ord DESC LIMIT 1}}:ord
* Secondary form, `ord` formelement, field `value`: set
* Secondary form, `ord` *FormElement*, field `value`: set
::
......@@ -2722,7 +2727,7 @@ Version 2
Compute the next 'ord' as default value direct inside the secondary form. No change is needed for the primary form.
* Secondary form, `ord` formelement, field `value`: set `{{SELECT IF({{ord:R0}}=0, MAX(IFNULL(fe.ord,0))+10,{{ord:R0}}) FROM (SELECT 1) AS a LEFT JOIN FormElement AS fe ON fe.formId={{formId:S0}} GROUP BY fe.formId}}`.
* Secondary form, `ord` *FormElement*, field `value`: set `{{SELECT IF({{ord:R0}}=0, MAX(IFNULL(fe.ord,0))+10,{{ord:R0}}) FROM (SELECT 1) AS a LEFT JOIN FormElement AS fe ON fe.formId={{formId:S0}} GROUP BY fe.formId}}`.
Form: Person Wizard - firstname, city
-------------------------------------
......@@ -2743,14 +2748,14 @@ Relation: `Person.id = Address.personId`
* Table: Person
* Render: bootstrap
* FormElement: firstname
* *FormElement*: firstname
* Class: **native**
* Type: **text**
* Name: firstname
* Label: Firstname
* FormElement: email, text, 20
* *FormElement*: email, text, 20
* Class: **native**
* Type: **text**
......@@ -2758,7 +2763,7 @@ Relation: `Person.id = Address.personId`
* Label: City
* Value: `{{SELECT city FROM Address WHERE personId={{r}} ORDER BY id LIMIT 1}}`
* FormElement: insert/update address record
* *FormElement*: insert/update address record
* Class: **action**
* Type: **afterSave**
......@@ -2790,14 +2795,14 @@ Relation: `Person.id = Address.personId`
* Table: Person
* Render: bootstrap
* FormElement: firstname
* *FormElement*: firstname
* Class: **native**
* Type: **text**
* Name: firstname
* Label: Firstname
* FormElement: email, text, 20
* *FormElement*: email, text, 20
* Class: **native**
* Type: **text**
......@@ -2805,7 +2810,7 @@ Relation: `Person.id = Address.personId`
* Label: Note
* Value: `{{SELECT Note FROM Note AS n, Person AS p WHERE p.id={{r}} AND p.noteId=n.id ORDER BY id }}`
* FormElement: insert/update address record
* *FormElement*: insert/update address record
* Class: **action**
* Type: **afterSave**
......
......@@ -322,6 +322,104 @@ abstract class AbstractBuildForm {
abstract public function getProcessFilter();
/**
* Check if there is an explicit 'autofocus' definition in at least one FE.
* Found: do nothing, it will be rendered at the correct position.
* Not found: set 'autofocus' on the first FE.
*
* Accepted misbehaviour on forms with pills: if there is at least one editable element on the first pill,
* the other pills are not checked - independent if there was a definition on the first pill or not.
* Reason: checks happens per pill - if there is no explizit definition on the first pill, take the first editable
* element of that pill.
*/
private function checkAutoFocus() {
static $found = false;
$idx = false;
if ($found) {
return;
}
// Search if there is an explicit autofocus definition.
for ($i = 0; $i < count($this->feSpecNative); ++$i) {
// Only check native elements which will be shown
if ($this->feSpecNative[$i][FE_CLASS] == FE_CLASS_NATIVE &&
($this->feSpecNative[$i][FE_MODE] == FE_MODE_SHOW || $this->feSpecNative[$i][FE_MODE] == FE_MODE_REQUIRED)
) {
// Check if there is an explicit definition.
if (isset($this->feSpecNative[$i][FE_AUTOFOCUS])) {
if ($this->feSpecNative[$i][FE_AUTOFOCUS] == '' || $this->feSpecNative[$i][FE_AUTOFOCUS] == '1') {
$this->feSpecNative[$i][FE_AUTOFOCUS] = '1'; // fix to '=1'
} else {
unset($this->feSpecNative[$i][FE_AUTOFOCUS]);
}
$found = true;
return;
}
if ($idx === false) {
$idx = $i;
}
}
}
// No explicit definition found: take the first found editable element.
if ($idx !== false) {
$found = true;
// No explicit definition found: set autofocus.
$this->feSpecNative[$idx][FE_AUTOFOCUS] = '1';
}
}
/**
* Check if there is an explicit 'autofocus' definition in at least one FE.
* Found: do nothing, it will be rendered at the correct position.
* Not found: set 'autofocus' on the first FE.
*
* Accepted misbehaviour on forms with pills: if there is at least one editable element on the first pill,
* the other pills are not checked - independent if there was a definition on the first pill or not.
* Reason: checks happens per pill - if there is no explizit definition on the first pill, take the first editable
* element of that pill.
*/
private function checkAutoFocus() {
static $found = false;
$idx = false;
if ($found) {
return;
}
// Search if there is an explicit autofocus definition.
for ($i = 0; $i < count($this->feSpecNative); ++$i) {
// Only check native elements which will be shown
if ($this->feSpecNative[$i][FE_CLASS] == FE_CLASS_NATIVE &&
($this->feSpecNative[$i][FE_MODE] == FE_MODE_SHOW || $this->feSpecNative[$i][FE_MODE] == FE_MODE_REQUIRED)
) {
// Check if there is an explicit definition.
if (isset($this->feSpecNative[$i][FE_AUTOFOCUS])) {
if ($this->feSpecNative[$i][FE_AUTOFOCUS] == '' || $this->feSpecNative[$i][FE_AUTOFOCUS] == '1') {
$this->feSpecNative[$i][FE_AUTOFOCUS] = '1'; // fix to '=1'
} else {
unset($this->feSpecNative[$i][FE_AUTOFOCUS]);
}
$found = true;
return;
}
if ($idx === false) {
$idx = $i;
}
}
}
// No explicit definition found: take the first found editable element.
if ($idx !== false) {
$found = true;
// No explicit definition found: set autofocus.
$this->feSpecNative[$idx][FE_AUTOFOCUS] = '1';
}
}