[ 'renderType' => 'editPopup', 'disabled' => true, ], 'addRecord' => [ 'renderType' => 'addRecord', 'disabled' => true, ], 'listModule' => [ 'renderType' => 'listModule', 'disabled' => true, 'after' => [ 'addRecord' ], ], ]; /** * Default field wizards enabled for this element. * * @var array */ protected $defaultFieldWizard = [ 'localizationStateSelector' => [ 'renderType' => 'localizationStateSelector', ], 'otherLanguageContent' => [ 'renderType' => 'otherLanguageContent', 'after' => [ 'localizationStateSelector', ], ], 'defaultLanguageDifferences' => [ 'renderType' => 'defaultLanguageDifferences', 'after' => [ 'otherLanguageContent', ], ], ]; public function __construct( private readonly IconFactory $iconFactory, ) {} /** * Merge field control configuration with default controls and render them. * * @return array Result array */ protected function renderFieldControl(): array { $alternativeResult = [ 'additionalInlineLanguageLabelFiles' => [], 'stylesheetFiles' => [], 'javaScriptModules' => [], 'inlineData' => [], 'html' => '', ]; $options = $this->data; $fieldControl = $this->defaultFieldControl; $fieldControlFromTca = $options['parameterArray']['fieldConf']['config']['fieldControl'] ?? []; ArrayUtility::mergeRecursiveWithOverrule($fieldControl, $fieldControlFromTca); $options['renderType'] = 'fieldControl'; if (isset($fieldControl['editPopup'])) { $editPopupControl = $fieldControl['editPopup']; unset($fieldControl['editPopup']); $alternativeOptions = $options; $alternativeOptions['renderData']['fieldControl'] = ['editPopup' => $editPopupControl]; $alternativeResult = $this->nodeFactory->create($alternativeOptions)->render(); } $options['renderData']['fieldControl'] = $fieldControl; return [$this->nodeFactory->create($options)->render(), $alternativeResult]; } /** * Render side by side element. * * @return array As defined in initializeResultArray() of AbstractNode */ public function render(): array { $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; if ($config['readOnly'] ?? false) { // Early return for the relatively simple read only case return $this->renderReadOnly(); } $filterTextfield = []; $languageService = $this->getLanguageService(); $resultArray = $this->initializeResultArray(); $elementName = $parameterArray['itemFormElName']; $possibleItems = $config['items']; $selectedItems = $parameterArray['itemFormElValue'] ?: []; $maxItems = $config['maxitems']; $size = (int)($config['size'] ?? 2); $autoSizeMax = (int)($config['autoSizeMax'] ?? 0); if ($autoSizeMax > 0) { $size = MathUtility::forceIntegerInRange($size, 1); $size = MathUtility::forceIntegerInRange(count($selectedItems) + 1, $size, $autoSizeMax); } $itemCanBeSelectedMoreThanOnce = !empty($config['multiple']); $listOfSelectedValues = []; $selectedItemsHtml = []; foreach ($selectedItems as $itemValue) { foreach ($possibleItems as $possibleItem) { if ($possibleItem['value'] == $itemValue) { $title = $possibleItem['label']; $listOfSelectedValues[] = $itemValue; $selectedItemsHtml[] = ''; break; } } } $selectableItemCounter = 0; $selectableItemGroupCounter = 0; $selectableItemGroups = []; $selectableItemsHtml = []; // Initialize groups foreach ($possibleItems as $possibleItem) { $disableAttributes = []; if (!$itemCanBeSelectedMoreThanOnce && in_array((string)$possibleItem['value'], $selectedItems, true)) { $disableAttributes = [ 'disabled' => 'disabled', 'class' => 'hidden', ]; } if ($possibleItem['value'] === '--div--') { if ($selectableItemCounter !== 0) { $selectableItemGroupCounter++; } $selectableItemGroups[$selectableItemGroupCounter]['header']['title'] = $possibleItem['label']; } else { $selectableItemGroups[$selectableItemGroupCounter]['items'][] = [ 'label' => $this->appendValueToLabelInDebugMode($possibleItem['label'], $possibleItem['value']), 'attributes' => array_merge(['title' => $possibleItem['label'], 'value' => $possibleItem['value']], $disableAttributes), ]; // In case the item is not disabled, enable the group (if any) if ($disableAttributes === [] && isset($selectableItemGroups[$selectableItemGroupCounter]['header'])) { $selectableItemGroups[$selectableItemGroupCounter]['header']['disabled'] = false; } $selectableItemCounter++; } } // Process groups foreach ($selectableItemGroups as $selectableItemGroup) { if (!is_array($selectableItemGroup['items'] ?? false)) { continue; } $optionGroup = isset($selectableItemGroup['header']); if ($optionGroup) { $selectableItemsHtml[] = ''; } } // Html stuff for filter and select filter on top of right side of multi select boxes $filterTextfieldId = StringUtility::getUniqueId('tceforms-multiselect-filter-'); $filterTextfield[] = ''; $filterDropDownOptions = []; if (isset($config['multiSelectFilterItems']) && is_array($config['multiSelectFilterItems']) && count($config['multiSelectFilterItems']) > 1) { foreach ($config['multiSelectFilterItems'] as $optionElement) { $value = $languageService->sL($optionElement[0]); $label = $value; if (isset($optionElement[1]) && trim($optionElement[1]) !== '') { $label = $languageService->sL($optionElement[1]); } $filterDropDownOptions[] = ''; } } $filterHtml = []; $filterHtml[] = '