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 @@ ...@@ -19,7 +19,6 @@
/css /css
/fonts /fonts
/qfq.flowchart.dia.autosave /qfq.flowchart.dia.autosave
/qfq*.zip
/support /support
/extension/Resources/Public/fonts /extension/Resources/Public/fonts
/extension/Resources/Public/JavaScript /extension/Resources/Public/JavaScript
......
...@@ -34,7 +34,7 @@ LOAD ...@@ -34,7 +34,7 @@ LOAD
* active/valid formname: [$this->store->setVar(SYSTEM_FORM, $formName, STORE_SYSTEM);] * active/valid formname: [$this->store->setVar(SYSTEM_FORM, $formName, STORE_SYSTEM);]
* SIP: [$this->store->getVar('form', STORE_SIP)] * SIP: [$this->store->getVar('form', STORE_SIP)]
* All parameters from active SIP: [$this->store->getStore(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 * 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`. elements are available in `$this->feNative` and `$this->feAction`.
...@@ -43,13 +43,34 @@ LOAD ...@@ -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 * 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). parameter in the form).
* Depending on `r=0` or `r>0` a form submit will do an MySQL `insert` or `update` later during save. * Uniq SIP for mutliple tabs with r=0
* For new records (r=0), clicking on 'save' without closing the form is a tricky situation. Additionally the user might have open multiple * Depending on `r=0` or `r>0` a form submit will do an MySQL `insert` or `update` later during save.
tabs (same form, all r=0) and after saving the record (wihtout closing the form) the user expects that it's ok to edit * For new records (r=0), clicking on 'save' without closing the form is a tricky situation. Additionally the user might have open multiple
the record again and again. Unfortunately, the initial created SIP (before 'form load') is not uniqe anymore (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
tabs might contain a saved 'new record'). To guarantee correct saving of r=0 records, a unique on the fly generated SIP the record again and again. Unfortunately, the initial created SIP (before 'form load') is not uniqe anymore (multiple
is creatd during form load - individually per browser tab. 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 SAVE
---- ----
* Via wrapper api/save.php * Via wrapper api/save.php
......
...@@ -18,7 +18,7 @@ Neue Versionsnummer ...@@ -18,7 +18,7 @@ Neue Versionsnummer
git checkout master git checkout master
git merge crose_work 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. 5) Alle Files, inkl. Tags, in GIT einchecken.
......
...@@ -32,7 +32,7 @@ Preparation for Ubuntu 14.04:: ...@@ -32,7 +32,7 @@ Preparation for Ubuntu 14.04::
Preparation steps for Ubuntu 16.04:: Preparation steps for Ubuntu 16.04::
sudo apt-get install php7-intl sudo apt install php7.0-intl
Setup Setup
----- -----
...@@ -53,6 +53,12 @@ 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 { page.includeCSS {
file1 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap.min.css file1 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap.min.css
...@@ -68,9 +74,10 @@ Setup ...@@ -68,9 +74,10 @@ Setup
file2 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap.min.js file2 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap.min.js
file3 = typo3conf/ext/qfq/Resources/Public/JavaScript/validator.min.js file3 = typo3conf/ext/qfq/Resources/Public/JavaScript/validator.min.js
file4 = typo3conf/ext/qfq/Resources/Public/JavaScript/jqx-all.js file4 = typo3conf/ext/qfq/Resources/Public/JavaScript/jqx-all.js
file5 = typo3conf/ext/qfq/Resources/Public/JavaScript/tinymce.min.js file5 = typo3conf/ext/qfq/Resources/Public/JavaScript/globalize.js
file6 = typo3conf/ext/qfq/Resources/Public/JavaScript/EventEmitter.min.js file6 = typo3conf/ext/qfq/Resources/Public/JavaScript/tinymce.min.js
file7 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.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 ...@@ -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 # If there is a form given by SIP: show
form = {{form:S}} form={{form:S}}
10 { 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. # 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"> 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 ...@@ -95,9 +102,8 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content
fend = </th> fend = </th>
10 { 10 {
# All forms. # All forms
# Table rows. 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 FROM Form AS f ORDER BY f.name
rbeg = <tr> rbeg = <tr>
rend = </tr> rend = </tr>
fbeg = <td> fbeg = <td>
...@@ -105,54 +111,57 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content ...@@ -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 config.qfq.ini
-------------- --------------
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| Keyword | Example | Description | | Keyword | Example | Description |
+=========================+=========================================+============================================================================+ +=============================+=========================================+============================================================================+
| DB_USER | DB_USER=qfqUser | Credentials configured in MySQL | | DB_USER | DB_USER=qfqUser | Credentials configured in MySQL |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_PASSWORD | DB_PASSWORD=12345678 | Credentials configured in MySQL | | DB_PASSWORD | DB_PASSWORD=12345678 | Credentials configured in MySQL |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_SERVER | DB_SERVER=localhost | Hostname of MySQL Server | | DB_SERVER | DB_SERVER=localhost | Hostname of MySQL Server |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME | DB_NAME=qfq_db | Database name | | DB_NAME | DB_NAME=qfq_db | Database name |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME_TEST | DB_NAME_TEST=qfq_db_test | Used during development of QFQ | | 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. | | 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 | 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 | | SQL_LOG_MODE | SQL_LOG_MODE=modify | *all*: every statement will be logged - this is a lot |
| | | *modify*: log only statements who change data | | | | *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, | | 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. | | | | 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_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_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'. | | CSS_CLASS_QFQ_CONTAINER |CSS_CLASS_QFQ_CONTAINER=container | QFQ with own Bootstrap: 'container'. |
| | | QFQ already nested in Bootstrap of mainpage: <empty> | | | | 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_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 | | 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 | | 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_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_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_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_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* ...@@ -160,6 +169,7 @@ Example: *typo3conf/config.qfq.ini*
:: ::
; To get internal default values, inactivate the option by commenting (= ';') it.
DB_USER = qfqUser DB_USER = qfqUser
DB_SERVER = localhost DB_SERVER = localhost
DB_PASSWORD = 12345678 DB_PASSWORD = 12345678
...@@ -169,14 +179,17 @@ Example: *typo3conf/config.qfq.ini* ...@@ -169,14 +179,17 @@ Example: *typo3conf/config.qfq.ini*
SHOW_DEBUG_INFO = auto SHOW_DEBUG_INFO = auto
CSS_LINK_CLASS_INTERNAL = internal CSS_LINK_CLASS_INTERNAL = internal
CSS_LINK_CLASS_EXT = external CSS_LINK_CLASS_EXT = external
;CSS_CLASS_QFQ_CONTAINER = ;CSS_CLASS_QFQ_CONTAINER =
;CSS_CLASS_QFQ_FORM = ;CSS_CLASS_QFQ_FORM =
CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1 CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1
CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2 CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2
;FORM_DATA_PATTERN_ERROR = ;FORM_DATA_PATTERN_ERROR =
;FORM_DATA_REQUIRED_ERROR = ;FORM_DATA_REQUIRED_ERROR =
;FORM_DATA_MATCH_ERROR = ;FORM_DATA_MATCH_ERROR =
;FORM_DATA_ERROR = ;FORM_DATA_ERROR =
;FORM_BS_LABEL_COLUMNS = 3
;FORM_BS_INPUT_COLUMNS = 6
;FORM_BS_NOTE_COLUMNS = 3
Documentation Documentation
------------- -------------
...@@ -187,7 +200,7 @@ To render the QFQ reST documentation: ...@@ -187,7 +200,7 @@ To render the QFQ reST documentation:
Preparation for Ubuntu 16.04:: 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). * Install the extension "Sphinx Python Documentation Generator and Viewer" (sphinx).
...@@ -197,3 +210,5 @@ Preparation for Ubuntu 16.04:: ...@@ -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. * 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'. * On top of the browser window click on the 'question mark' to open the menu, choose 'Sphinx'.
* Show doumentation 'QFQ Extension' * 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 @@ ...@@ -6,8 +6,8 @@
conf.py: conf.py:
copyright: 2017 copyright: 2017
project: QFQ Extension project: QFQ Extension
version: 0.11.0 version: 0.12.0
release: 0.11.0 release: 0.12.0
latex_documents: latex_documents:
- - Index - - Index
- qfq.tex - qfq.tex
......
...@@ -57,9 +57,9 @@ copyright = u'2017, Carsten Rose' ...@@ -57,9 +57,9 @@ copyright = u'2017, Carsten Rose'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '0.8' version = '0.12'
# The full version, including alpha/beta/rc tags. # 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 # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # 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 Version 0.11
============ ============
......
...@@ -10,5 +10,5 @@ $EM_CONF[$_EXTKEY] = array( ...@@ -10,5 +10,5 @@ $EM_CONF[$_EXTKEY] = array(
'dependencies' => 'fluid,extbase', 'dependencies' => 'fluid,extbase',
'clearcacheonload' => true, 'clearcacheonload' => true,
'state' => 'alpha', '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 { ...@@ -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_START] = "";
$this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_END] = ""; $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['radio'] = 'radio';
// $this->feDivClass['checkbox'] = 'checkbox'; // $this->feDivClass['checkbox'] = 'checkbox';
} }
...@@ -151,7 +154,7 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -151,7 +154,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
$toolTip .= PHP_EOL . "table = '" . $this->formSpec[F_TABLE_NAME] . "'" . PHP_EOL . "r = '" . $recordId . "'"; $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 // Button: Close
...@@ -209,13 +212,13 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -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. * Creates a button with the given attributes. If there is no $icon given, render the button without glyph.
* *
* @param $id * @param string $id
* @param $title * @param string $title
* @param $icon * @param string $icon
* @param string $disabled * @param string $disabled
* @return string * @return string
*/ */
private function buildButtonCode($id, $title, $icon, $disabled = '') { private function buildButtonCode($id, $title, $icon, $disabled = '', $buttonOnChangeClass = '') {
$element = "<span class='glyphicon $icon'></span>"; $element = "<span class='glyphicon $icon'></span>";
$classAdd = "navbar-btn"; $classAdd = "navbar-btn";
...@@ -225,7 +228,10 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -225,7 +228,10 @@ class BuildFormBootstrap extends AbstractBuildForm {
$classAdd = ''; $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 { ...@@ -325,7 +331,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
if ($this->formSpec[F_SUBMIT_BUTTON_TEXT] !== '') { if ($this->formSpec[F_SUBMIT_BUTTON_TEXT] !== '') {
$buttonText = $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_LABEL, '');
$html .= $this->wrapItem(WRAP_SETUP_INPUT, $htmlElement); $html .= $this->wrapItem(WRAP_SETUP_INPUT, $htmlElement);
...@@ -400,24 +406,66 @@ EOF; ...@@ -400,24 +406,66 @@ EOF;
} }
/** /**
* @param array $formElement * @param array $formElement Complete FormElement, especially some FE_WRAP
* @param string $htmlElement * @param string $htmlElement Content to wrap.
* @return string * @param $htmlFormElementId
* @return string Wrapped $htmlElement
* @throws \qfq\UserFormException
*/ */
public function buildRowNative(array $formElement, $htmlElement, $htmlFormElementId) { public function buildRowNative(array $formElement, $htmlElement, $htmlFormElementId) {
$html = ''; $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); $note = Support::wrapTag("<div class='qfq-note'>", $formElement[FE_NOTE], true);
$html .= $this->wrapItem(WRAP_SETUP_INPUT, $htmlElement); $html .= $this->customWrap($formElement, $note, FE_WRAP_NOTE, $formElement[FE_BS_NOTE_COLUMNS],
$html .= $this->wrapItem(WRAP_SETUP_NOTE, $formElement[FE_NOTE], true); [$this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END]]);