From b08a6db22b037820d338fa4c44a9ef39fec6537d Mon Sep 17 00:00:00 2001
From: Carsten  Rose <carsten.rose@math.uzh.ch>
Date: Mon, 9 May 2016 17:58:32 +0200
Subject: [PATCH] CheckBox Multi: checkboxes are now builded with uniq html
 names. This is necessary for the client, to assign values correctly to
 multiple checkboxes during form update by JSON data. HelperFormElement.php:
 new prependFormElementIdCheckBoxMulti() FillStoreForm.php: new
 collectCheckboxMultiValue(), process() recoded to collect checkBoxMulti
 values to one element. AbstractBuildForm.php: checkBoxMulti elements: a) no
 longer contains an '[]' at the end, b) get individual names

---
 extension/qfq/qfq/AbstractBuildForm.php       | 10 +++---
 .../qfq/qfq/helper/HelperFormElement.php      | 13 ++++++--
 extension/qfq/qfq/store/FillStoreForm.php     | 32 ++++++++++++++++++-
 3 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/extension/qfq/qfq/AbstractBuildForm.php b/extension/qfq/qfq/AbstractBuildForm.php
index 8925bf2b0..22874b294 100644
--- a/extension/qfq/qfq/AbstractBuildForm.php
+++ b/extension/qfq/qfq/AbstractBuildForm.php
@@ -840,7 +840,7 @@ abstract class AbstractBuildForm {
         }
 
         if ($formElement['checkBoxMode'] === 'multi') {
-            $htmlFormElementId .= '[]';
+//            $htmlFormElementId .= '[]';
         } else {
             // Fill meaningfull defaults to parameter: checked|unchecked  (CHECKBOX_VALUE_CHECKED|CHECKBOX_VALUE_UNCHECKED)
             $this->prepareCheckboxCheckedUncheckedValue($itemKey, $formElement);
@@ -1080,10 +1080,10 @@ abstract class AbstractBuildForm {
         // Defines which of the checkboxes will be checked.
         $values = explode(',', $value);
 
-        $attributeBase .= Support::doAttribute('name', $htmlFormElementId);
+//        $attributeBase .= Support::doAttribute('name', $htmlFormElementId);
         $attributeBase .= Support::doAttribute('data-load', ($formElement['dynamicUpdate'] === 'yes') ? 'data-load' : '');
 
-        $html = $this->buildNativeHidden($htmlFormElementId, '');
+        $html = $this->buildNativeHidden(HelperFormElement::prependFormElementIdCheckBoxMulti($htmlFormElementId, 'h'), '');
 
         $orientation = ($formElement['maxLength'] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
         $checkboxClass = ($orientation === ALIGN_HORIZONTAL) ? 'checkbox-inline' : 'checkbox';
@@ -1093,6 +1093,7 @@ abstract class AbstractBuildForm {
         for ($ii = 0, $jj = 1; $ii < count($itemKey); $ii++, $jj++) {
             $jsonValue = false;
             $attribute = $attributeBase;
+            $attribute .= Support::doAttribute('name', HelperFormElement::prependFormElementIdCheckBoxMulti($htmlFormElementId, $ii));
 
             // Do this only the first round.
             if ($flagFirst) {
@@ -1114,8 +1115,6 @@ abstract class AbstractBuildForm {
 
             $htmlElement = '<input ' . $attribute . '>' . $value;
 
-//            $htmlElement = Support::wrapTag("<label class='$orientation'>", $htmlElement, true);
-//            $htmlElement = Support::wrapTag("<label>", $htmlElement, true);
             // With ALIGN_HORIZONTAL: the label causes some trouble: skip it
             if (($orientation === ALIGN_VERTICAL)) {
                 $htmlElement = Support::wrapTag('<label>', $htmlElement);
@@ -1123,6 +1122,7 @@ abstract class AbstractBuildForm {
 
             $htmlElement = Support::wrapTag("<div class='$checkboxClass'>", $htmlElement, true);
 
+            // control orientation
             if ($formElement['maxLength'] > 1) {
 
                 if ($jj == $formElement['maxLength']) {
diff --git a/extension/qfq/qfq/helper/HelperFormElement.php b/extension/qfq/qfq/helper/HelperFormElement.php
index 958c4fcfa..da5cb214d 100644
--- a/extension/qfq/qfq/helper/HelperFormElement.php
+++ b/extension/qfq/qfq/helper/HelperFormElement.php
@@ -61,8 +61,8 @@ class HelperFormElement
     }
 
     /**
-     * @param $field
-     * @param $id
+     * @param string $field
+     * @param string $id
      * @return string
      */
     public static function buildFormElementId($field, $id)
@@ -70,4 +70,13 @@ class HelperFormElement
         return ($field . ':' . $id);
     }
 
+    /**
+     * @param string $field
+     * @param string $index
+     * @return string
+     */
+    public static function prependFormElementIdCheckBoxMulti($field, $index) {
+        return ('_' . $index . '_' . $field);
+    }
+
 }
\ No newline at end of file
diff --git a/extension/qfq/qfq/store/FillStoreForm.php b/extension/qfq/qfq/store/FillStoreForm.php
index 48b664438..6c6514827 100644
--- a/extension/qfq/qfq/store/FillStoreForm.php
+++ b/extension/qfq/qfq/store/FillStoreForm.php
@@ -130,6 +130,11 @@ class FillStoreForm {
                 continue;
             }
 
+            // Checkbox Multi: collect values
+            if ($formElement[FE_TYPE] == 'checkbox') {
+                $clientValues[$clientFieldName] = $this->collectCheckboxMultiValue($clientFieldName, $clientValues);
+            }
+
             if ($formElement[FE_MODE] === FE_MODE_REQUIRED) {
                 if (!isset($clientValues[$clientFieldName]) || ($clientValues[$clientFieldName] === '')) {
                     throw new UserFormException("Missing required value.", ERROR_REQUIRED_VALUE_EMPTY);
@@ -141,7 +146,7 @@ class FillStoreForm {
                 case FE_MODE_SHOW:
                     if (isset($clientValues[$clientFieldName])) {
 
-                        // SELECT MULTI or CHECKBOX MULTI: delivered as array - implode them.
+                        // CHECKBOX MULTI (SELECT MULTI ?): delivered as array - implode them.
                         if (is_array($clientValues[$clientFieldName])) {
                             // E.g. Checkboxes needs a 'HIDDEN' HTML input to detect 'unset' of values. These 'HIDDEN' element
                             //  needs to be removed, if there is at least one checkbox is checked (=submitted)
@@ -177,6 +182,31 @@ class FillStoreForm {
         $this->store->setVarArray($newValues, STORE_FORM, true);
     }
 
+    /**
+     * @param $clientFieldName
+     * @param array $clientValues
+     * @return mixed
+     */
+    private function collectCheckboxMultiValue($clientFieldName, array $clientValues) {
+        $checkboxValue = array();
+
+        $checkboxKey = HelperFormElement::prependFormElementIdCheckBoxMulti($clientFieldName, 'h');
+        // Check there is a hidden value with naming in checkbox multi syntax
+        if (isset($clientValues[$checkboxKey])) {
+            $checkboxValue[] = $clientValues[$checkboxKey];
+            $pattern = '/' . HelperFormElement::prependFormElementIdCheckBoxMulti($clientFieldName, '\d+') . '/';
+            foreach ($clientValues as $key => $value) {
+                if (1 === preg_match($pattern, $key)) {
+                    $checkboxValue[] = $value;
+                }
+            }
+
+            $clientValues[$clientFieldName] = $checkboxValue;
+        }
+
+        return $clientValues[$clientFieldName];
+    }
+
     /**
      * Check  $value as date/datime/time value and convert it to FORMAT_DATE_INTERNATIONAL.
      *
-- 
GitLab