TYPO3 11 LTS中为selectMultipleSideBySide添加自定义fieldControl节点
解决TYPO3中selectMultipleSideBySide添加自定义FieldControl的问题
问题背景
你需要给selectMultipleSideBySide类型的TCA字段添加一个"全选"按钮,点击后将右侧所有可用选项移到已选列表,但当前配置后无任何输出,核心问题在于错误使用了Xclass重写NodeFactory,且自定义FieldControl的实现不符合TYPO3规范。
正确实现流程
1. 移除无效的Xclass配置
删除以下冗余配置:
Configuration/Services.php中NodeFactory的子类注册代码ext_localconf.php中关于NodeFactory的Xclass配置
2. 通过Services.yaml注册自定义FieldControl
在扩展的Configuration/Services.yaml中添加注册规则,这是TYPO3推荐的扩展方式:
services: NK\FeatureTour\Form\FieldControl\AllSelection: tags: - name: backend.form.fieldControl identifier: allSelection
该标签会自动将你的FieldControl类注册到FormEngine的NodeFactory,无需修改核心类。
3. 修正TCA配置中的renderType
确保TCA里的renderType与注册的标识符完全匹配(小写):
'select_multiplesidebyside_6' => [ 'label' => 'select_multiplesidebyside_6 fieldControl', 'config' => [ 'type' => 'select', 'renderType' => 'selectMultipleSideBySide', 'foreign_table' => 'tx_styleguide_staticdata', 'size' => 5, 'autoSizeMax' => 20, 'fieldControl' => [ 'editPopup' => [ 'disabled' => false, 'options' => [ 'windowOpenParameters' => 'height=300,width=500,status=0,' . 'menubar=0,scrollbars=1', ], ], 'addRecord' => [ 'disabled' => false, ], 'allSelection' => [ 'renderType' => 'allSelection' // 与Services.yaml中的identifier一致 ], ], ], ],
4. 完善AllSelection类的render方法
render()方法必须返回符合FieldControl规范的数组,包含按钮HTML、JavaScript依赖等,以下是完整实现:
<?php declare(strict_types=1); namespace NK\FeatureTour\Form\FieldControl; use TYPO3\CMS\Backend\Form\AbstractNode; use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction; use TYPO3\CMS\Core\Utility\StringUtility; class AllSelection extends AbstractNode { /** * 渲染全选按钮 * * @return array FieldControl渲染结果结构 */ public function render(): array { // 获取字段ID,用于关联前端逻辑 $fieldId = $this->data['parameterArray']['itemFormElID']; // 生成唯一按钮ID,避免冲突 $buttonId = StringUtility::getUniqueId('btn-all-selection-'); // 构建按钮HTML $buttonHtml = sprintf( '<button type="button" id="%s" class="btn btn-default" title="%s">%s</button>', htmlspecialchars($buttonId), htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:feature_tour/Resources/Private/Language/locallang.xlf:select_all')), htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:feature_tour/Resources/Private/Language/locallang.xlf:select_all')) ); // 绑定JavaScript模块 $javaScript = JavaScriptModuleInstruction::create('@nk-feature-tour/all-selection.js') ->assign('fieldId', $fieldId) ->assign('buttonId', $buttonId); return [ 'iconIdentifier' => 'actions-select-all', // 使用TYPO3内置图标 'title' => $this->getLanguageService()->sL('LLL:EXT:feature_tour/Resources/Private/Language/locallang.xlf:select_all'), 'html' => $buttonHtml, 'requireJsModules' => [$javaScript], ]; } }
5. 实现前端JavaScript逻辑
创建Resources/Public/JavaScript/all-selection.js,完成按钮点击后的全选功能:
import $ from 'jquery'; export default function({fieldId, buttonId}) { $(document).on('click', '#' + buttonId, function() { // 获取右侧可用选项的下拉框 const availableSelect = $('#' + fieldId).closest('.t3js-form-field-select-multiple-side-by-side').find('.available-items select'); // 获取所有选项并移到已选列表 availableSelect.find('option').appendTo($('#' + fieldId)); // 触发change事件,通知FormEngine数据已更新 $('#' + fieldId).trigger('change'); }); }
6. 添加语言翻译(可选)
在Resources/Private/Language/locallang.xlf中添加多语言支持:
<?xml version="1.0" encoding="UTF-8"?> <xliff version="1.0"> <file source-language="en" datatype="plaintext" original="messages" product-name="feature_tour"> <header/> <body> <trans-unit id="select_all"> <source>Select All</source> <target>全选</target> </trans-unit> </body> </file> </xliff>
验证
- 清除TYPO3所有缓存(配置缓存、页面缓存等)
- 打开对应后台编辑页面,查看字段是否显示"全选"按钮
- 点击按钮,验证是否能将右侧所有选项移到已选列表
内容的提问来源于stack exchange,提问作者Geee
相关产品推荐
相关产品推荐

