diff --git a/Documentation-develop/DRAGANDDROP.md b/Documentation-develop/DRAGANDDROP.md index 14d9b9cd5216ac4d23fdc6d8b618fc8810067b7b..700705263d0ed40ebb2373a4e0ec6607dbb24bd5 100644 --- a/Documentation-develop/DRAGANDDROP.md +++ b/Documentation-develop/DRAGANDDROP.md @@ -18,5 +18,10 @@ Request will be sent containing following GET variables: * hoverId = `data-dnd-id` id of the element the dragged element is now hovering, meaning before or after. * hoverPosition = client internal position of currently hovered element. +Example: http://something/bla?dragId=uno&dragPosition=1&setTo=before&hoverId=tre&hoverPosition=3 -Example: http://something/bla?dragId=uno&dragPosition=1&setTo=before&hoverId=tre&hoverPosition=3 \ No newline at end of file +## Drag'n'drop in forms + +* For FormElement.typ=subrecord DND is automatically detected. +* The encoded SIP contains: dnd-subrecord-form-id, dnd-subrecord-form-table, dnd-subrecord-id, dndTable, oderColumn, + oderInterval, dnd-db-index. diff --git a/Documentation/CodingGuideline.rst b/Documentation/CodingGuideline.rst index d5366849dd39f027af0c57412d34c04dc3af46ca..e02e24e6a06ce01ff58c5ee6d200341f292f1fd7 100644 --- a/Documentation/CodingGuideline.rst +++ b/Documentation/CodingGuideline.rst @@ -81,7 +81,7 @@ QFQ content record QFQ Form -------- -* Mandatory SIP parameter have to be mentioned in Form.requiredNew and/or Form.requiredEdit. +* Mandatory SIP parameter should to be mentioned in Form.requiredNew and/or Form.requiredEdit. * If the title of a FormElement isn't descriptive enough, use tooltip, note or extraButtonInfo to explain to a user. * Every Form should show a descriptive title to identify the task and current record. E.g. Not 'Person' but 'Person: John Doe'. * Often the length of a pill title if not sufficient, use a tooltip to give a more descriptive hint. diff --git a/Documentation/Form.rst b/Documentation/Form.rst index ffc5e36045fa5a617469741630357c0f1b64157a..bafedaf38950db83d39d9c7f090f22a834ceff7b 100644 --- a/Documentation/Form.rst +++ b/Documentation/Form.rst @@ -1107,7 +1107,7 @@ FormElement.parameter | minWidth | See :ref:`checkboxRadioMinWidth`. | +---------------------------------+----------------------------------------------------------------------------------------------------------+ | clearMe | 0 (off)|1(on) - Overwrite default from Form.parameter.clearMe or :ref:`configuration`. Show a small | -| | 'x' in every input or textarea to clear field. | +| | 'x' in input or textarea fields to clear the input. | +---------------------------------+----------------------------------------------------------------------------------------------------------+ @@ -1901,19 +1901,26 @@ include a column `id` (or `_id`) and a column `ord` (or `_ord`). E.g.:: FE.sql1 = {{!SELECT p.id AS _id, p.ord AS _ord, p.name FROM Person WHERE p.email!='' ORDER BY p.ord}} -Tips: +In case the modified ord value should be shown without reloading the page, add html id `qfq-dnd-ord-id-...`:: -* If you want to deactivate a drag-and-drop that QFQ automatically renders, set the `orderColumn` to a non-existing column. - E.g., `orderColumn = nonExistingColumn`. This will deactivate drag-and-drop. -* In order to evaluate the `sql1` query dynamically during a drag-and-drop event, the STORE_RECORD (with the current subrecord) - is loaded. -* The stores STORE_RECORD, STORE_SIP and STORE_SYSTEM are supported during a drag-and-drop event and can be used in FE.sql1 query. + FE.sql1 = {{!SELECT p.id AS _id, p.ord AS _ord, p.name + , CONCAT('', p.ord, '') AS 'Ord|nostrip' + FROM Person WHERE p.email!='' ORDER BY p.ord}} - * STORE_SIP: SIP values on form load - * STORE_RECORD: values of the current record loaded in the form. -* If the subrecord is rendered with drag-and-drop active, but the order is not affected upon reload, there is - most likely a problem with evaluating the `sql1` query at runtime. +.. tip:: + + * If you want to deactivate a drag-and-drop that QFQ automatically renders, set the `orderColumn` to a non-existing column. + E.g., `orderColumn = nonExistingColumn`. This will deactivate drag-and-drop. + * In order to evaluate the `sql1` query dynamically during a drag-and-drop event, the STORE_RECORD (with the current subrecord) + is loaded. + * The stores STORE_RECORD, STORE_SIP and STORE_SYSTEM are supported during a drag-and-drop event and can be used in FE.sql1 query. + + * STORE_SIP: SIP values on form load + * STORE_RECORD: values of the current record loaded in the form. + + * If the subrecord is rendered with drag-and-drop active, but the order is not affected upon reload, there is + most likely a problem with evaluating the `sql1` query at runtime. Type: time ^^^^^^^^^^ diff --git a/extension/Classes/Core/AbstractBuildForm.php b/extension/Classes/Core/AbstractBuildForm.php index 87b9ed165c54369b9720931a48a5b241172a7e82..6640ba07a788a68b0637f9f44513937409e6f3db 100644 --- a/extension/Classes/Core/AbstractBuildForm.php +++ b/extension/Classes/Core/AbstractBuildForm.php @@ -2261,6 +2261,7 @@ abstract class AbstractBuildForm { $dataDndApi .= '&' . FE_ORDER_INTERVAL . '=' . $orderInterval; $dataDndApi .= '&' . FE_ORDER_COLUMN . '=' . $orderColumn; $dataDndApi .= '&' . FE_DND_TABLE . '=' . $dndTable; + $dataDndApi .= '&' . DND_DB_INDEX . '=' . $this->formSpec[F_DB_INDEX]; $dndAttributes = Support::doAttribute('class', 'qfq-dnd-sort'); $dndAttributes .= $this->evaluate->parse("{{ '$dataDndApi' AS _data-dnd-api }}") . ' '; diff --git a/extension/Classes/Core/Constants.php b/extension/Classes/Core/Constants.php index beac7116accea20f5ed39ae141560cf1f64ca268..76e8ec1e08c54e339f56efd5dcf188a4b9a9dbe4 100644 --- a/extension/Classes/Core/Constants.php +++ b/extension/Classes/Core/Constants.php @@ -1986,6 +1986,7 @@ const DND_SUBRECORD_FORM_ID = 'dnd-subrecord-form-id'; const DND_SUBRECORD_FORM_TABLE = 'dnd-subrecord-form-table'; const DND_ORD_HTML_ID_PREFIX = 'qfq-dnd-ord-id-'; const DND_FORM_SIP_VALUES = '_sipForm'; +const DND_DB_INDEX = 'dnd-db-index'; // Application Test: SELENIUM const ATTRIBUTE_DATA_REFERENCE = 'data-reference'; diff --git a/extension/Classes/Core/Database/DatabaseUpdate.php b/extension/Classes/Core/Database/DatabaseUpdate.php index f243bdf979cdd8fb26b57e2c3533d99e0cf2dec5..bce76e104cd43e4ffc295ce9740bac1bb6cac29d 100644 --- a/extension/Classes/Core/Database/DatabaseUpdate.php +++ b/extension/Classes/Core/Database/DatabaseUpdate.php @@ -156,8 +156,6 @@ class DatabaseUpdate { $versionInfo[QFQ_VERSION_KEY_FUNCTION_VERSION] = $new; } - $this->dbUpdateStatements($old, $new); - if (FEATURE_FORM_FILE_SYNC) { if ($this->db->existTable('Form')) { // If Form table exists, import all form files so everything is up to date. @@ -165,11 +163,11 @@ class DatabaseUpdate { // create Form table and export all system forms $this->db->playSqlFile(__DIR__ . '/../../Sql/formEditor.sql'); - FormAsFIle::exportAllForms($this->db); + FormAsFile::exportAllForms($this->db); } else { // If not, then create Form table and export all system forms $this->db->playSqlFile(__DIR__ . '/../../Sql/formEditor.sql'); - FormAsFIle::exportAllForms($this->db); + FormAsFile::exportAllForms($this->db); // import form files which existed before the new installation FormAsFile::importAllForms($this->db, true); @@ -178,6 +176,10 @@ class DatabaseUpdate { $this->db->playSqlFile(__DIR__ . '/../../Sql/formEditor.sql'); } + // Perform dbUpdate only after formEditor.sql has been played: + // in case a new system table has been added between old and new and there is an dbUpdate on the new system table now. + $this->dbUpdateStatements($old, $new); + FormAsFile::importSystemForms($this->db); Logger::logMessage(date('Y.m.d H:i:s ') . ": Updated from QFQ version '$old' to '$new'", Path::absoluteQfqLogFile()); @@ -195,7 +197,7 @@ class DatabaseUpdate { if (version_compare($old, '19.9.0') === -1) { $this->updateSpecialColumns(); if (FEATURE_FORM_FILE_SYNC) { - FormAsFIle::exportAllForms($this->db); + FormAsFile::exportAllForms($this->db); } } diff --git a/extension/Classes/Core/Form/DragAndDrop.php b/extension/Classes/Core/Form/DragAndDrop.php index cc659cedd530a9980fc50736e3ed335faecb4d7a..c8ff19a74178e288800c69057f607e3061f55fdf 100644 --- a/extension/Classes/Core/Form/DragAndDrop.php +++ b/extension/Classes/Core/Form/DragAndDrop.php @@ -8,10 +8,9 @@ namespace IMATHUZH\Qfq\Core\Form; -use IMATHUZH\Qfq\Core\Store\Store; use IMATHUZH\Qfq\Core\Database\Database; use IMATHUZH\Qfq\Core\Evaluate; - +use IMATHUZH\Qfq\Core\Store\Store; /** @@ -54,7 +53,7 @@ class DragAndDrop { #TODO: rewrite $phpUnit to: "if (!defined('PHPUNIT_QFQ')) {...}" $this->formSpec = $formSpec; - $dbIndex = DB_INDEX_DEFAULT; //Hier muss noch die aktuelle DB ermittelt werden (kann im Form angegeben sein) - Gerade im Formular FORM Editor genau testen! + $dbIndex = $formSpec[F_DB_INDEX]; //Hier muss noch die aktuelle DB ermittelt werden (kann im Form angegeben sein) - Gerade im Formular FORM Editor genau testen! $this->db = new Database($dbIndex); $this->store = Store::getInstance('', $phpUnit); diff --git a/extension/Classes/Core/QuickFormQuery.php b/extension/Classes/Core/QuickFormQuery.php index 087ea4839316a81a7505473e2bdcb46af4ceae4f..c8662e678b39a658f6e9681e54e9f54931dd5f46 100644 --- a/extension/Classes/Core/QuickFormQuery.php +++ b/extension/Classes/Core/QuickFormQuery.php @@ -195,7 +195,7 @@ class QuickFormQuery { // Set dbIndex, evaluate any $dbIndex = $this->store->getVar(TOKEN_DB_INDEX, STORE_TYPO3 . STORE_EMPTY); $dbIndex = $this->evaluate->parse($dbIndex); - $dbIndex = ($dbIndex == '') ? DB_INDEX_DEFAULT : $dbIndex; + $dbIndex = ($dbIndex == '') ? $this->dbIndexData : $dbIndex; $this->store->setVar(TOKEN_DB_INDEX, $dbIndex, STORE_TYPO3); // Create report file if file keyword not found (and auto export is enabled in qfq settings) @@ -1889,21 +1889,36 @@ class QuickFormQuery { $dndSubrecordId = $this->store::getVar(DND_SUBRECORD_ID, STORE_SIP . STORE_CLIENT . STORE_ZERO); if ($dndSubrecordId > 0) { - // Subrecord DragAndDrop - $subrecord = $this->dbArray[$this->dbIndexQfq]->sql(SQL_FORM_ELEMENT_BY_ID, ROW_REGULAR, [$dndSubrecordId]); + + // Save dbIndex + $dbIndex = $this->store::getVar(DND_DB_INDEX, STORE_SIP . STORE_ZERO); + + // Get FormElement of current 'Subrecord' DragAndDrop + $feSubrecord = $this->dbArray[$this->dbIndexQfq]->sql(SQL_FORM_ELEMENT_BY_ID, ROW_REGULAR, [$dndSubrecordId]); $recordId = $this->store::getVar(DND_SUBRECORD_FORM_ID, STORE_SIP . STORE_ZERO); $tableName = $this->store::getVar(DND_SUBRECORD_FORM_TABLE, STORE_SIP); -// $this->store->fillStoreWithRecord('form', $recordId, $this->dbArray[$this->dbIndexQfq]); - $this->store->fillStoreWithRecord($tableName, $recordId, $this->dbArray[$this->dbIndexQfq]); +// $this->store->fillStoreWithRecord($tableName, $recordId, $this->dbArray[$this->dbIndexQfq]); + $this->store->fillStoreWithRecord($tableName, $recordId, $this->dbArray[$dbIndex]); $formSip = $this->store::getVar(DND_FORM_SIP_VALUES, STORE_SIP); // Backup STORE_SIP $save = $this->store::getStore(STORE_SIP); // Fake STORE_SIP $this->store::fillStoreSip($formSip); + // Fire query, which might use SIP Vars - $dndOrderSql = $this->evaluate->parse($subrecord[0][FE_SQL1]); + $sql = $feSubrecord[0][FE_SQL1]; + $sqlSelect = str_replace(' ', '', substr($sql, 0, 9)); + $sqlRest = substr($sql, 9); + + // In case there is already a dbIndex given: change nothing '{{[123]!SELECT'. Else set the one defined by the SIP + if ($sqlSelect[2] != '[') { + $sqlSelect = str_replace('{{', '{{[' . $dbIndex . ']', $sqlSelect); + $sql = $sqlSelect . $sqlRest; + } + + $dndOrderSql = $this->evaluate->parse($sql); // Restore STORE_SIP $this->store::setStore($save, STORE_SIP, true); @@ -1921,6 +1936,7 @@ class QuickFormQuery { F_ORDER_INTERVAL => $this->store->getVar(FE_ORDER_INTERVAL, STORE_SIP . STORE_ZERO), F_ORDER_COLUMN => $this->store->getVar(FE_ORDER_COLUMN, STORE_SIP . STORE_ZERO), F_DRAG_AND_DROP_ORDER_SQL => $dndOrderSql, + F_DB_INDEX => $dbIndex, F_TABLE_NAME => $this->store->getVar(FE_DND_TABLE, STORE_SIP . STORE_ZERO) ]; diff --git a/extension/Classes/Sql/formEditor.sql b/extension/Classes/Sql/formEditor.sql index 20c0c12bfb292edb2611564446a6d22ca295881a..54269642aa3acf30f24a23e4427f1ee7ca2eb435 100644 --- a/extension/Classes/Sql/formEditor.sql +++ b/extension/Classes/Sql/formEditor.sql @@ -264,6 +264,7 @@ CREATE TABLE IF NOT EXISTS `Split` AUTO_INCREMENT = 0 DEFAULT CHARSET = utf8; +# Used to save tablesorter.js column selection settings. Free to use for other settings as well. CREATE TABLE IF NOT EXISTS `Setting` ( `id` INT(11) NOT NULL AUTO_INCREMENT,