c2369990b6b27ec0c218db097fda20018d1ac696
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / SelectMultipleSideBySideElement.php
1 <?php
2 namespace TYPO3\CMS\Backend\Form\Element;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
19 use TYPO3\CMS\Core\Utility\MathUtility;
20 use TYPO3\CMS\Core\Utility\StringUtility;
21
22 /**
23 * Render a widget with two boxes side by side.
24 *
25 * This is rendered for config type=select, maxitems > 1, renderType=selectMultipleSideBySide set
26 */
27 class SelectMultipleSideBySideElement extends AbstractFormElement
28 {
29 /**
30 * Render side by side element.
31 *
32 * @return array As defined in initializeResultArray() of AbstractNode
33 */
34 public function render()
35 {
36 $table = $this->data['tableName'];
37 $field = $this->data['fieldName'];
38 $parameterArray = $this->data['parameterArray'];
39 // Field configuration from TCA:
40 $config = $parameterArray['fieldConf']['config'];
41
42 $selItems = $config['items'];
43 $html = '';
44 $disabled = '';
45 if ($config['readOnly']) {
46 $disabled = ' disabled="disabled"';
47 }
48 // Setting this hidden field (as a flag that JavaScript can read out)
49 if (!$disabled) {
50 $html .= '<input type="hidden" data-formengine-input-name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="' . ($config['multiple'] ? 1 : 0) . '" />';
51 }
52 // Set max and min items:
53 $maxitems = MathUtility::forceIntegerInRange($config['maxitems'], 0);
54 if (!$maxitems) {
55 $maxitems = 100000;
56 }
57 // Get the array with selected items:
58 $itemsArray = $parameterArray['itemFormElValue'] ?: [];
59
60 // Perform modification of the selected items array:
61 foreach ($itemsArray as $itemNumber => $itemValue) {
62 $itemArray = [
63 0 => $itemValue,
64 1 => '',
65 ];
66
67 if (isset($parameterArray['fieldTSConfig']['altIcons.'][$itemValue])) {
68 $itemArray[2] = $parameterArray['fieldTSConfig']['altIcons.'][$itemValue];
69 }
70
71 foreach ($selItems as $selItem) {
72 if ($selItem[1] == $itemValue) {
73 $itemArray[1] = $selItem[0];
74 break;
75 }
76 }
77 $itemsArray[$itemNumber] = implode('|', $itemArray);
78 }
79
80 // size must be at least two, as there are always maxitems > 1 (see parent function)
81 if (isset($config['size'])) {
82 $size = (int)$config['size'];
83 } else {
84 $size = 2;
85 }
86 $size = $config['autoSizeMax'] ? MathUtility::forceIntegerInRange(count($itemsArray) + 1, MathUtility::forceIntegerInRange($size, 1), $config['autoSizeMax']) : $size;
87 $allowMultiple = !empty($config['multiple']);
88
89 $itemsToSelect = [];
90 $filterTextfield = [];
91 $filterSelectbox = '';
92 if (!$disabled) {
93 // Create option tags:
94 $opt = [];
95 foreach ($selItems as $p) {
96 $disabledAttr = '';
97 $classAttr = '';
98 if (!$allowMultiple && in_array((string)$p[1], $parameterArray['itemFormElValue'], true)) {
99 $disabledAttr = ' disabled="disabled"';
100 $classAttr = ' class="hidden"';
101 }
102 $opt[] = '<option value="' . htmlspecialchars($p[1]) . '" title="' . htmlspecialchars($p[0]) . '"' . $classAttr . $disabledAttr . '>' . htmlspecialchars($p[0]) . '</option>';
103 }
104 // Put together the selector box:
105 $selector_itemListStyle = isset($config['itemListStyle'])
106 ? ' style="' . htmlspecialchars($config['itemListStyle']) . '"'
107 : '';
108 $sOnChange = implode('', $parameterArray['fieldChangeFunc']);
109
110 $multiSelectId = StringUtility::getUniqueId('tceforms-multiselect-');
111 $itemsToSelect[] = '<select data-relatedfieldname="' . htmlspecialchars($parameterArray['itemFormElName']) . '" '
112 . 'data-exclusivevalues="' . htmlspecialchars($config['exclusiveKeys']) . '" '
113 . 'id="' . $multiSelectId . '" '
114 . 'data-formengine-input-name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" '
115 . 'class="form-control t3js-formengine-select-itemstoselect" '
116 . ($size > 1 ? ' size="' . $size . '" ' : '')
117 . 'onchange="' . htmlspecialchars($sOnChange) . '" '
118 . $this->getValidationDataAsDataAttribute($config)
119 . $selector_itemListStyle
120 . '>';
121 $itemsToSelect[] = implode(LF, $opt);
122 $itemsToSelect[] = '</select>';
123
124 // enable filter functionality via a text field
125 if ($config['enableMultiSelectFilterTextfield']) {
126 $filterTextfield[] = '<span class="input-group input-group-sm">';
127 $filterTextfield[] = '<span class="input-group-addon">';
128 $filterTextfield[] = '<span class="fa fa-filter"></span>';
129 $filterTextfield[] = '</span>';
130 $filterTextfield[] = '<input class="t3js-formengine-multiselect-filter-textfield form-control" value="">';
131 $filterTextfield[] = '</span>';
132 }
133
134 // enable filter functionality via a select
135 if (isset($config['multiSelectFilterItems']) && is_array($config['multiSelectFilterItems']) && count($config['multiSelectFilterItems']) > 1) {
136 $filterDropDownOptions = [];
137 foreach ($config['multiSelectFilterItems'] as $optionElement) {
138 $optionValue = $this->getLanguageService()->sL(isset($optionElement[1]) && trim($optionElement[1]) !== '' ? trim($optionElement[1])
139 : trim($optionElement[0]));
140 $filterDropDownOptions[] = '<option value="' . htmlspecialchars($this->getLanguageService()->sL(trim($optionElement[0]))) . '">'
141 . htmlspecialchars($optionValue) . '</option>';
142 }
143 $filterSelectbox = '<select class="form-control input-sm t3js-formengine-multiselect-filter-dropdown">'
144 . implode(LF, $filterDropDownOptions) . '</select>';
145 }
146 }
147
148 if (!empty(trim($filterSelectbox)) && !empty($filterTextfield)) {
149 $filterSelectbox = '<div class="form-multigroup-item form-multigroup-element">' . $filterSelectbox . '</div>';
150 $filterTextfield = '<div class="form-multigroup-item form-multigroup-element">' . implode(LF, $filterTextfield) . '</div>';
151 $selectBoxFilterContents = '<div class="t3js-formengine-multiselect-filter-container form-multigroup-wrap">' . $filterSelectbox . $filterTextfield . '</div>';
152 } else {
153 $selectBoxFilterContents = trim($filterSelectbox . ' ' . implode(LF, $filterTextfield));
154 }
155
156 // Pass to "dbFileIcons" function:
157 $params = [
158 'size' => $size,
159 'autoSizeMax' => MathUtility::forceIntegerInRange($config['autoSizeMax'], 0),
160 'style' => isset($config['selectedListStyle'])
161 ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"'
162 : '',
163 'dontShowMoveIcons' => $maxitems <= 1,
164 'maxitems' => $maxitems,
165 'info' => '',
166 'headers' => [
167 'selector' => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.selected'),
168 'items' => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.items'),
169 'selectorbox' => $selectBoxFilterContents,
170 ],
171 'noBrowser' => 1,
172 'rightbox' => implode(LF, $itemsToSelect),
173 'readOnly' => $disabled
174 ];
175 $html .= $this->dbFileIcons($parameterArray['itemFormElName'], '', '', $itemsArray, '', $params);
176
177 // Wizards:
178 if (!$disabled) {
179 $html = $this->renderWizards(
180 [$html],
181 $config['wizards'],
182 $table,
183 $this->data['databaseRow'],
184 $field,
185 $parameterArray,
186 $parameterArray['itemFormElName'],
187 BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras'])
188 );
189 }
190
191 $resultArray = $this->initializeResultArray();
192 $resultArray['html'] = $html;
193 return $resultArray;
194 }
195
196 /**
197 * @return BackendUserAuthentication
198 */
199 protected function getBackendUserAuthentication()
200 {
201 return $GLOBALS['BE_USER'];
202 }
203 }