Commit 86ccd5ef authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'master' into formTitle

parents 41e1f306 32705657
......@@ -1203,7 +1203,7 @@ Bug Fixes
* Dynamic Update has been broken since implementing of 'element-update' (#3180). Now both methods, 'element-update' and 'form-update' should be fine.
* qfq-bs.css.less: Fixed problem with 'typeahead input elements' not expanded to Bootstrap column width. Changed
Layout/Design Typeahead drop-down box. Add hoover for the drop-down box with a blue background
Layout/Design Typeahead drop-down box. Add hover for the drop-down box with a blue background
* AbstractBuildForm.php: #3374 - textarea elements now contains 'maxlength' attribute.
* BuildFormBootstrap.php: wrapping of optional 'submitButtonText' now done with the 'per form' values.
* typeahead.php: if there is an exception, the message body is sent as regular 'content' for the drop-down box. At the
......
# Drag And Drop
## Sort
Initialize a dnd container by adding the class "qfq-dnd"
Set container object class to `class="qfq-dnd qfq-dnd-sort"`.
Add the data elements: `data-dnd-api="url"` and `data-dnd-key="key"`.
For the children inside of the container (just the first children):
add `data-dnd-id` to a reference you can handle (probably record id).
Request will be sent containing following GET variables:
* dragId = `data-dnd-id` of the dragged object,
* dragPosition = client internal old position of the dragged object.
* setTo = "after" or "before",
* hoverId = `data-dnd-id` id of the element the dragged element is now hovering, meaning before or after.
* hoverPosition = client internal position of currently hovered element.
Example: http://something/bla?dragId=uno&dragPosition=1&setTo=before&hoverId=tre&hoverPosition=3
\ No newline at end of file
......@@ -73,11 +73,11 @@ the Client by adding following name/value pairs to the response JSON
Stream
{
"status": "error",
...
"field-name": "<field name>",
"field-message": "<message>",
...
"status": "error",
...
"field-name": "<field name>",
"field-message": "<message>",
...
}
Only one validation failure per request can be reported to Client.
......@@ -224,18 +224,22 @@ The format of redirect information is outlined below
{
...
"redirect": "no" | "url" | "url-skip-history" | "client"
"redirect": "no" | "url" | "url-skip-history" | "auto" | "close"
"redirect-url": "<url>"
...
}
`"redirect"`
: type of redirection. `"no"` advises the Client to stay on the
Current Page. `"client"` advises the Client to decide where to
redirect to. `"url"` advices the Client to redirect to the URL
provided in `"redirect-url"`. `"url-skip-history"` behaves like
`"url"` but the current page will skip the browser history.
: type of redirection.
* `"no"` advises the Client to stay on the Current Page.
* `"close"` the client goes back one in history - if there is no history, stays on the same page.
* `"auto"` the Client decide where to redirect to.
* if the user clicks 'save', stay on the same page.
* if the user clicks 'close', go back one in history - if there is no history, stays on the same page.
* `"url"` advices the Client to redirect to the URL provided in `"redirect-url"`.
* `"url-skip-history"` behaves like `"url"` but the current page will skip the browser history.
`"redirect-url"`
: Used to provide an URL when `"redirect"` is set to `"url"`. It
......@@ -465,7 +469,7 @@ Request Method
: GET
URL Parameters
: `s=<SIP>` (form, r)
: `s=<SIP>` (form, r)
: `action=lock`, `action=extend`, `action=release>`
: `recordHashMd5=<value of hidden form element 'recordHashMd5'>`
......@@ -479,7 +483,7 @@ JSON Response from the server (extended [Minimal Response]) containing:
{
"status": "success"|"error"|"conflict"|"conflict_allow_force",
"message": "<message>"
"message": "<message>"e5
}
`status` indicates how the request has been fulfilled by the server.
......@@ -488,6 +492,29 @@ On one of`"error"|"conflict"|"conflict_allow_force"` the Client must display `"<
On `"conflict"` the Client opens the alert as modal dialog (user can't change anything on the form) with a 'reload current
form' button.
On `"conflict_allow_force"` the Client opens the alert non-modal (default).
### Drag And Drop (sort)
Request
: api/dragAndDrop.php
Request Method
: GET
URL Parameters:
: `s=<SIP>` (`form=<formname>`)
:
: `dragId=<data-dnd-id of dragged element>`
: `dragPosition=<client internal position (numbering) of element before dragging>`
: `setTo=before`, `setTo=after`
: `hoverId=<data-dnd-id of dragged element>`
: `hoverPosition=<client internal position (numbering) of element after dragging>`
Server Response
: The response contains at least a [Minimal Response]. In addition, a
[HTML Element Update] may be included.
## Glossary
......
......@@ -1888,7 +1888,7 @@ Definition
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Show button | 'new, delete, close, save' (Default: 'new,delete,close,save'): Shown named buttons in the upper right corner of the form. See `form-showButton`_ |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Forward Mode | 'client | no | url | url-skip-history' (Default: client): See `form-forward`_. |
|Forward Mode | 'auto | close | no | url | url-skip-history' (Default: auto): See `form-forward`_. |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Forward (Mode) Page | a) URL / Typo3 page id/alias or b) Forward Mode (via '{{...}}') or combination of a) & b). See `form-forward`_. |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
......@@ -2003,14 +2003,15 @@ Forward (=forwardMode)
After the user presses *Save*, *Close*, *Delete* or *New*, different actions are possible where the browser redirects to.
* `client` (default) - the QFQ browser Javascript logic, decides to stay on the page or to force a redirection
to a previous page.
* `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* closes the current page and goes back to the previous page. Note: if a new tab is opened and the user presses
QFQ close (in any way) - in that new browser tab there is no previous page! QFQ won't close the tab, instead a message
is shown
* *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`.
......@@ -2031,14 +2032,14 @@ Format: [<url>] or [<mode>|<url>]
* `{{SELECT ...}}`
* `<mode>|<url>`
* `<mode>` - Valid keywords are as above: `no|client|url|url-skip-history`
* `<mode>` - Valid keywords are as above: `auto|close|no|url|url-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 `client` mode.
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:
......@@ -2048,7 +2049,7 @@ The CLIENT `submit_reason` shows the user action:
Example forwardPage
^^^^^^^^^^^^^^^^^^^
* `{{SELECT IF('{{formModeGlobal:S:alnumx}}'='requiredOff', 'no', 'client') }}`
* `{{SELECT IF('{{formModeGlobal:S:alnumx}}'='requiredOff', 'no', 'auto') }}`
* `{{SELECT IF('{{submit_reason:CE:alnumx}}'='save', 'no', 'url'), '|http://example.com' }}`
Type: combined dynamic mode & URL/page
......@@ -2556,7 +2557,7 @@ See also at specific *FormElement* definitions.
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| htmlAfter | string | HTML Code wrapped after the complete *FormElement* |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| wrapRow | string | If specified, skip default wrapping (`<div class='col-md-?>`). Instead the given string is used. |
| wrapRow | string | If specified, skip default wrapping (`<div class='col-md-?'>`). Instead the given string is used. |
+------------------------+--------+ |
| wrapLabel | string | |
+------------------------+--------+ |
......@@ -2937,6 +2938,8 @@ Type: text
the value is an empty string
* *inputType* = number (optional). Typically the HTML tag 'type' will be 'text', 'textarea' or 'number' (detected automatically).
If necessary, the HTML tag 'type' might be forced to a specific given value.
* *step* = Step size of the up/down buttons which increase/decrease the number of in the input field. Optional.
Default 1. Only useful with `inputType=number` (defined explicit via `inputType` or detected automatically).
.. _`input-typeahead`:
......@@ -4119,6 +4122,21 @@ Best practice
Custom default value only for 'new records'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Method 1
''''''''
On `Form.parameter` define a `fillStoreVar` query with a column name equal to a form field. That's all.
Example: ::
FormElement.name = technicalContact
Form.parameter.fillStoreVar = {{!SELECT CONCAT(p.firstName, ' ', p.name) AS technicalContact FROM Person AS p WHERE p.account='{{feUser:T}}' }}
What we use here is the default STORE prio FSRVD. If the form loads with r=0, 'F', 'S' and 'R' are empty. 'V' is filled.
If r>0, than 'F' and 'S' are empty and 'R' is filled.
Method 2
''''''''
In the specific `FormElement` set `value={{columnName:RSE}}`. The link to the form should be rendered with
'"...&columnName=<data>&..." AS _page'. The trick is that the STORE_RECORD is empty for new records, and therefore the
corresponding value from STORE_SIP will be returned. Existing records will use the already saved value.
......@@ -6218,8 +6236,125 @@ E.g.::
10.sql = SELECT "p:home&r=0|t:Home|c:qfq-100 qfq-left" AS _pagev
Examples
--------
Drag and drop
-------------
Sort/order elements
^^^^^^^^^^^^^^^^^^^
Manually sorting and ordering of elements via `HTML5 drag and drop` is supported via QFQ. Any sortable element
should be represented by a database record with an order column. If the elements are unordered, they will be ordered after
the first 'drag and drop' move of an element.
Functionality is divided into:
* Display list: the records will be displayed via QFQ/report.
* Update database: updates of the order column are managed by a specific 'drag and drop' definition form.
Part 1: Display list
''''''''''''''''''''
Display the list of elements via a regular QFQ content record. All 'drag and drop' elements have to be nested by an HTML
element:
* With `class="qfq-dnd-sort"`.
* With an automatically SIP protected form name: `{{'form=<form name>' AS _data-dnd-api}}`
* Only direct children of such element can be dragged.
* Every children needs a unique identifier `data-dnd-id="<unique>"`. Typically this is the corresponding record id.
* The record needs a dedicated order column, which will be updated through API calls in time.
A `<div>` example HTML output: ::
<div class="qfq-dnd-sort" data-dnd-api="typo3conf/ext/qfq/qfq/api/dragAndDrop.php?s=badcaffee1234">
<div class="anyClass" id="<uniq1>" data-dnd-id="55">
Numbero Uno
</div>
<div class="anyClass" id="<uniq2>" data-dnd-id="18">
Numbero Deux
</div>
<div class="anyClass" id="<uniq3>" data-dnd-id="27">
Numbero Tre
</div>
</div>
A typical QFQ report which generates those `<div>` HTML: ::
10 {
sql = SELECT '<div id="anytag-', n.id,'" data-dnd-id="', n.id,'">' , n.note, '</div>'
FROM Note AS n
WHERE grId=28
ORDER BY n.ord
head = <div class="qfq-dnd-sort" data-dnd-api="{{'form=dndSortNote&grId=28|A:dnd-sort' AS _api}}">
tail = </div>
}
A `<table>` based setup is also possible. Note the attribute `data-columns="3"` - those generates a dropzone
which is the same width as the outer table. ::
<table>
<tbody class="qfq-dnd-sort" data-dnd-api="typo3conf/ext/qfq/qfq/api/dragAndDrop.php?s=badcaffee1234" data-columns="3">
<tr> class="anyClass" id="<uniq1>" data-dnd-id="55">
<td>Numbero Uno</td><td>Numbero Uno.2</td><td>Numbero Uno.3</td>
</tr>
<tr class="anyClass" id="<uniq2>" data-dnd-id="18">
<td>Numbero Deux</td><td>Numbero Deux.2</td><td>Numbero Deux.3</td>
</tr>
<tr class="anyClass" id="<uniq3>" data-dnd-id="27">
<td>Numbero Tre</td><td>Numbero Tre.2</td><td>Numbero Tre.3</td>
</tr>
</tbody>
</table>
A typical QFQ report which generates those HTML: ::
10 {
sql = SELECT '<tr id="anytag-', n.id,'" data-dnd-id="', n.id,'" data-columns="3">' , n.id AS '_+td', n.note AS '_+td', n.ord AS '_+td', '</tr>'
FROM Note AS n
WHERE grId=28
ORDER BY n.ord
head = <table><tbody class="qfq-dnd-sort" {{'form=dndSortNote&grId=28' AS _data-dnd-api}} data-columns="3">
tail = </tbody><table>
}
Part 2: Update database
'''''''''''''''''''''''
A dedicated `Form`, without any `FormElements`, is needed to define the database update definition.
Fields:
* Name: <custom form name> - used in Part 1 in the `_data-dnd-api` variable.
* Table: <table with the element records> - used to the update the records specified by `dragAndDropOrderSql`.
* Parameter:
+-------------------------------------+--------------------------------------------------------------------------------+
| Attribute | Description |
+=====================================+================================================================================+
| orderInterval = <number> | Optional. By default '10'. Might be any number > 0. |
+-------------------------------------+--------------------------------------------------------------------------------+
| orderColumn = <column name> | Optional. By default 'ord'. |
+-------------------------------------+--------------------------------------------------------------------------------+
| dragAndDropOrderSql = | Query to selects the *same* records as the report in the |
| {{!SELECT n.id AS id, n.ord AS ord FROM Note AS n | same *order!* Inconsistencies results in sort differences. |
| ORDER BY n.ord}} | The columns `id` and `ord` are *mandatory.* |
+-------------------------------------------------------+--------------------------------------------------------------+
The form related to the example of part 1: ::
Form.name: dndSortNote
Form.table: Note
Form.parameter: orderInterval = 1
Form.parameter: orderColumn = ord
Form.parameter: dragAndDropOrderSql = {{!SELECT n.id AS id, n.ord AS ord FROM Note AS n WHERE n.grId={{grId:S0}} ORDER BY n.ord}}
Report Examples
---------------
The following section gives some examples of typical reports
......@@ -6571,42 +6706,42 @@ Create / edit `AutoCron` jobs
Create a T3 page with a QFQ record (similar to the formeditor). Such page should be access restricted and is only needed
to edit `AutoCron` jobs: ::
dbIndex={{indexQfq:Y}}
form={{form:S}}
dbIndex={{indexQfq:Y}}
form={{form:S}}
10 {
# Table header.
sql = SELECT CONCAT('p:{{pageId:T}}&form=cron') AS _pagen, 'id', 'Next run','Frequency','Comment','Last run','In progress', 'Status' FROM (SELECT 1) AS fake WHERE '{{form:SE}}'=''
head = <table class='table table-hover qfq-table-50'>
tail = </table>
rbeg = <thead><tr>
rend = </tr></thead>
fbeg = <th>
fend = </th>
10 {
# All Cron Jobs
sql = SELECT CONCAT('<tr class="',
IF(c.lastStatus LIKE 'Error%','danger',''),
IF(c.inProgress!=0 AND DATE_ADD(c.inProgress, INTERVAL 10 MINUTE)<NOW(),' warning',''),
IF(c.status='enable','',' text-muted'),'" ',
IF(c.inProgress!=0 AND DATE_ADD(c.inProgress, INTERVAL 10 MINUTE)<NOW(),'title="inProgress > 10mins"',
IF(c.lastStatus LIKE 'Error%','title="Status: Error"','')),
'>'),
'<td>', CONCAT('p:{{pageId:T}}&form=cron&r=', c.id) AS _pagee, '</td><td>',
c.id, '</td><td>',
IF(c.nextrun=0,"", DATE_FORMAT(c.nextrun, "%d.%m.%y %H:%i:%s")), '</td><td>',
c.frequency, '</td><td>',
c.comment, '</td><td>',
IF(c.lastrun=0,"", DATE_FORMAT(c.lastrun,"%d.%m.%y %H:%i:%s")), '</td><td>',
IF(c.inProgress=0,"", DATE_FORMAT(c.inProgress,"%d.%m.%y %H:%i:%s")), '</td><td>',
LEFT(c.laststatus,40) AS '_+pre', '</td><td>',
CONCAT('U:form=cron&r=', c.id) AS _paged, '</td></tr>'
FROM Cron AS c
ORDER BY c.id
}
}
10 {
# Table header.
sql = SELECT CONCAT('p:{{pageId:T}}&form=cron') AS _pagen, 'id', 'Next run','Frequency','Comment','Last run','In progress', 'Status' FROM (SELECT 1) AS fake WHERE '{{form:SE}}'=''
head = <table class='table table-hover qfq-table-50'>
tail = </table>
rbeg = <thead><tr>
rend = </tr></thead>
fbeg = <th>
fend = </th>
10 {
# All Cron Jobs
sql = SELECT CONCAT('<tr class="',
IF(c.lastStatus LIKE 'Error%','danger',''),
IF(c.inProgress!=0 AND DATE_ADD(c.inProgress, INTERVAL 10 MINUTE)<NOW(),' warning',''),
IF(c.status='enable','',' text-muted'),'" ',
IF(c.inProgress!=0 AND DATE_ADD(c.inProgress, INTERVAL 10 MINUTE)<NOW(),'title="inProgress > 10mins"',
IF(c.lastStatus LIKE 'Error%','title="Status: Error"','')),
'>'),
'<td>', CONCAT('p:{{pageId:T}}&form=cron&r=', c.id) AS _pagee, '</td><td>',
c.id, '</td><td>',
IF(c.nextrun=0,"", DATE_FORMAT(c.nextrun, "%d.%m.%y %H:%i:%s")), '</td><td>',
c.frequency, '</td><td>',
c.comment, '</td><td>',
IF(c.lastrun=0,"", DATE_FORMAT(c.lastrun,"%d.%m.%y %H:%i:%s")), '</td><td>',
IF(c.inProgress=0,"", DATE_FORMAT(c.inProgress,"%d.%m.%y %H:%i:%s")), '</td><td>',
LEFT(c.laststatus,40) AS '_+pre', '</td><td>',
CONCAT('U:form=cron&r=', c.id) AS _paged, '</td></tr>'
FROM Cron AS c
ORDER BY c.id
}
}
Usage
......
......@@ -89,7 +89,7 @@ try {
$answer = array();
if ($flagSuccess) {
$answer[API_MESSAGE] = 'Deleted';
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_CLIENT;
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_AUTO;
$answer[API_STATUS] = API_ANSWER_STATUS_SUCCESS;
} else {
$answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
......
<?php
/**
* Created by PhpStorm.
* User: ep
* Date: 12/23/15
* Time: 6:17 PM
*/
namespace qfq;
use qfq;
require_once(__DIR__ . '/../qfq/store/Store.php');
require_once(__DIR__ . '/../qfq/Constants.php');
require_once(__DIR__ . '/../qfq/QuickFormQuery.php');
//require_once(__DIR__ . '/../qfq/exceptions/UserFormException.php');
//require_once(__DIR__ . '/../qfq/exceptions/CodeException.php');
//require_once(__DIR__ . '/../qfq/exceptions/DbException.php');
//require_once(__DIR__ . '/../qfq/exceptions/ErrorHandler.php');
/**
* Return JSON encoded answer
*
* status: success|error
* message: <message>
* redirect: client|url|no
* redirect-url: <url>
* field-name: <field name>
* field-message: <message>
* form-data: [ fieldname1 => value1, fieldname2 => value2, ... ]
* form-control: [ fieldname1 => status1, fieldname2 => status2, ... ] status: show|hide, enabled|disabled,
* readonly|readwrite
*
* Description:
*
* Save successful. Button 'close', 'new'. Form.forward: 'auto'. Client logic decide to redirect or not. Show message
* if no redirect. status = 'success' message = <message> redirect = 'client'
*
* Save successful. Button 'close': Form.forward: 'page'. Client redirect to url.
* status = 'success'
* message = <message>
* redirect = 'url'
* redirect-url = <URL>
*
* Save failed: Button: any. Show message and set 'alert' on _optional_ specified form element. Bring 'pill' of
* specified form element to front. status = 'error' message = <message> redirect = 'no' Optional: field-name = <field
* name> field-message = <message appearing as tooltip (or similar) near the form element>
*/
$answer = array();
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_NO;
$answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
$answer[API_MESSAGE] = '';
try {
$qfq = new QuickFormQuery(['bodytext' => '']);
$data = $qfq->dragAndDrop();
$answer[API_STATUS] = API_ANSWER_STATUS_SUCCESS;
$answer[API_MESSAGE] = 'reorder: success';
// $answer[API_FORM_UPDATE] = $data[API_FORM_UPDATE];
// $answer[API_ELEMENT_UPDATE] = $data[API_ELEMENT_UPDATE];
// unset($answer[API_FORM_UPDATE][API_ELEMENT_UPDATE]);
} catch (qfq\UserFormException $e) {
$answer[API_MESSAGE] = $e->formatMessage();
} catch (qfq\CodeException $e) {
$answer[API_MESSAGE] = $e->formatMessage();
} catch (qfq\DbException $e) {
$answer[API_MESSAGE] = $e->formatMessage();
} catch (\Exception $e) {
$answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage();
}
header("Content-Type: application/json");
echo json_encode($answer);
......@@ -49,12 +49,12 @@ require_once(__DIR__ . '/../qfq/exceptions/DbException.php');
$answer = array();
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_CLIENT;
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_AUTO;
$answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
$answer[API_MESSAGE] = '';
try {
$qfq = new \qfq\QuickFormQuery(['bodytext' => ""]);
$qfq = new QuickFormQuery(['bodytext' => ""]);
$data = $qfq->saveForm();
......
This diff is collapsed.
......@@ -113,6 +113,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
* @throws CodeException
* @throws DbException
* @throws UserFormException
* @throws UserReportException
*/
public function head($mode = FORM_LOAD) {
$html = '';
......@@ -383,7 +384,9 @@ class BuildFormBootstrap extends AbstractBuildForm {
* @param array $json
* @return string
* @throws CodeException
* @throws DbException
* @throws UserFormException
* @throws UserReportException
*/
private function buildPillNavigation($mode = FORM_LOAD, array $pillArray, array &$json) {
$pillButton = '';
......@@ -513,6 +516,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
* @return string
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
public function getFormTag() {
......@@ -595,6 +599,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
fileDeleteUrl: '$apiDir/file.php?$actionDelete'
});
var qfqRecordList = new QfqNS.QfqRecordList('$apiDeletePhp');
})
</script>
......@@ -614,6 +619,7 @@ EOF;
* @throws CodeException
* @throws DbException
* @throws UserFormException
* @throws UserReportException
*/
public function buildPill(array $formElement, $htmlFormElementName, $value, array &$json) {
$html = '';
......@@ -809,6 +815,7 @@ EOF;
* @throws CodeException
* @throws DbException
* @throws UserFormException
* @throws UserReportException
*/
public function process($mode, $htmlElementNameIdZero = false, $latestFeSpecNative = array()) {
......
......@@ -33,6 +33,7 @@ const FORM_LOAD = 'form_load';
const FORM_SAVE = 'form_save';
const FORM_UPDATE = 'form_update';
const FORM_DELETE = 'form_delete';
const FORM_DRAG_AND_DROP = 'form_drag_and_drop';
const FORM_PERMISSION_SIP = 'sip';
const FORM_PERMISSION_LOGGED_IN = 'logged_id';
const FORM_PERMISSION_LOGGED_OUT = 'logged_out';
......@@ -143,10 +144,11 @@ const ERROR_DEBUG = 1031;
const ERROR_UNKNOWN_MODE = 1032;
const ERROR_NOT_IMPLEMENTED = 1033;
const ERROR_RESERVED_KEY_NAME = 1034;
const ERROR_MISSING_FORM = 1035;
const ERROR_UNKNOWN_FORWARD_MODE = 1036;
const ERROR_MISSING_HIDDEN_FIELD_IN_SIP = 1038;
const ERROR_MISSING_MESSAGE_FAIL = 1037;
const ERROR_MISSING_EXPECT_RECORDS = 1038;
const ERROR_MISSING_HIDDEN_FIELD_IN_SIP = 1039;
const ERROR_UNKNOWN_CHECKTYPE = 1042;
const ERROR_PATTERN_VIOLATION = 1043;
......@@ -169,7 +171,7 @@ const ERROR_MISSING_OPEN_DELIMITER = 1060;
const ERROR_MISSING_CLOSE_DELIMITER = 1061;
const ERROR_EXPECTED_ARRAY = 1062;
const ERROR_REPORT_FAILED_ACTION = 1063;
const ERROR_MISSING_MESSAGE_FAIL = 1064;