Commit 6238871d authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'Ticket4606LinkTokenButton' into upload-button

# Conflicts:
#	javascript/src/QfqForm.js
parents fb01dd62 b9f6edb3
This diff is collapsed.
QFQ: Typo3 Extbase Extension
===============================
QFQ: Quick Form Query - Typo3 Extbase Extension
===============================================
Version: see `extension/ext_emconf.php`
......@@ -20,7 +20,9 @@ See: https://w3.math.uzh.ch/qfq/
Documentation
-------------
a) See the documentation provided with the exentions inside Typo3
Latest stable version under https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Index.html
Local: See the documentation provided with the exentions inside Typo3
<your Typo3 installation>/typo3conf/ext/qfq/Documentation/html/Index.html
If you get a 'Page forbidden / not found' there might be some Webserver restrictions. E.g. the Typo3 example of `.htaccess`
......@@ -32,6 +34,4 @@ server). For a development server instead, activate the documentation. `.htacces
development: RewriteRule (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|docs?)/ - [F]
</pre>
b) Latest stable version under https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Index.html
......@@ -20,6 +20,7 @@ Neue Versionsnummer
* qfq/extension/Documentation/Release.rst
* Den Inhalt von Release.rst kopieren nach qfq/extension/RELEASE.txt.
* Den Inhalt von Release.rst kopieren nach CHANGELOG.md.
3) In folgenden Files anpassen:
......@@ -42,8 +43,8 @@ Neue Versionsnummer
6) New Tag:
git tag v0.21.1
git push -u origin v0.21.1
git tag v0.23.2
git push -u origin v0.23.2
7) PhpStorm: Sync all files to VM qfq.
......@@ -57,3 +58,5 @@ https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info
2) In `qfq-doc` Projektverzeichnis wechseln und auf github einchecken:
git commit -a
git push # User: math-uzh, PW: <kpit>
one line: make update-qfq-doc; pushd ../qfq-doc; git commit -a; git push; popd
\ No newline at end of file
......@@ -197,7 +197,7 @@ Setup a *report* to manage all *forms*:
10 {
# List of Forms: Do not show this list of forms if there is a form given by SIP.
# Table header.
sql = SELECT CONCAT('{{pageId:T}}&form=Form&') as _Pagen, '#', 'Name', 'Title', 'Table', '' FROM (SELECT 1) AS fake WHERE '{{form:SE}}'=''
sql = SELECT CONCAT('{{pageId:T}}&form=form&') as _Pagen, '#', 'Name', 'Title', 'Table', '' FROM (SELECT 1) AS fake WHERE '{{form:SE}}'=''
head = <table class="table table-hover qfq-table-50">
tail = </table>
rbeg = <thead><tr>
......@@ -207,7 +207,7 @@ Setup a *report* to manage all *forms*:
10 {
# All forms
sql = SELECT CONCAT('{{pageId:T}}&form=Form&r=', f.id) as _Pagee, f.id, f.name, f.title, f.tableName, CONCAT('form=Form&r=', f.id) as _Paged FROM Form AS f ORDER BY f.name
sql = SELECT CONCAT('{{pageId:T}}&form=form&r=', f.id) as _Pagee, f.id, f.name, f.title, f.tableName, CONCAT('form=form&r=', f.id) as _Paged FROM Form AS f ORDER BY f.name
rbeg = <tr>
rend = </tr>
fbeg = <td>
......@@ -1644,9 +1644,9 @@ 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 | 'client | no | url | url-skip-history' (Default: client): See `form-forward`_. |
|Forward Mode | 'client | no | url | url-skip-history' (Default: client): See `form-forward`_. |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Forward Page | URL or Typo3 page id/alias. 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`_. |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Parameter | Misc additional parameters. See `form-parameter`_. |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
......@@ -1753,33 +1753,65 @@ Display or hide the button `new`, `delete`, `close`, `save`.
Forward: Save / Close
^^^^^^^^^^^^^^^^^^^^^
Forward
'''''''
Forward (=forwardMode)
''''''''''''''''''''''
After the user presses *Save*, *Close*, *Delete* or *New*, different actions are possible where the browser redirects to.
* `client` (default) - the QFQ Javascript logic, inside the browser, decides to stay on the page or to force a redirection
* `client` (default) - the QFQ browser Javascript logic, decides to stay on the page or to force a redirection
to a previous page.
* *Close* closes the current page and goes back to the previous page.
* *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
* *Save* stays on the current page.
* `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 named URL or T3 page. Independent if the user presses `save` or `close`.
* `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.
Only with `Forward` == `url` | `url-skip-history`, the definition of `Forward URL / Page` becomes active.
Forward URL / Page
''''''''''''''''''
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 Alias pageid>&a=123#bottom, ?id=<T3 page id>&a=123#bottom`
* `{{SELECT ...}}`
* `<mode>|<url>`
* `<mode>` - Valid keywords are as above: `no|client|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.
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:
Possible values:
* `{{submit_reason:CE:alnumx}}` = `save` or `save,close`
* `http://john-doe.com` - fix URL.
* `?thanks` - fix URL, inside current Typo3 installation.
* `{{SELECT ... }}` - dynamically calculated, after all processing is done. This is very usefull, to redirect to different
targets, depending on user input or whatever.
Example forwardPage
^^^^^^^^^^^^^^^^^^^
* `{{SELECT IF('{{formModeGlobal:S:anumx}}'='requiredOff', 'no', 'client') }}`
* `{{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:
......@@ -2011,12 +2043,21 @@ 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 fieldset needs to be assigned to a pill.
* If there is at least one pill defined, every *fieldset* needs to be assigned to a pill.
* Pills are not 'dynamicUpdate' aware (at the moment). At least during form load, *modeSql* can be dynamically computed to
switch the pill in show / readonly (disabled) / hidden state.
* 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.
* *parameter*:
......@@ -2298,6 +2339,8 @@ See also at specific *FormElement* definitions.
| sqlDelete | string | |
| sqlAfter | string | |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
| fileButtonText | string | Overwrite default 'Choose File' |
+------------------------+--------+----------------------------------------------------------------------------------------------------------+
Effect matrix
......@@ -2890,6 +2933,10 @@ Inside the *Form editor* it's shown as a 'native FormElement'.
During saving the current record, it behaves like an action FormElement
and will be processed after saving the primary record and before any action FormElements are processed.
* *FormElement.value*: By default, the full path of any already uploaded file is shown. To show something different, e.g.
only the filename, define: ::
{{SELECT SUBSTRING_INDEX(pathFilenamePicture, '/', -1) FROM Note WHERE id={{id:R0}} }}
* *FormElement.parameter*:
......@@ -2910,7 +2957,7 @@ and will be processed after saving the primary record and before any action Form
* If for a specific filetype is no mime type available, the definition of file extension(s) is possible. This is **less
secure**, cause there is no *content* check on the server after the upload.
* *maxFileSize*: max filesize in Bytes for an uploaded file. Default: 10485760 (=10MB)
* *maxFileSize*: max filesize in bytes for an uploaded file. Default: 10485760 (=10MB)
* *fileDestination*: Destination where to copy the file. A good practice is to specify a relative `fileDestination` -
such an installation (filesystem and database) are moveable.
......@@ -2942,7 +2989,7 @@ and will be processed after saving the primary record and before any action Form
Immediately after the upload finished (before the user press save), the file will be checked on the server for it's
content or file extension (see 'accept').
The maximum size is defined by the minimum of `upload_max_filesize`, `post_max_size`and `memory_limit` (PHP script) in the php.ini.
The maximum size is defined by the minimum of `upload_max_filesize`, `post_max_size` and `memory_limit` (PHP script) in the php.ini.
In case of broken uploads, please also check `max_input_time` in php.ini.
......@@ -4477,6 +4524,8 @@ Column: _link
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| | |Render |r:<mode> |r:[0-5] |See: `render-mode`_, Default: 0 |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| | |Button |b[:0|1|<btn class>] | b:0, b:1, b:success |'b', 'b:1': a bootstrap button is created. 'b:0' disable the button. <btn class>: default, primary, success, info, warning,danger |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Picture |P:<filename> |P:bullet-red.gif |Picture '<img src="bullet-red.gif"alt="....">', default link class: internal. |
+---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
| |x |Edit |E |E |Show 'edit' icon as image |
......
......@@ -36,6 +36,64 @@ Features
Bug Fixes
^^^^^^^^^
Release
=======
Version 0.23.1
--------------
Date: 23.9.2017
Bug Fixes
^^^^^^^^^
* #4620 / Easy Fix: saveButtonText / closeButtonText Formatierung
Version 0.23.0
--------------
Date: 17.09.2017
Features
^^^^^^^^
* #3752 / Pills auf mode|modeSql=hidden|readonly setzen - implemented during 'form load' (not dynamic update)
Bug Fixes
^^^^^^^^^
* #4548 /Template Group: 'form-update' broken - Broken Redirect after Save - Broken same HTML ID for FE copies in a template group.
* #4548 /Template Group: 'form-update' broken - max tg element value/index shown after save instead of last user supplied value, but save is ok. Neu wird nach dem Speichern das Formular nochmal komplett geladen. Das ist wichtig um die durch aftersave geaenderten Records in die Formularelemente zu bekommen.
Release
=======
Version 0.22
------------
Date: 14.09.2017
Notes
^^^^^
* Form Editor: element 'forwardPage' is static again (no dynamic update) - see features in #4511.
Features
^^^^^^^^
* #4511 / Form: URL Forward - mode dynamic computed
Bug Fixes
^^^^^^^^^
* #4512 | SIP URL does not respect anker token '#'- fixed PLUS: L and type _GET Params included in links which contain a SIP (regular links still open).
* #4508 / Form: during Save with FE with 'report'-Note/Values an exception is thrown - report does not expect, to be called without typo3 - but this is the case during save and generating the JSON.
* #4021 / "required" asterik does not handle multi column labels correctly
* #4423 / Date inputs with readonly: label is grey.
* Empty date might create '2001-00-00'
* #4504 / Upload Button: required asterik missing after save - seems to be a problem for every element - should be fixed now.
Version 0.21.0
--------------
......
......@@ -2,8 +2,8 @@
[general]
project = QFQ - Quick Form Query
version = 0.21
release = 0.21.1
version = 0.23
release = 0.23.2
t3author = Carsten Rose
copyright = since 2017 by the author
......
......@@ -57,9 +57,9 @@ copyright = u'2017, Carsten Rose'
# built documents.lease
#
# The short X.Y version.
version = '0.21'
version = '0.23'
# The full version, including alpha/beta/rc tags.
release = '0.21.1'
release = '0.23.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
......@@ -36,6 +36,64 @@ Features
Bug Fixes
^^^^^^^^^
Release
=======
Version 0.23.1
--------------
Date: 23.9.2017
Bug Fixes
^^^^^^^^^
* #4620 / Easy Fix: saveButtonText / closeButtonText Formatierung
Version 0.23.0
--------------
Date: 17.09.2017
Features
^^^^^^^^
* #3752 / Pills auf mode|modeSql=hidden|readonly setzen - implemented during 'form load' (not dynamic update)
Bug Fixes
^^^^^^^^^
* #4548 /Template Group: 'form-update' broken - Broken Redirect after Save - Broken same HTML ID for FE copies in a template group.
* #4548 /Template Group: 'form-update' broken - max tg element value/index shown after save instead of last user supplied value, but save is ok. Neu wird nach dem Speichern das Formular nochmal komplett geladen. Das ist wichtig um die durch aftersave geaenderten Records in die Formularelemente zu bekommen.
Release
=======
Version 0.22
------------
Date: 14.09.2017
Notes
^^^^^
* Form Editor: element 'forwardPage' is static again (no dynamic update) - see features in #4511.
Features
^^^^^^^^
* #4511 / Form: URL Forward - mode dynamic computed
Bug Fixes
^^^^^^^^^
* #4512 | SIP URL does not respect anker token '#'- fixed PLUS: L and type _GET Params included in links which contain a SIP (regular links still open).
* #4508 / Form: during Save with FE with 'report'-Note/Values an exception is thrown - report does not expect, to be called without typo3 - but this is the case during save and generating the JSON.
* #4021 / "required" asterik does not handle multi column labels correctly
* #4423 / Date inputs with readonly: label is grey.
* Empty date might create '2001-00-00'
* #4504 / Upload Button: required asterik missing after save - seems to be a problem for every element - should be fixed now.
Version 0.21.0
--------------
......
......@@ -10,6 +10,6 @@ $EM_CONF[$_EXTKEY] = array(
'dependencies' => 'fluid,extbase',
'clearcacheonload' => true,
'state' => 'alpha',
'version' => '0.21.1',
'version' => '0.23.2',
);
......@@ -158,7 +158,7 @@ abstract class AbstractBuildForm {
* @throws DbException
* @throws \qfq\UserFormException
*/
public function process($mode, $htmlElementNameIdZero = false) {
public function process($mode, $htmlElementNameIdZero = false, $latestFeSpecNative = array()) {
$htmlHead = '';
$htmlTail = '';
$htmlT3vars = '';
......@@ -166,6 +166,11 @@ abstract class AbstractBuildForm {
$htmlElements = '';
$json = array();
// After action 'afterSave', it's necessary to reinitialize the FeSpecNative
if (!empty($latestFeSpecNative)) {
$this->feSpecNative = $latestFeSpecNative;
}
$modeCollectFe = FLAG_DYNAMIC_UPDATE;
$storeUse = STORE_USE_DEFAULT;
......@@ -195,12 +200,6 @@ abstract class AbstractBuildForm {
$htmlElements = $this->elements($recordId, $filter, 0, $json, $modeCollectFe, $htmlElementNameIdZero, $storeUse, $mode);
if ($mode === FORM_SAVE && $recordId != 0) {
// $json[] = [API_ELEMENT_UPDATE => [DIRTY_RECORD_HASH_MD5 => [API_ELEMENT_ATTRIBUTE => ['value' => $newMd5]]]];
// $json[] = [API_ELEMENT_UPDATE => [DIRTY_RECORD_HASH_MD5 => ['value' => $newMd5]]];
// element-update: with 'content'
// $inputMd5 = $this->buildInputRecordHashMd5(false);
// $json[][API_ELEMENT_UPDATE][DIRTY_RECORD_HASH_MD5_SPAN][API_ELEMENT_CONTENT] = $inputMd5;
// element-update: with 'value'
$recordId = $this->store->getVar(SIP_RECORD_ID, STORE_SIP . STORE_ZERO);
......@@ -208,10 +207,6 @@ abstract class AbstractBuildForm {
// Via 'element-update'
$json[][API_ELEMENT_UPDATE][DIRTY_RECORD_HASH_MD5][API_ELEMENT_ATTRIBUTE]['value'] = $md5;
// Via 'form-update'
// $json[] = [API_FORM_UPDATE_FORM_ELEMENT => DIRTY_RECORD_HASH_MD5, API_FORM_UPDATE_VALUE => $md5,
// API_FORM_UPDATE_DISABLED => false, API_FORM_UPDATE_REQUIRED => false ];
}
}
......@@ -531,7 +526,7 @@ abstract class AbstractBuildForm {
continue; // skip this FE
}
$flagOutput = ($fe[FE_TYPE] !== FE_TYPE_EXTRA); // type='extra' will not displayed and not transmitted to the form
$flagOutput = ($fe[FE_TYPE] !== FE_TYPE_EXTRA); // type='extra' will not displayed and not transmitted to the form.
$debugStack = array();
......@@ -860,7 +855,8 @@ abstract class AbstractBuildForm {
if (isset($formElement[FE_LABEL])) {
$key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_LABEL;
$json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = $this->buildLabel($htmlFormElementName, $formElement[FE_LABEL]);
$addClass = ($formElement[FE_MODE] == FE_MODE_REQUIRED) ? CSS_REQUIRED : '';
$json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = $this->buildLabel($htmlFormElementName, $formElement[FE_LABEL], $addClass);
}
if (isset($formElement[FE_NOTE])) {
......@@ -2274,7 +2270,6 @@ abstract class AbstractBuildForm {
// Fill $itemKey & $itemValue
$this->getKeyValueListFromSqlEnumSpec($formElement, $itemKey, $itemValue);
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('class', 'form-control');
......@@ -2317,9 +2312,9 @@ abstract class AbstractBuildForm {
$json = $this->getFormElementForJson($htmlFormElementName, $jsonValues, $formElement);
$html = '<select ' . $attribute . '>' . $option . '</select>';
$formElement = HelperFormElement::prepareExtraButton($formElement, false);
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
$html = '<select ' . $attribute . '>' . $option . '</select>';
$html = $html . $this->getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML];
return $html . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
......@@ -2412,13 +2407,8 @@ abstract class AbstractBuildForm {
$toolTip .= PHP_EOL . "form = '" . $formElement[F_FINAL_DELETE_FORM] . "'" . PHP_EOL . "r = '" . $row[$nameColumnId] . "'";
}
// $buttonDelete = $this->buildButtonCode('delete-button', $toolTip, GLYPH_ICON_DELETE, $disabled);
$s = $this->createDeleteUrl($formElement[F_FINAL_DELETE_FORM], $row[$nameColumnId], RETURN_SIP);
// $rowHtml .= Support::wrapTag('<td>', Support::wrapTag("<button type='button' class='record-delete btn btn-default' data-sip='$s'>", '<span class="glyphicon ' . GLYPH_ICON_DELETE . '"></span>'));
$rowHtml .= Support::wrapTag('<td>', Support::wrapTag("<button type='button' class='record-delete btn btn-default' data-sip='$s' " . Support::doAttribute('title', $toolTip) . ">", '<span class="glyphicon ' . GLYPH_ICON_DELETE . '"></span>'));
}
Support::setIfNotSet($row, FE_SUBRECORD_ROW_CLASS);
......@@ -2815,10 +2805,14 @@ abstract class AbstractBuildForm {
$attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
$attribute .= Support::doAttribute('data-sip', $sipUpload);
$json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement); // Below, $formElement[FE_MODE]=FE_MODE_REQUIRED will be changed. Get the JSON unchanged
if ($value === '' || $value === false) {
$textDeleteClass = 'hidden';
$uploadClass = '';
} else {
$textDeleteClass = '';
$uploadClass = 'hidden';
if ($formElement[FE_MODE] == FE_MODE_REQUIRED) {
......@@ -2831,7 +2825,17 @@ abstract class AbstractBuildForm {
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
$attribute .= Support::doAttribute('class', $uploadClass, true);
$htmlInputFile = '<input ' . $attribute . '>' . $this->getHelpBlock();
// $htmlInputFile = '<input ' . $attribute . '>' . $this->getHelpBlock();
// <input type="file"> with BS3: https://stackoverflow.com/questions/11235206/twitter-bootstrap-form-file-element-upload-button/25053973#25053973
$attribute .= Support::doAttribute('style', "display:none;");
$htmlInputFile = '<input ' . $attribute . '>';
$attributeFileLabel = Support::doAttribute('for', $formElement[FE_HTML_ID]);
$attributeFileLabel .= Support::doAttribute('class', 'btn btn-default ' . $uploadClass);
Support::setIfNotSet($formElement, FE_FILE_BUTTON_TEXT, FE_FILE_BUTTON_TEXT_DEFAULT);
$htmlInputFile = Support::wrapTag("<label $attributeFileLabel>", $htmlInputFile . $formElement[FE_FILE_BUTTON_TEXT]);
$deleteButton = Support::wrapTag("<button type='button' class='delete-file' data-sip='$sipUpload' name='delete-$htmlFormElementName'>", $this->symbol[SYMBOL_DELETE]);
......@@ -2840,7 +2844,6 @@ abstract class AbstractBuildForm {
// <button type="button" class="file-delete" data-sip="571d1fc9e6974"><span class="glyphicon glyphicon-trash"></span></button>
$json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
$formElement = HelperFormElement::prepareExtraButton($formElement, false);
......@@ -2949,12 +2952,17 @@ abstract class AbstractBuildForm {
$attribute .= Support::doAttribute('max', $arrMinMax[1]);
}
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
$json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
$formElement = HelperFormElement::prepareExtraButton($formElement, true);
$input = Support::wrapTag('<div class="input-group">', "<input $attribute>" . $this->getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML]);
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
$input = "<input $attribute>" . $this->getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML];
if ($formElement[FE_TMP_EXTRA_BUTTON_HTML] !== '') {
$input = Support::wrapTag('<div class="input-group">', $input);
}
return $input . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
......
......@@ -168,9 +168,9 @@ class BuildFormBootstrap extends AbstractBuildForm {
$formId = $this->store->getVar(COLUMN_ID, STORE_RECORD . STORE_ZERO);
$queryStringArray = [
'id' => $this->store->getVar(SYSTEM_EDIT_FORM_PAGE, STORE_SYSTEM),
'id' => $this->store->getVar(SYSTEM_EDIT_FORM_PAGE, STORE_SYSTEM),
'form' => 'copyForm',
'r' => 0,
'r' => 0,
'idSrc' => $formId,
];
$queryString = Support::arrayToQueryString($queryStringArray);
......@@ -216,7 +216,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
$queryStringArray = [
'id' => $this->store->getVar(SYSTEM_EDIT_FORM_PAGE, STORE_SYSTEM),
'form' => $form,
'r' => 0,
'r' => 0,
];
$queryString = Support::arrayToQueryString($queryStringArray);
$sip = $this->store->getSipInstance();
......@@ -353,7 +353,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
if ($icon === '') {
$element = $text;
} else {
$element = "<span class='glyphicon $icon'>$text</span>";
$element = "<span class='glyphicon $icon'></span>" . ' ' . $text;
}
$class = Support::doAttribute('class', $class);
......@@ -389,6 +389,9 @@ class BuildFormBootstrap extends AbstractBuildForm {
$formElement = $this->evaluate->parseArray($formElement);
HelperFormElement::explodeParameter($formElement, F_PARAMETER);
$formElement = HelperFormElement::setLanguage($formElement, $parameterLanguageFieldName);
if (!empty($formElement[FE_MODE_SQL])) {
$formElement[FE_MODE] = $formElement[FE_MODE_SQL];
}
$ii++;
......@@ -399,12 +402,34 @@ class BuildFormBootstrap extends AbstractBuildForm {
}
// Anker for pill navigation
$a = '<a ' . Support::doAttribute('href', '#' . $this->createAnker($formElement['id'])) . ' data-toggle="tab">' . $formElement[FE_LABEL] . '</a>';
// $a = '<a ' . Support::doAttribute('href', '#' . $this->createAnker($formElement[FE_ID])) . ' data-toggle="tab">' . $formElement[FE_LABEL] . '</a>';
$attributeA = 'data-toggle="tab" ';
$hrefTarget = '#' . $this->createAnker($formElement[FE_ID]);
switch ($formElement[FE_MODE]) {
case FE_MODE_SHOW:
case FE_MODE_REQUIRED:
$attributeLi = '';
break;
case FE_MODE_READONLY:
$attributeLi = Support::doAttribute('class', 'disabled');
$hrefTarget = '#';
$attributeA .= Support::doAttribute('class', 'noclick');
break;
case FE_MODE_HIDDEN:
$attributeLi = Support::doAttribute('style', 'display: none');
$a = '';
break;
default:
throw new UserFormException("Unknown Mode: " . $formElement[FE_MODE], ERROR_UNKNOWN_MODE);
}
$a = Support::wrapTag("<a $attributeA" . Support::doAttribute('href', $hrefTarget) . ">", $formElement[FE_LABEL]);
if ($ii <= $maxVisiblePill) {
$pillButton .= '<li role="presentation" ' . $active . '>' . $a . '</li>';
$pillButton .= '<li role="presentation"' . $attributeLi . $active . ">" . $a . "</li>";
} else {
$pillDropdown .= '<li>' . $a . '</li>';
$pillDropdown .= '<li ' . $attributeLi . '>' . $a . "</li>";
}
$active = '';
}
......@@ -430,7 +455,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
* @return string