[TASK] Add prepended icon to SelectSingleElement 06/43306/7
authorMathias Brodala <mbrodala@pagemachine.de>
Mon, 14 Sep 2015 16:16:37 +0000 (18:16 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Tue, 15 Sep 2015 12:21:49 +0000 (14:21 +0200)
This brings back the select prepend icon and moves all event
handling for updating it to a RequireJS module.

Also moves all remaining event handling to the module including
FormEngine "fieldChangeFunc" and "onFocus".

Resolves: #69792
Releases: master
Change-Id: I9943412bb61639759aeba05746facdce60cfd12e
Reviewed-on: http://review.typo3.org/43306
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Michael Oehlhof <typo3@oehlhof.de>
Tested-by: Michael Oehlhof <typo3@oehlhof.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/backend/Classes/Form/Element/SelectSingleElement.php
typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectSingleElement.js [new file with mode: 0644]

index 138374a..d86b3c7 100644 (file)
@@ -106,9 +106,12 @@ class SelectSingleElement extends AbstractFormElement {
                $selectItemGroups = array();
                $selectIcons = array();
                $selectedValue = '';
+               $hasIcons = FALSE;
+
                if (!empty($parameterArray['itemFormElValue'])) {
                        $selectedValue = (string)$parameterArray['itemFormElValue'][0];
                }
+
                foreach ($selectItems as $item) {
                        if ($item[1] === '--div--') {
                                // IS OPTGROUP
@@ -117,18 +120,19 @@ class SelectSingleElement extends AbstractFormElement {
                                }
                                $selectItemGroups[$selectItemGroupCount]['header'] = array(
                                        'title' => $item[0],
-                                       'icon' => (!empty($item[2]) ? FormEngineUtility::getIconHtml($item[2]) : ''),
                                );
                        } else {
                                // IS ITEM
                                $title = htmlspecialchars($item['0'], ENT_COMPAT, 'UTF-8', FALSE);
                                $icon = !empty($item[2]) ? FormEngineUtility::getIconHtml($item[2], $title, $title) : '';
                                $selected = $selectedValue === (string)$item[1];
+
                                if ($selected) {
                                        $selectedIndex = $selectItemCounter;
                                        $selectedIcon = $icon;
                                        $selectedValueFound = TRUE;
                                }
+
                                $selectItemGroups[$selectItemGroupCount]['items'][] = array(
                                        'title' => $title,
                                        'value' => $item[1],
@@ -136,18 +140,16 @@ class SelectSingleElement extends AbstractFormElement {
                                        'selected' => $selected,
                                        'index' => $selectItemCounter
                                );
+
                                // ICON
                                if ($icon && !$suppressIcons && (!$onlySelectedIconShown || $selected)) {
-                                       $onClick = 'document.editform[' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . '].selectedIndex=' . $selectItemCounter . ';';
-                                       $onClick .= implode('', $parameterArray['fieldChangeFunc']);
-                                       $onClick .= 'this.blur();return false;';
                                        $selectIcons[] = array(
                                                'title' => $title,
                                                'icon' => $icon,
                                                'index' => $selectItemCounter,
-                                               'onClick' => $onClick
                                        );
                                }
+
                                $selectItemCounter++;
                        }
 
@@ -170,63 +172,88 @@ class SelectSingleElement extends AbstractFormElement {
 
                        $optionGroup = is_array($selectItemGroup['header']);
                        $options .= ($optionGroup ? '<optgroup label="' . htmlspecialchars($selectItemGroup['header']['title'], ENT_COMPAT, 'UTF-8', FALSE) . '">' : '');
+
                        if (is_array($selectItemGroup['items'])) {
                                foreach ($selectItemGroup['items'] as $item) {
                                        $options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
                                                htmlspecialchars($item['icon']) . '"'
                                                . ($item['selected'] ? ' selected="selected"' : '') . '>' . $item['title'] . '</option>';
                                }
+                               $hasIcons = !empty($item['icon']);
                        }
+
                        $options .= ($optionGroup ? '</optgroup>' : '');
                }
 
-               // Create item form fields:
-               $sOnChange = 'if (this.options[this.selectedIndex].value==\'--div--\') {this.selectedIndex=' . $selectedIndex . ';} ';
-               $sOnChange .= implode('', $parameterArray['fieldChangeFunc']);
-
                // Build the element
-               $html = '
-                       <div class="form-control-wrap">
-                               <select'
+               $html = ['<div class="form-control-wrap">'];
+
+               if ($hasIcons) {
+                       $html[] = '<div class="input-group">';
+                       $html[] =       '<span class="input-group-addon input-group-icon">';
+                       $html[] =               $selectedIcon;
+                       $html[] =       '</span>';
+               }
+
+               $html[] = '<select'
                                        . ' id="' . $selectId . '"'
                                        . ' name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"'
                                        . $this->getValidationDataAsDataAttribute($config)
                                        . ' class="form-control form-control-adapt"'
                                        . ($size ? ' size="' . $size . '"' : '')
-                                       . ' onchange="' . htmlspecialchars($sOnChange) . '"'
-                                       . $parameterArray['onFocus']
                                        . ($disabled ? ' disabled="disabled"' : '')
-                                       . '>
-                                       ' . $options . '
-                               </select>
-                       </div>';
+                                       . '>';
+               $html[] =       $options;
+               $html[] = '</select>';
+
+               if ($hasIcons) {
+                       $html[] = '</div>';
+               }
+
+               $html[] = '</div>';
 
                // Create icon table:
                if (!empty($selectIcons) && !$config['noIconsBelowSelect']) {
                        $selectIconColumns = (int)$config['selicon_cols'];
+
                        if (!$selectIconColumns) {
                                $selectIconColumns = count($selectIcons);
                        }
+
                        $selectIconColumns = ($selectIconColumns > 12 ? 12 : $selectIconColumns);
                        $selectIconRows = ceil(count($selectIcons) / $selectIconColumns);
                        $selectIcons = array_pad($selectIcons, $selectIconRows * $selectIconColumns, '');
-                       $html .= '<div class="table-fit table-fit-inline-block"><table class="table table-condensed table-white table-center"><tbody><tr>';
-                       $selectIconTotalCount = count($selectIcons);
-                       for ($selectIconCount = 0; $selectIconCount < $selectIconTotalCount; $selectIconCount++) {
-                               if ($selectIconCount % $selectIconColumns === 0 && $selectIconCount !== 0) {
-                                       $html .= '</tr><tr>';
+
+                       $html[] = '<div class="t3js-forms-select-single-icons table-fit table-fit-inline-block">';
+                       $html[] =       '<table class="table table-condensed table-white table-center">';
+                       $html[] =               '<tbody>';
+                       $html[] =                       '<tr>';
+
+                       foreach ($selectIcons as $i => $selectIcon) {
+                               if ($i % $selectIconColumns === 0 && $i !== 0) {
+                                       $html[] =       '</tr>';
+                                       $html[] =       '<tr>';
                                }
-                               $html .= '<td>';
-                               if (is_array($selectIcons[$selectIconCount])) {
-                                       $html .= (!$onlySelectedIconShown ? '<a href="#" title="' . $selectIcons[$selectIconCount]['title'] . '" onClick="' . htmlspecialchars($selectIcons[$selectIconCount]['onClick']) . '">' : '');
-                                       $html .= $selectIcons[$selectIconCount]['icon'];
-                                       $html .= (!$onlySelectedIconShown ? '</a>' : '');
+
+                               $html[] =                       '<td>';
+
+                               if (is_array($selectIcon)) {
+                                       $html[] = (!$onlySelectedIconShown ? '<a href="#" title="' . $selectIcon['title'] . '" data-select-index="' . $selectIcon['index'] . '">' : '');
+                                       $html[] = $selectIcon['icon'];
+                                       $html[] = (!$onlySelectedIconShown ? '</a>' : '');
                                }
-                               $html .= '</td>';
+
+                               $html[] =                       '</td>';
                        }
-                       $html .= '</tr></tbody></table></div>';
+
+                       $html[] =                       '</tr>';
+                       $html[] =               '</tbody>';
+                       $html[] =       '</table>';
+                       $html[] = '</div>';
                }
 
+               $html = implode(LF, $html);
+
                // Wizards:
                if (!$disabled) {
                        $html = $this->renderWizards(
@@ -243,6 +270,21 @@ class SelectSingleElement extends AbstractFormElement {
 
                $resultArray = $this->initializeResultArray();
                $resultArray['html'] = $html;
+               $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectSingleElement' => implode(LF, [
+                       'function(SelectSingleElement) {',
+                               'SelectSingleElement.initialize(',
+                                       GeneralUtility::quoteJSvalue('#' . $selectId) . ',',
+                                       '{',
+                                               'onChange: function() {',
+                                                       implode('', $parameterArray['fieldChangeFunc']),
+                                               '},',
+                                               'onFocus: function() {',
+                                                       $parameterArray['onFocus'],
+                                               '},',
+                                       '}',
+                               ');',
+                       '}',
+               ])];
 
                return $resultArray;
        }
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectSingleElement.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectSingleElement.js
new file mode 100644 (file)
index 0000000..fa42808
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Logic for SelectSingleElement
+ */
+define(['jquery'], function ($) {
+
+       var SelectSingleElement = {};
+
+       /**
+        * Initializes the SelectSingleEleemnt
+        */
+       SelectSingleElement.initialize = function(selector, options) {
+
+               var $selectElement = $(selector);
+               var $groupIconContainer = $selectElement.prev('.input-group-icon');
+               var options = options || {};
+
+               $selectElement.on('change', function() {
+                       // Update prepended select icon
+                       $groupIconContainer.html($selectElement.find(':selected').data('icon'));
+               });
+
+               // Append optionally passed additional "change" event callback
+               if (typeof options.onChange === 'function') {
+                       $selectElement.on('change', options.onChange);
+               }
+
+               // Append optionally passed additional "focus" event callback
+               if (typeof options.onFocus === 'function') {
+                       $selectElement.on('focus', options.onFocus);
+               }
+
+               $selectElement.closest('.form-control-wrap').next('.t3js-forms-select-single-icons').on('click', function(e) {
+                       var $selectIcon = $(e.target).closest('[data-select-index]');
+
+                       $selectElement
+                               .prop('selectedIndex', $selectIcon.data('selectIndex'))
+                               .trigger('change');
+                       $selectIcon.trigger('blur');
+
+                       return false;
+               });
+       };
+
+       return SelectSingleElement;
+});