TYPO3 CMS  TYPO3_7-6
SelectSingleElement.php
Go to the documentation of this file.
1 <?php
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 
22 
30 {
36  public function render()
37  {
38  $table = $this->data['tableName'];
39  $field = $this->data['fieldName'];
40  $row = $this->data['databaseRow'];
41  $parameterArray = $this->data['parameterArray'];
42  $config = $parameterArray['fieldConf']['config'];
43 
44  $selectItems = $parameterArray['fieldConf']['config']['items'];
45 
46  // Check against inline uniqueness
48  $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
49  $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
50  $uniqueIds = null;
51  if ($this->data['isInlineChild'] && $this->data['inlineParentUid']) {
52  $inlineObjectName = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
53  $inlineFormName = $inlineStackProcessor->getCurrentStructureFormPrefix();
54  if ($this->data['inlineParentConfig']['foreign_table'] === $table
55  && $this->data['inlineParentConfig']['foreign_unique'] === $field
56  ) {
57  $uniqueIds = $this->data['inlineData']['unique'][$inlineObjectName . '-' . $table]['used'];
58  $parameterArray['fieldChangeFunc']['inlineUnique'] = 'inline.updateUnique(this,'
59  . GeneralUtility::quoteJSvalue($inlineObjectName . '-' . $table) . ','
60  . GeneralUtility::quoteJSvalue($inlineFormName) . ','
61  . GeneralUtility::quoteJSvalue($row['uid']) . ');';
62  }
63  // hide uid of parent record for symmetric relations
64  if ($this->data['inlineParentConfig']['foreign_table'] === $table
65  && (
66  $this->data['inlineParentConfig']['foreign_field'] === $field
67  || $this->data['inlineParentConfig']['symmetric_field'] === $field
68  )
69  ) {
70  $uniqueIds[] = $this->data['inlineParentUid'];
71  }
72  }
73 
74  // Initialization:
75  $selectId = StringUtility::getUniqueId('tceforms-select-');
76  $selectedIcon = '';
77  $size = (int)$config['size'];
78 
79  // Style set on <select/>
80  $options = '';
81  $disabled = false;
82  if (!empty($config['readOnly'])) {
83  $disabled = true;
84  }
85 
86  // Prepare groups
87  $selectItemCounter = 0;
88  $selectItemGroupCount = 0;
89  $selectItemGroups = [];
90  $selectIcons = [];
91  $selectedValue = '';
92  $hasIcons = false;
93 
94  if (!empty($parameterArray['itemFormElValue'])) {
95  $selectedValue = (string)$parameterArray['itemFormElValue'][0];
96  }
97 
98  foreach ($selectItems as $item) {
99  if ($item[1] === '--div--') {
100  // IS OPTGROUP
101  if ($selectItemCounter !== 0) {
102  $selectItemGroupCount++;
103  }
104  $selectItemGroups[$selectItemGroupCount]['header'] = [
105  'title' => $item[0],
106  ];
107  } else {
108  // IS ITEM
109  $icon = !empty($item[2]) ? FormEngineUtility::getIconHtml($item[2], $item[0], $item[0]) : '';
110  $selected = $selectedValue === (string)$item[1];
111 
112  if ($selected) {
113  $selectedIcon = $icon;
114  }
115 
116  $selectItemGroups[$selectItemGroupCount]['items'][] = [
117  'title' => $item[0],
118  'value' => $item[1],
119  'icon' => $icon,
120  'selected' => $selected,
121  'index' => $selectItemCounter
122  ];
123 
124  // ICON
125  if ($icon) {
126  $selectIcons[] = [
127  'title' => $item[0],
128  'icon' => $icon,
129  'index' => $selectItemCounter,
130  ];
131  }
132 
133  $selectItemCounter++;
134  }
135  }
136 
137  // Fallback icon
138  // @todo: assign a special icon for non matching values?
139  if (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
140  $selectedIcon = $selectItemGroups[0]['items'][0]['icon'];
141  }
142 
143  // Process groups
144  foreach ($selectItemGroups as $selectItemGroup) {
145  // suppress groups without items
146  if (empty($selectItemGroup['items'])) {
147  continue;
148  }
149 
150  $optionGroup = is_array($selectItemGroup['header']);
151  $options .= ($optionGroup ? '<optgroup label="' . htmlspecialchars($selectItemGroup['header']['title'], ENT_COMPAT, 'UTF-8', false) . '">' : '');
152 
153  if (is_array($selectItemGroup['items'])) {
154  foreach ($selectItemGroup['items'] as $item) {
155  $options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
156  htmlspecialchars($item['icon']) . '"'
157  . ($item['selected'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($item['title'], ENT_COMPAT, 'UTF-8', false) . '</option>';
158  }
159  $hasIcons = !empty($item['icon']);
160  }
161 
162  $options .= ($optionGroup ? '</optgroup>' : '');
163  }
164 
165  // Build the element
166  $html = ['<div class="form-control-wrap">'];
167 
168  if ($hasIcons) {
169  $html[] = '<div class="input-group">';
170  $html[] = '<span class="input-group-addon input-group-icon">';
171  $html[] = $selectedIcon;
172  $html[] = '</span>';
173  }
174 
175  $html[] = '<select'
176  . ' id="' . $selectId . '"'
177  . ' name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"'
178  . $this->getValidationDataAsDataAttribute($config)
179  . ' class="form-control form-control-adapt"'
180  . ($size ? ' size="' . $size . '"' : '')
181  . ($disabled ? ' disabled="disabled"' : '')
182  . '>';
183  $html[] = $options;
184  $html[] = '</select>';
185 
186  if ($hasIcons) {
187  $html[] = '</div>';
188  }
189 
190  $html[] = '</div>';
191 
192  // Create icon table:
193  if (!empty($selectIcons) && !empty($config['showIconTable'])) {
194  $selectIconColumns = (int)$config['selicon_cols'];
195 
196  if (!$selectIconColumns) {
197  $selectIconColumns = count($selectIcons);
198  }
199 
200  $selectIconColumns = ($selectIconColumns > 12 ? 12 : $selectIconColumns);
201  $selectIconRows = ceil(count($selectIcons) / $selectIconColumns);
202  $selectIcons = array_pad($selectIcons, $selectIconRows * $selectIconColumns, '');
203 
204  $html[] = '<div class="t3js-forms-select-single-icons table-icons table-fit table-fit-inline-block">';
205  $html[] = '<table class="table table-condensed table-white table-center">';
206  $html[] = '<tbody>';
207  $html[] = '<tr>';
208 
209  foreach ($selectIcons as $i => $selectIcon) {
210  if ($i % $selectIconColumns === 0 && $i !== 0) {
211  $html[] = '</tr>';
212  $html[] = '<tr>';
213  }
214 
215  $html[] = '<td>';
216 
217  if (is_array($selectIcon)) {
218  $html[] = '<a href="#" title="' . htmlspecialchars($selectIcon['title'], ENT_COMPAT, 'UTF-8', false) . '" data-select-index="' . htmlspecialchars($selectIcon['index']) . '">';
219  $html[] = $selectIcon['icon'];
220  $html[] = '</a>';
221  }
222 
223  $html[] = '</td>';
224  }
225 
226  $html[] = '</tr>';
227  $html[] = '</tbody>';
228  $html[] = '</table>';
229  $html[] = '</div>';
230  }
231 
232  $html = implode(LF, $html);
233 
234  // Wizards:
235  if (!$disabled) {
236  $html = $this->renderWizards(
237  [$html],
238  $config['wizards'],
239  $table,
240  $row,
241  $field,
242  $parameterArray,
243  $parameterArray['itemFormElName'],
244  BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras'])
245  );
246  }
247 
248  $resultArray = $this->initializeResultArray();
249  $resultArray['html'] = $html;
250  $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectSingleElement' => implode(LF, [
251  'function(SelectSingleElement) {',
252  'require([\'jquery\'], function($) {',
253  '$(function() {',
254  'SelectSingleElement.initialize(',
255  GeneralUtility::quoteJSvalue('#' . $selectId) . ',',
256  '{',
257  'onChange: function() {',
258  implode('', $parameterArray['fieldChangeFunc']),
259  '},',
260  'onFocus: function() {',
261  $parameterArray['onFocus'],
262  '}',
263  '}',
264  ');',
265  '});',
266  '});',
267  '}',
268  ])];
269 
270  return $resultArray;
271  }
272 }
static getIconHtml($icon, $alt='', $title='')
getValidationDataAsDataAttribute(array $config)
static getSpecConfParts($defaultExtrasString, $_='')