Commit d02ad978 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Save templateGroup.

AdministratorManual/Index.rst: extend sphinx setup doc, fix typo
UserManual/Index.rst: add doc for templateGroup
FillStore.php: Implement save for templateGroup
parent 6205c4ec
......@@ -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
-----
......@@ -169,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
......@@ -196,7 +197,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).
......@@ -206,3 +207,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
......@@ -742,6 +742,33 @@ Type: pill
.. _class-native:
Type: templateGroup
^^^^^^^^^^^^^^^^^^^
*TemplateGroups* will be used to create a series of grouped (by the given *templateGroup*) *FormElements*.
FormElements can be assigned to a *templateGroup*. These *templateGroup* will be rendered upto *n*-times. On 'form load'
only a single (=first) copy of the *templateGroup* will be shown. Below the last copy of the *templateGroup* an 'add'-button is
shown. If the user click on it, an additional copy of the *templateGroup* is displayed. This can be repeated up to
*templateGroup.maxLength* times. Also, the user can 'remove' previously created copies by clicking on a remove button near
beside every *templateGroup*.
* Parameter
* FormElement.*label*: Shown in the FormElement-editor *container* field.
* FormElement.*maxLength*: Maximum number of copies of the current *templateGroup*. Default: 5.
* FormElement.parameter.*tgAddClass*: Class of the 'add' button. Default: `btn btn-default`.
* FormElement.parameter.*tgAddText*: Text shown on the button. Default: `Add`.
* FormElement.parameter.*tgRemoveClass*: Class of the 'remove' button. Default: `btn btn-default`.
* FormElement.parameter.*tgRemoveText*: Text shown on the button. Default: `Remove`.
* FormElement.parameter.*tgClass*: Class wrapped around every copy of the *templateGroup*. E.g. the class
`qfq-child-margin-top` adds a margin between two copies of the *templateGroup*. Default: empty
Multiple *templatedGroups* per form are allowed.
The name of the native FormElements, inside the templateGroup, which represents the effective table columns, uses the placeholder
`%d`. E.g. the columns `grade1`, `grade2`, `grade3` needs a *FormElement.name*=`grade%d`. The counting will always start with 1.
Class: Native
-------------
......
......@@ -48,7 +48,8 @@ const RETURN_ARRAY = 'return_array';
const SQL_FORM_ELEMENT_SPECIFIC_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted = 'no' AND FIND_IN_SET(fe.class, ? ) AND fe.feIdContainer = ? AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_ALL_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted = 'no' AND FIND_IN_SET(fe.class, ? ) AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER = "SELECT fe.id, fe.name, fe.label, fe.type, fe.checkType, fe.checkPattern, fe.mode, fe.modeSql, fe.parameter, fe.dynamicUpdate FROM FormElement AS fe, Form AS f WHERE f.name = ? AND f.id = fe.formId AND fe.deleted = 'no' AND fe.class = 'native' AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER = "SELECT fe.id, fe.feIdContainer, fe.name, fe.label, fe.type, fe.checkType, fe.checkPattern, fe.mode, fe.modeSql, fe.parameter, fe.dynamicUpdate FROM FormElement AS fe, Form AS f WHERE f.name = ? AND f.id = fe.formId AND fe.deleted = 'no' AND fe.class = 'native' AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_CONTAINER_TEMPLATE_GROUP = "SELECT fe.id, fe.name, fe.label, fe.maxLength, fe.parameter FROM FormElement AS fe, Form AS f WHERE f.name = ? AND f.id = fe.formId AND fe.deleted = 'no' AND fe.class = 'container' AND fe.type='templateGroup' AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
// SANITIZE Classifier
const SANITIZE_ALLOW_ALNUMX = "alnumx";
......@@ -498,6 +499,7 @@ const FE_SUBRECORD_ROW_TITLE = '_rowTitle';
// FormElement columns: real
const FE_ID = 'id';
const FE_ID_CONTAINER = 'feIdContainer';
const FE_NAME = 'name';
const FE_TYPE = 'type';
const FE_MODE = 'mode';
......@@ -559,6 +561,7 @@ const FE_TEMPLATE_GROUP_ADD_TEXT = 'tgAddText';
const FE_TEMPLATE_GROUP_REMOVE_CLASS = 'tgRemoveClass';
const FE_TEMPLATE_GROUP_REMOVE_TEXT = 'tgRemoveText';
const FE_TEMPLATE_GROUP_CLASS = 'tgClass';
const FE_TEMPLATE_GROUP_DEFAULT_MAX_LENGTH = 5;
const RETYPE_FE_NAME_EXTENSION = 'RETYPE';
......
......@@ -48,9 +48,56 @@ class FillStoreForm {
}
/**
* Checks if there are templateGroups defined. If yes, expand them. Return expanded feSpecNative array.
*
* @param array $feSpecTemplateGroup
* @param array $feSpecNative
* @return array
*/
private function expandTemplateGroupFormElement(array $feSpecTemplateGroup, array $feSpecNative) {
$expanded = array();
if(count($feSpecTemplateGroup)==0) {
return $feSpecNative; // No templateGroups >> nothing to do >> just return
}
// Iterate over all 'FormElements': part of a templateGroup?
foreach($feSpecNative as $fe) {
$flagCopied=false;
if($fe[FE_ID_CONTAINER]>0) {
// Search for a corresponding template group.
foreach ($feSpecTemplateGroup as $templateGroup) {
if ($fe[FE_ID_CONTAINER] = $templateGroup[FE_ID]) {
$flagCopied=true;
// Get max copies per template group
$maxCopies = ($templateGroup[FE_MAX_LENGTH] == 0 || $templateGroup[FE_MAX_LENGTH] == '') ? FE_TEMPLATE_GROUP_DEFAULT_MAX_LENGTH : $templateGroup[FE_MAX_LENGTH];
// Copy each native FormElement
$template = $fe[FE_NAME];
for ($ii = 1; $ii <= $maxCopies; $ii++) {
$fe[FE_NAME] = str_replace('%d', $ii, $template);
$expanded[] = $fe;
}
}
}
}
if(!$flagCopied) {
$expanded[] = $fe;
}
}
return $expanded;
}
/**
* Loads a minimal definition of FormElement of the form specified in SIP.
*
* @return array
* @throws CodeException
* @throws DbException
* @throws UserFormException
......@@ -61,13 +108,15 @@ class FillStoreForm {
// Preparation for Log, Debug
$this->store->setVar(SYSTEM_FORM, $formName, STORE_SYSTEM);
$feSpecNative = $this->db->sql(SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER, ROW_REGULAR, [$formName]);
$feSpecNative = $this->db->sql(SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER, ROW_EXPECT_GE_1, [$formName],
'Form or FormElements not found: ' . ERROR_FORM_NOT_FOUND);
HelperFormElement::explodeParameterInArrayElements($feSpecNative);
$feSpecTemplateGroup = $this->db->sql(SQL_FORM_ELEMENT_CONTAINER_TEMPLATE_GROUP, ROW_REGULAR, [$formName]);
HelperFormElement::explodeParameterInArrayElements($feSpecTemplateGroup);
if (count($feSpecNative) === 0) {
throw new UserFormException('Form not found or multiple forms with the same name.', ERROR_FORM_NOT_FOUND);
}
$feSpecNative = $this->expandTemplateGroupFormElement($feSpecTemplateGroup, $feSpecNative);
HelperFormElement::explodeParameterInArrayElements($feSpecNative);
return $feSpecNative;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment