[ 'renderType' => 'tcaDescription', ], ]; /** * Default field controls for this element. * * @var array */ protected $defaultFieldControl = [ 'editPopup' => [ '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', ], ], ]; /** * Merge field control configuration with default controls and render them. * * @return array Result array */ protected function renderFieldControl(): array { $alternativeResult = [ 'additionalJavaScriptPost' => [], 'additionalHiddenFields' => [], 'additionalInlineLanguageLabelFiles' => [], 'stylesheetFiles' => [], 'requireJsModules' => [], '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() { $filterTextfield = []; $languageService = $this->getLanguageService(); $resultArray = $this->initializeResultArray(); $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; $elementName = $parameterArray['itemFormElName']; if ($config['readOnly']) { // Early return for the relatively simple read only case return $this->renderReadOnly(); } $possibleItems = $config['items']; $selectedItems = $parameterArray['itemFormElValue'] ?: []; $selectedItemsCount = count($selectedItems); $maxItems = $config['maxitems']; $autoSizeMax = MathUtility::forceIntegerInRange($config['autoSizeMax'], 0); $size = 2; if (isset($config['size'])) { $size = (int)$config['size']; } if ($autoSizeMax >= 1) { $size = MathUtility::forceIntegerInRange($selectedItemsCount + 1, MathUtility::forceIntegerInRange($size, 1), $autoSizeMax); } $itemCanBeSelectedMoreThanOnce = !empty($config['multiple']); $listOfSelectedValues = []; $selectedItemsHtml = []; foreach ($selectedItems as $itemValue) { foreach ($possibleItems as $possibleItem) { if ($possibleItem[1] == $itemValue) { $title = $possibleItem[0]; $listOfSelectedValues[] = $itemValue; $selectedItemsHtml[] = ''; break; } } } $selectableItemsHtml = []; foreach ($possibleItems as $possibleItem) { $disabledAttr = ''; $classAttr = ''; if (!$itemCanBeSelectedMoreThanOnce && in_array((string)$possibleItem[1], $selectedItems, true)) { $disabledAttr = ' disabled="disabled"'; $classAttr = ' class="hidden"'; } $selectableItemsHtml[] = ''; } // Html stuff for filter and select filter on top of right side of multi select boxes $filterTextfield[] = ''; $filterTextfield[] = ''; $filterTextfield[] = ''; $filterTextfield[] = ''; $filterTextfield[] = ''; $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[] = '
'; if (!empty($filterDropDownOptions)) { $filterHtml[] = '
'; $filterHtml[] = '
'; $filterHtml[] = ''; $filterHtml[] = '
'; $filterHtml[] = '
'; $filterHtml[] = implode(LF, $filterTextfield); $filterHtml[] = '
'; $filterHtml[] = '
'; } else { $filterHtml[] = implode(LF, $filterTextfield); } $filterHtml[] = '
'; $multipleAttribute = ''; if ($maxItems !== 1 && $size !== 1) { $multipleAttribute = ' multiple="multiple"'; } $fieldInformationResult = $this->renderFieldInformation(); $fieldInformationHtml = $fieldInformationResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); [$fieldControlResult, $alternativeControlResult] = $this->renderFieldControl(); $fieldControlHtml = $fieldControlResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false); $alternativeFieldControlHtml = $alternativeControlResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $alternativeControlResult, false); $fieldWizardResult = $this->renderFieldWizard(); $fieldWizardHtml = $fieldWizardResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false); $selectedOptionsFieldId = StringUtility::getUniqueId('tceforms-multiselect-'); $availableOptionsFieldId = StringUtility::getUniqueId('tceforms-multiselect-'); $html = []; $html[] = '
'; $html[] = $fieldInformationHtml; $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = ''; $html[] = '
'; $html[] = ''; $html[] = '
'; $html[] = '
'; $html[] = implode(LF, $filterHtml); $html[] = 'getValidationDataAsJsonString($config)) . '"'; $html[] = '>'; $html[] = implode(LF, $selectableItemsHtml); $html[] = ''; $html[] = '
'; if (!empty($fieldControlHtml)) { $html[] = '
'; $html[] = '
'; $html[] = $fieldControlHtml; $html[] = '
'; $html[] = '
'; } $html[] = '
'; $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = '
'; if (!empty($fieldWizardHtml)) { $html[] = '
'; $html[] = $fieldWizardHtml; $html[] = '
'; } $html[] = '
'; $html[] = ''; $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectMultipleSideBySideElement' => ' function(SelectMultipleSideBySideElement) { new SelectMultipleSideBySideElement(' . GeneralUtility::quoteJSvalue($selectedOptionsFieldId) . ', ' . GeneralUtility::quoteJSvalue($availableOptionsFieldId) . '); }' ]; $resultArray['html'] = implode(LF, $html); return $resultArray; } /** * Create HTML of a read only multi select. Right side is not * rendered, but just the left side with the selected items. * * @return array */ protected function renderReadOnly() { $languageService = $this->getLanguageService(); $resultArray = $this->initializeResultArray(); $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; $fieldName = $parameterArray['itemFormElName']; $possibleItems = $config['items']; $selectedItems = $parameterArray['itemFormElValue'] ?: []; if (!is_array($selectedItems)) { $selectedItems = GeneralUtility::trimExplode(',', $selectedItems, true); } $selectedItemsCount = count($selectedItems); $autoSizeMax = MathUtility::forceIntegerInRange($config['autoSizeMax'], 0); $size = 2; if (isset($config['size'])) { $size = (int)$config['size']; } if ($autoSizeMax >= 1) { $size = MathUtility::forceIntegerInRange($selectedItemsCount + 1, MathUtility::forceIntegerInRange($size, 1), $autoSizeMax); } $multiple = ''; if ($size !== 1) { $multiple = ' multiple="multiple"'; } $listOfSelectedValues = []; $optionsHtml = []; foreach ($selectedItems as $itemValue) { foreach ($possibleItems as $possibleItem) { if ($possibleItem[1] == $itemValue) { $title = $possibleItem[0]; $listOfSelectedValues[] = $itemValue; $optionsHtml[] = ''; break; } } } $fieldInformationResult = $this->renderFieldInformation(); $fieldInformationHtml = $fieldInformationResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); $html = []; $html[] = '
'; $html[] = $fieldInformationHtml; $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = '
'; $html[] = '
'; $html[] = '
'; $resultArray['html'] = implode(LF, $html); return $resultArray; } /** * @return LanguageService */ protected function getLanguageService() { return $GLOBALS['LANG']; } /** * @return BackendUserAuthentication */ protected function getBackendUserAuthentication() { return $GLOBALS['BE_USER']; } }