Commit bddd34ce authored by Rafael Ostertag's avatar Rafael Ostertag
Browse files

Merge remote-tracking branch 'remotes/origin/crose_work' into raos_work

parents 20e30e12 81e5a8dc
......@@ -19,7 +19,6 @@
/css
/fonts
/qfq.flowchart.dia.autosave
/qfq*.zip
/support
/extension/Resources/Public/fonts
/extension/Resources/Public/JavaScript
......
......@@ -34,7 +34,7 @@ LOAD
* active/valid formname: [$this->store->setVar(SYSTEM_FORM, $formName, STORE_SYSTEM);]
* SIP: [$this->store->getVar('form', STORE_SIP)]
* All parameters from active SIP: [$this->store->getStore(STORE_SIP)]
* Check Contstants.php for known Store members
* Check Contstants.php for known Store members:
* In QuickFormQuery.php the whole Form will be copied to `$this->formSpec` and depending on further processing, the
elements are available in `$this->feNative` and `$this->feAction`.
......@@ -43,13 +43,34 @@ LOAD
* If a form is called without a SIP (form.permitNew='always'), than a SIP is created on the fly (as a
parameter in the form).
* Depending on `r=0` or `r>0` a form submit will do an MySQL `insert` or `update` later during save.
* For new records (r=0), clicking on 'save' without closing the form is a tricky situation. Additionally the user might have open multiple
tabs (same form, all r=0) and after saving the record (wihtout closing the form) the user expects that it's ok to edit
the record again and again. Unfortunately, the initial created SIP (before 'form load') is not uniqe anymore (multiple
tabs might contain a saved 'new record'). To guarantee correct saving of r=0 records, a unique on the fly generated SIP
is creatd during form load - individually per browser tab.
* Uniq SIP for mutliple tabs with r=0
* Depending on `r=0` or `r>0` a form submit will do an MySQL `insert` or `update` later during save.
* For new records (r=0), clicking on 'save' without closing the form is a tricky situation. Additionally the user might have open multiple
tabs (same form, all r=0) and after saving the record (wihtout closing the form) the user expects that it's ok to edit
the record again and again. Unfortunately, the initial created SIP (before 'form load') is not uniqe anymore (multiple
tabs might contain a saved 'new record'). To guarantee correct saving of r=0 records, a unique on the fly generated SIP
is creatd during form load - individually per browser tab.
* Faking the STORE_TYPO3 for API calls:
* The PHP code api/save.php, api/load.php is called directly, without any TYPO3 Framework. Therefore the Typo3 information
'pageId', 'feUser*', 'beUser*', 'ttContentUid', ... is not available.
* *Form load*: an additional hidden Formelement '_sipForTypo3Vars' will be created with a subset of the current
STORE_TYPO3 values. The workaround with the SIP is usefull, cause the same form can be shown on different places (QFQ records) -
this is not very likely, but might happen. The 'on the fly rendered' SIP helps to deliver the status.
AbstractBuildForm.php: process() > prepareT3VarsForSave() > Store.php: copyT3VarsToSip();
* *Form save*: FillStoreForm.php: process() > Store: fillTypo3StoreFromSip()
* Formular zusammenbauen
* QuickFormQuery: doForm > loadFormSpecification - laedt alle Elemente die nicht genested sind: native, pill, fieldset, templateGroup >> $his->formNative
* Damit wird '(BuildFormBootstrap / AbstractBuildForm) > process()' aufgerufen.
* Hier wird AbstractBuildForm->elements() aufgerufen (ein Aufruf fuer alle root elemente).
* Pro native Element (inkl. pill, fieldset, templateGroup) wird $builElementFunctionName aufgerufen.
- buildText()
- ....
- buildFieldSet() << von hier werden alle zum aktuellen 'FieldSet' gehoerenden SubElemente abgearbeitet - via AbstractBuildForm->elements() (damit schliesst sich der Kreis und wird rekursiv)
- buildPill() << von hier werden alle zum aktuellen 'Pill' gehoerenden SubElemente abgearbeitet - via AbstractBuildForm->elements() (damit schliesst sich der Kreis und wird rekursiv)
- buildTemplateGroup() << von hier werden alle zum aktuellen 'Pill' gehoerenden SubElemente abgearbeitet - via AbstractBuildForm->elements() (damit schliesst sich der Kreis und wird rekursiv)
>>
SAVE
----
* Via wrapper api/save.php
......
......@@ -18,7 +18,7 @@ Neue Versionsnummer
git checkout master
git merge crose_work
4) Neuen Tag vergeben: git tag 0.11
4) Neuen Tag vergeben: git tag 0.12.0
5) Alle Files, inkl. Tags, in GIT einchecken.
......
......@@ -32,7 +32,7 @@ Preparation for Ubuntu 14.04::
Preparation steps for Ubuntu 16.04::
sudo apt-get install php7-intl
sudo apt install php7.0-intl
Setup
-----
......@@ -53,6 +53,12 @@ Setup
::
page.meta {
X-UA-Compatible = IE=edge
X-UA-Compatible.attribute = http-equiv
viewport=width=device-width, initial-scale=1
}
page.includeCSS {
file1 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap.min.css
......@@ -68,9 +74,10 @@ Setup
file2 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap.min.js
file3 = typo3conf/ext/qfq/Resources/Public/JavaScript/validator.min.js
file4 = typo3conf/ext/qfq/Resources/Public/JavaScript/jqx-all.js
file5 = typo3conf/ext/qfq/Resources/Public/JavaScript/tinymce.min.js
file6 = typo3conf/ext/qfq/Resources/Public/JavaScript/EventEmitter.min.js
file7 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.min.js
file5 = typo3conf/ext/qfq/Resources/Public/JavaScript/globalize.js
file6 = typo3conf/ext/qfq/Resources/Public/JavaScript/tinymce.min.js
file7 = typo3conf/ext/qfq/Resources/Public/JavaScript/EventEmitter.min.js
file8 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.min.js
}
......@@ -80,11 +87,11 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content
::
# If there is a form given by SIP: show
form = {{form:S}}
# If there is a form given by SIP: show
form={{form:S}}
10 {
# List of Forms: Do not show this list of forms if there is a form given by SIP.
# 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}}'=''
head = <table class="table table-hover">
......@@ -95,9 +102,8 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content
fend = </th>
10 {
# All forms.
# Table rows.
sql = SELECT CONCAT('{{pageId:T}}&form=Form&r=', f.id) as Pagee, f.id, f.name, f.title, f.tableName FROM Form AS f ORDER BY f.name
# 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
rbeg = <tr>
rend = </tr>
fbeg = <td>
......@@ -105,54 +111,57 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content
}
}
.. _config-qfq-ini:
config.qfq.ini
--------------
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| Keyword | Example | Description |
+=========================+=========================================+============================================================================+
| DB_USER | DB_USER=qfqUser | Credentials configured in MySQL |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_PASSWORD | DB_PASSWORD=12345678 | Credentials configured in MySQL |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_SERVER | DB_SERVER=localhost | Hostname of MySQL Server |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME | DB_NAME=qfq_db | Database name |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME_TEST | DB_NAME_TEST=qfq_db_test | Used during development of QFQ |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_INIT | DB_INIT=set names utf8 | Global init for using the database. |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SQL_LOG | SQL_LOG=sql.log | Filename to log SQL commands: relative to <ext_dir> or absolute. |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SQL_LOG_MODE | SQL_LOG_MODE=modify | *all*: every statement will be logged - this is a lot |
| | | *modify*: log only statements who change data |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SHOW_DEBUG_INFO | SHOW_DEBUG_INFO=auto | Possible values: auto|yes|no. For 'auto': If a BE User is logged in, |
| | | debug information will be shown on the fronend. |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_LINK_CLASS_INTERNAL | CSS_LINK_CLASS_INTERNAL=internal | CSS class name of links which points to internal tagets |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_LINK_CLASS_EXTERNAL | CSS_LINK_CLASS_EXTERNAL=external | CSS class name of links which points to internal tagets |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_CONTAINER |CSS_CLASS_QFQ_CONTAINER=container | QFQ with own Bootstrap: 'container'. |
| | | QFQ already nested in Bootstrap of mainpage: <empty> |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_FORM_PILL |CSS_CLASS_QFQ_FORM_PILL=qfq-color-grey-1 | Wrap around title bar for pills: CSS Class, typically a background color |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_FORM_BODY |CSS_CLASS_QFQ_FORM_BODY=qfq-color-grey-2 | Wrap around formelements: CSS Class, typically a background color |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DATE_FORMAT | DATE_FORMAT= yyyy-mm-dd | Possible options: yyyy-mm-dd, dd.mm.yyyy |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_PATTERN_ERROR |FORM_DATA_PATTERN_ERROR=please check pa. | Customizable error message used in validator.js. 'pattern' violation |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_REQUIRED_ERROR|FORM_DATA_REQUIRED_ERROR=missing value | Customizable error message used in validator.js. 'required' fields |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_MATCH_ERROR |FORM_DATA_MATCH_ERROR=type error | Customizable error message used in validator.js. 'match' retype mismatch |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_ERROR |FORM_DATA_ERROR=generic error | Customizable error message used in validator.js. 'no specific' given |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| Keyword | Example | Description |
+=============================+=========================================+============================================================================+
| DB_USER | DB_USER=qfqUser | Credentials configured in MySQL |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_PASSWORD | DB_PASSWORD=12345678 | Credentials configured in MySQL |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_SERVER | DB_SERVER=localhost | Hostname of MySQL Server |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME | DB_NAME=qfq_db | Database name |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME_TEST | DB_NAME_TEST=qfq_db_test | Used during development of QFQ |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_INIT | DB_INIT=set names utf8 | Global init for using the database. |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SQL_LOG | SQL_LOG=sql.log | Filename to log SQL commands: relative to <ext_dir> or absolute. |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SQL_LOG_MODE | SQL_LOG_MODE=modify | *all*: every statement will be logged - this is a lot |
| | | *modify*: log only statements who change data |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SHOW_DEBUG_INFO | SHOW_DEBUG_INFO=auto | Possible values: auto|yes|no. For 'auto': If a BE User is logged in, |
| | | debug information will be shown on the fronend. |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_LINK_CLASS_INTERNA L | CSS_LINK_CLASS_INTERNAL=internal | CSS class name of links which points to internal tagets |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_LINK_CLASS_EXTERNAL | CSS_LINK_CLASS_EXTERNAL=external | CSS class name of links which points to internal tagets |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_CONTAINER |CSS_CLASS_QFQ_CONTAINER=container | QFQ with own Bootstrap: 'container'. |
| | | QFQ already nested in Bootstrap of mainpage: <empty> |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_FORM_PILL |CSS_CLASS_QFQ_FORM_PILL=qfq-color-grey-1 | Wrap around title bar for pills: CSS Class, typically a background color |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_FORM_BODY |CSS_CLASS_QFQ_FORM_BODY=qfq-color-grey-2 | Wrap around formelements: CSS Class, typically a background color |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DATE_FORMAT | DATE_FORMAT= yyyy-mm-dd | Possible options: yyyy-mm-dd, dd.mm.yyyy |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_PATTERN_ERROR |FORM_DATA_PATTERN_ERROR=please check pa. | Customizable error message used in validator.js. 'pattern' violation |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_REQUIRED_ERROR |FORM_DATA_REQUIRED_ERROR=missing value | Customizable error message used in validator.js. 'required' fields |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_MATCH_ERROR |FORM_DATA_MATCH_ERROR=type error | Customizable error message used in validator.js. 'match' retype mismatch |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_DATA_ERROR |FORM_DATA_ERROR=generic error | Customizable error message used in validator.js. 'no specific' given |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_BUTTON_ON_CHANGE_CLASS | FORM_BUTTON_ON_CHANGE_CLASS=alert-info btn-info | Color for save button after modification |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
......@@ -160,6 +169,7 @@ Example: *typo3conf/config.qfq.ini*
::
; To get internal default values, inactivate the option by commenting (= ';') it.
DB_USER = qfqUser
DB_SERVER = localhost
DB_PASSWORD = 12345678
......@@ -169,14 +179,17 @@ Example: *typo3conf/config.qfq.ini*
SHOW_DEBUG_INFO = auto
CSS_LINK_CLASS_INTERNAL = internal
CSS_LINK_CLASS_EXT = external
;CSS_CLASS_QFQ_CONTAINER =
;CSS_CLASS_QFQ_FORM =
CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1
CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2
;FORM_DATA_PATTERN_ERROR =
;FORM_DATA_REQUIRED_ERROR =
;FORM_DATA_MATCH_ERROR =
;FORM_DATA_ERROR =
;CSS_CLASS_QFQ_CONTAINER =
;CSS_CLASS_QFQ_FORM =
CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1
CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2
;FORM_DATA_PATTERN_ERROR =
;FORM_DATA_REQUIRED_ERROR =
;FORM_DATA_MATCH_ERROR =
;FORM_DATA_ERROR =
;FORM_BS_LABEL_COLUMNS = 3
;FORM_BS_INPUT_COLUMNS = 6
;FORM_BS_NOTE_COLUMNS = 3
Documentation
-------------
......@@ -187,7 +200,7 @@ To render the QFQ reST documentation:
Preparation for Ubuntu 16.04::
sudo apt install unzip python-setuptools
sudo apt install unzip python-setuptools python-pip
* Install the extension "Sphinx Python Documentation Generator and Viewer" (sphinx).
......@@ -197,3 +210,5 @@ Preparation for Ubuntu 16.04::
* In the Exension Manager open the configuration dialog of the extension 'sphinx'. Activate the 'Sphinx 1.4.4' option and save it.
* On top of the browser window click on the 'question mark' to open the menu, choose 'Sphinx'.
* Show doumentation 'QFQ Extension'
* If you have problems with the rendering, please check: http://mbless.de/blog/2015/01/26/sphinx-doc-installation-steps.html
......@@ -6,8 +6,8 @@
conf.py:
copyright: 2017
project: QFQ Extension
version: 0.11.0
release: 0.11.0
version: 0.12.0
release: 0.12.0
latex_documents:
- - Index
- qfq.tex
......
......@@ -57,9 +57,9 @@ copyright = u'2017, Carsten Rose'
# built documents.
#
# The short X.Y version.
version = '0.8'
version = '0.12'
# The full version, including alpha/beta/rc tags.
release = '0.11.0'
release = '0.12.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
Version 0.13
============
Changes
-------
* Table 'FormElement'
* Modified column: 'checkType' - new value 'numerical'
ALTER TABLE FormElement MODIFY COLUMN checkType ENUM('alnumx','digit','numerical','email','min|max','min|max date',
'pattern','allbut','all') NOT NULL DEFAULT 'alnumx'
Bug Fixes
---------
* #2138 / digit sanitize: new class 'numerical' implemented.
Version 0.12
============
Changes
-------
* Table 'FormElement'
* New column: rowLabelInputNote
ALTER TABLE `FormElement` ADD `rowLabelInputNote` set('row','label','/label','input','/input','note','/note','/row')
NOT NULL DEFAULT 'row,label,/label,input,/input,note,/note,/row' AFTER `bsNoteColumns` ;
* Modified column: 'type' - new value 'templateGroup'
ALTER TABLE `FormElement` CHANGE `type` `type` ENUM( 'checkbox', 'date', 'datetime', 'dateJQW', 'datetimeJQW', 'extra',
'gridJQW', 'text', 'editor', 'time', 'note', 'password', 'radio', 'select', 'subrecord', 'upload', 'fieldset', 'pill',
'templateGroup', 'beforeLoad', 'beforeSave', 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterLoad', 'afterSave',
'afterInsert', 'afterUpdate', 'afterDelete', 'sendMail' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'text';
* formEditor.sql: Added HTML 'placeholder' in FormEditor for bs*Columns.
* PLAY 'formEditor.sql'.
* User Input will be UTF8 normalized.
* INSTALL 'php5-intl' or 'php7.0-intl' on Webserver.
* Add globalize.js to be included. Needed by jqx-all.js
* UPDATE EXISTING TypoScript TEMPLATES of QFQ Installation.
Features
--------
* User input will be UTF8 normalized
* config.qfq-ini:
* New configuration values: FORM_BS_LABEL_COLUMNS / FORM_BS_INPUT_COLUMNS / FORM_BS_NOTE_COLUMNS
* Comment empty variables - the new default setting is, that empty parameter in config.qfq.ini means EMPTY (=parameter is set and will not be overwritten by internal default), not UNDEFINED (overwritten by internal default).
* FileUpload:
* Implemented new Formelement.parameter: fileReplace=always - will replace existing files.
* Multiple / Advanced Upload: new logic implements slaveId, sqlInsert, sqlUpdate, sqlDelete.
* FormElement.parameter: sqlBefore / sqlAfter fired during 'Form' save for action elements.
* STORE FORM: variable 'filename' moved to STORE VAR - sanatize class needs no longer specified.
* STORE VAR: two new variables 'filename' and 'fileDestination' valid during processing of current upload FormElement.
* Default store priority list changed. Old: 'FSRD', New: 'FSRVD'.
* CODING.md: update doc for FormElement 'upload' and general 'Form' rendering & save (recursive rendering).
* User manual:
* Described form layout options: description for bsLabelColumn, bsInputColumn, bsNoteColumn
* Update 'file-upload' doc.
* Described 3 examples for upload forms.
* Administrator manual:
* Add description page.meta...
* New FormElement (type= 'container') added: 'templateGroup'
* FormElement.parameter.tgAddClass | tgAddText | tgRemoveClass | tgRemoveText | tgClass
* FormElement.maxSize: max number of duplicates
* #3230 templateGroup: margin between copies. 'tgClass' implemented.
* Native FormElements:
* FormElement.parameter.htlmlBefore|htmlAfter - add the specified HTML code before or after the element (outside of any wrapping)
* #3224, #3231 Html Tag <hr> als FormElement. >> htmlBefore | htmlAfter.
* FormElement.parameter.wrapLabel | wrapInput | wrapAfter | wrapRow - if specified, any default wrapping is omitted.
* FormElement.bsNoteColumns | bsInputColumns | bsNoteColumns - a '0' will suppress the whole rendering of the item.
* FormElement.rowLabelInputNote - switch on/off rendering of the corresponding system wrapping items.
* #3232 Define custom 'on-change' color - used for the save button: Form.parameter.buttonOnChangeClass=...
* Form.parameter & FormElement.parameter: Lines starting with '#' are treated as comments and will not be parsed.
Bug fixes
---------
* User manual:
* Fixed double include of validator.js in T3 Typoscript template example.
* Fixed wrong store name SYSTEM: S > Y
* Fixed wrong STORE_FORM variable names.
* Reformat FormElement.parameter description.
* Styling errors fixed.
* Use of 'decryptCurlyBraces()' to get better error messages.
* Skip unwanted parameter expansion during save.
* Fixed bug with uninitialized FE_SLAVE_ID
* formEditor.sql:
* The defintion as 'editor' (not text) for FormElement 'note' has been lost - reinserted.
* Fixed problem while playing SQL query - deleting old FormElements of Formeditor deleted also FormElements of other forms.
* #3066 / help-text with-error - CSS class 'hidden' will be rendered by default (as long there is no error).
* Labels are skipped, if FormElement.bsLabelColumns=0.
* Respect attribute `data-class-on-change` on save buttons.
Version 0.11
============
......
......@@ -10,5 +10,5 @@ $EM_CONF[$_EXTKEY] = array(
'dependencies' => 'fluid,extbase',
'clearcacheonload' => true,
'state' => 'alpha',
'version' => '0.11.0'
'version' => '0.12.0'
);
\ No newline at end of file
This diff is collapsed.
......@@ -62,6 +62,9 @@ class BuildFormBootstrap extends AbstractBuildForm {
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_START] = "";
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_END] = "";
$this->wrap[WRAP_SETUP_IN_TEMPLATE_GROUP][WRAP_SETUP_START] = "";
$this->wrap[WRAP_SETUP_IN_TEMPLATE_GROUP][WRAP_SETUP_END] = "";
// $this->feDivClass['radio'] = 'radio';
// $this->feDivClass['checkbox'] = 'checkbox';
}
......@@ -151,7 +154,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
$toolTip .= PHP_EOL . "table = '" . $this->formSpec[F_TABLE_NAME] . "'" . PHP_EOL . "r = '" . $recordId . "'";
}
$buttonSave = $this->buildButtonCode('save-button', $toolTip, GLYPH_ICON_CHECK);
$buttonSave = $this->buildButtonCode('save-button', $toolTip, GLYPH_ICON_CHECK, '', $this->formSpec[F_BUTTON_ON_CHANGE_CLASS]);
}
// Button: Close
......@@ -209,13 +212,13 @@ class BuildFormBootstrap extends AbstractBuildForm {
/**
* Creates a button with the given attributes. If there is no $icon given, render the button without glyph.
*
* @param $id
* @param $title
* @param $icon
* @param string $id
* @param string $title
* @param string $icon
* @param string $disabled
* @return string
*/
private function buildButtonCode($id, $title, $icon, $disabled = '') {
private function buildButtonCode($id, $title, $icon, $disabled = '', $buttonOnChangeClass = '') {
$element = "<span class='glyphicon $icon'></span>";
$classAdd = "navbar-btn";
......@@ -225,7 +228,10 @@ class BuildFormBootstrap extends AbstractBuildForm {
$classAdd = '';
}
return "<button id='$id' type='button' class='btn btn-default $classAdd $disabled' " . Support::doAttribute('title', $title) . ">$element</button>";
$class = Support::doAttribute('class', ["btn btn-default", $classAdd]);
$onChange = Support::doAttribute('data-class-on-change', $buttonOnChangeClass);
$title = Support::doAttribute('title', $title);
return "<button id='$id' type='button' $class $onChange $title $disabled>$element</button>";
}
/**
......@@ -325,7 +331,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
if ($this->formSpec[F_SUBMIT_BUTTON_TEXT] !== '') {
$buttonText = $this->formSpec[F_SUBMIT_BUTTON_TEXT];
$htmlElement = $this->buildButtonCode('save-button', $buttonText, '');
$htmlElement = $this->buildButtonCode('save-button', $buttonText, '', '', $this->formSpec[F_BUTTON_ON_CHANGE_CLASS]);
$html .= $this->wrapItem(WRAP_SETUP_LABEL, '');
$html .= $this->wrapItem(WRAP_SETUP_INPUT, $htmlElement);
......@@ -400,24 +406,66 @@ EOF;
}
/**
* @param array $formElement
* @param string $htmlElement
* @return string
* @param array $formElement Complete FormElement, especially some FE_WRAP
* @param string $htmlElement Content to wrap.
* @param $htmlFormElementId
* @return string Wrapped $htmlElement
* @throws \qfq\UserFormException
*/
public function buildRowNative(array $formElement, $htmlElement, $htmlFormElementId) {
$html = '';
$htmlLabel = '';
if ($formElement[FE_BS_LABEL_COLUMNS] > 0) {
$htmlLabel = $this->buildLabel($htmlFormElementId, $formElement[FE_LABEL]);
}
$html .= $this->customWrap($formElement, $htmlLabel, FE_WRAP_LABEL, $formElement[FE_BS_LABEL_COLUMNS],
[$this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END]]);
$htmlLabel = $this->buildLabel($htmlFormElementId, $formElement[FE_LABEL]);
$html .= $this->customWrap($formElement, $htmlElement, FE_WRAP_INPUT, $formElement[FE_BS_INPUT_COLUMNS],
[$this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END]]);
$html .= $this->wrapItem(WRAP_SETUP_LABEL, $htmlLabel);
$html .= $this->wrapItem(WRAP_SETUP_INPUT, $htmlElement);
$html .= $this->wrapItem(WRAP_SETUP_NOTE, $formElement[FE_NOTE], true);
$note = Support::wrapTag("<div class='qfq-note'>", $formElement[FE_NOTE], true);
$html .= $this->customWrap($formElement, $note, FE_WRAP_NOTE, $formElement[FE_BS_NOTE_COLUMNS],
[$this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END]]);
$html = $this->wrapItem(WRAP_SETUP_ELEMENT, $html);
// ROW
$openTag = (Support::findInSet('row', $formElement[FE_WRAP_ROW_LABEL_INPUT_NOW])) ? $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_START] : '';
$closeTag = (Support::findInSet('/row', $formElement[FE_WRAP_ROW_LABEL_INPUT_NOW])) ? $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_END] : '';
$html = $this->customWrap($formElement, $html, FE_WRAP_ROW, 99, [$openTag, $closeTag]);
return $html;
}
/**
*
* @param array $formElement Complete FormElement, especially some FE_WRAP
* @param string $htmlElement Content to wrap.
* @param string $wrapName FE_WRAP_ROW, FE_WRAP_LABEL, FE_WRAP_INPUT, FE_WRAP_NOTE
* @param int $bsColumns
* @param array $wrapArray Systemwide Defaults: [ 'open wrap', 'close wrap' ]
* @return string Wrapped $htmlElement
* @throws \qfq\UserFormException
*/
private function customWrap(array $formElement, $htmlElement, $wrapName, $bsColumns, array $wrapArray) {
if ($bsColumns == 0) {
$wrapArray[0] = '';
$wrapArray[1] = '';
}
if (isset($formElement[$wrapName])) {
$wrapArray = explode('|', $formElement[$wrapName], 2);
}
if (count($wrapArray) != 2) {
throw new UserFormException("Need open & close wrap token for FormElement.parameter" . $wrapName . " - E.g.: <div ...>|</div>", ERROR_MISSING_VALUE);
}
return $wrapArray[0] . $htmlElement . $wrapArray[1];
}
/**
* @param $formElement
* @param $elementHtml
......@@ -449,6 +497,18 @@ EOF;
return $html;
}
/**
* Builds a templateGroup
*
* @param $formElement
* @param $elementHtml
*/
public function buildRowTemplateGroup(array $formElement, $elementHtml) {
$html = $elementHtml;
return $html;
}
/**
* @param $formElement
* @param $elementHtml
......
......@@ -39,6 +39,9 @@ class BuildFormPlain extends AbstractBuildForm {
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_START] = '<p>';
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_END] = '</p>';
$this->wrap[WRAP_SETUP_IN_TEMPLATE_GROUP][WRAP_SETUP_START] = "";
$this->wrap[WRAP_SETUP_IN_TEMPLATE_GROUP][WRAP_SETUP_END] = "";
}
public function fillWrapLabelInputNote($label, $input, $note) {
......@@ -74,13 +77,15 @@ class BuildFormPlain extends AbstractBuildForm {
// $buildElementFunctionName = 'build' . $this->buildElementFunctionName[$formElement[FE_TYPE]];
if($formElement['nestedInFieldSet']==='no')
if($formElement['nestedInFieldSet']==='no') {
$html .= $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_START];
}
$html .= $this->wrapItem(WRAP_SETUP_LABEL, $formElement[FE_LABEL]);
$html .= $this->wrapItem(WRAP_SETUP_INPUT, $htmlElement);
$html .= $this->wrapItem(WRAP_SETUP_NOTE, $formElement[FE_NOTE]);
if($formElement['nestedInFieldSet']==='no')
if($formElement['nestedInFieldSet']==='no') {
$html .= $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_END];
}
return $html;
}
......@@ -110,6 +115,10 @@ class BuildFormPlain extends AbstractBuildForm {
// TODO: Implement buildRowFieldset() method.
}
public function buildRowTemplateGroup(array $formElement, $elementHtml) {
// TODO: Implement buildRowTemplate() method.
}
public function buildRowSubrecord(array $formElement, $elementHtml) {
// TODO: Implement buildRowSubrecord() method.
}
......
......@@ -42,6 +42,8 @@ class BuildFormTable extends AbstractBuildForm {
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_START] = '<p>';
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_END] = '</p>';