diff --git a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/FormEngine/Element/SelectTreeElement.ts b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/FormEngine/Element/SelectTreeElement.ts new file mode 100644 index 0000000000000000000000000000000000000000..31184121020a421ae25c6ddcd5780ac890ff2b49 --- /dev/null +++ b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/FormEngine/Element/SelectTreeElement.ts @@ -0,0 +1,79 @@ +/* +* This file is part of the TYPO3 CMS project. +* +* It is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, either version 2 +* of the License, or any later version. +* +* For the full copyright and license information, please read the +* LICENSE.txt file that was distributed with this source code. +* +* The TYPO3 project - inspiring people to share! +*/ + +import SelectTree = require('TYPO3/CMS/Backend/FormEngine/Element/SelectTree'); + +class SelectTreeElement { + private readonly treeWrapper: HTMLElement = null; + private readonly recordField: HTMLInputElement = null; + private readonly callback: Function = null; + + constructor(treeWrapperId: string, treeRecordFieldId: string, callback: Function) { + this.treeWrapper = <HTMLElement>document.querySelector('#' + treeWrapperId); + this.recordField = <HTMLInputElement>document.querySelector('#' + treeRecordFieldId); + this.callback = callback; + + this.initialize(); + } + + private initialize(): void { + const dataUrl = this.generateRequestUrl(); + const tree = new SelectTree(); + + const settings = { + dataUrl: dataUrl, + showIcons: true, + showCheckboxes: true, + readOnlyMode: parseInt(this.recordField.dataset.readOnly, 10) === 1, + input: this.recordField, + exclusiveNodesIdentifiers: this.recordField.dataset.treeExclusiveKeys, + validation: JSON.parse(this.recordField.dataset.formengineValidationRules)[0], + expandUpToLevel: this.recordField.dataset.treeExpandUpToLevel, + }; + const initialized = tree.initialize(this.treeWrapper, settings); + if (!initialized) { + return; + } + + tree.dispatch.on('nodeSelectedAfter.requestUpdate', this.callback); + + if (this.recordField.dataset.treeShowToolbar) { + require(['TYPO3/CMS/Backend/FormEngine/Element/TreeToolbar'], (TreeToolbar: any): void => { + const selectTreeToolbar = new TreeToolbar(); + selectTreeToolbar.initialize(this.treeWrapper); + }); + } + } + + private generateRequestUrl(): string { + const params = { + tableName: this.recordField.dataset.tablename, + fieldName: this.recordField.dataset.fieldname, + uid: this.recordField.dataset.uid, + recordTypeValue: this.recordField.dataset.recordtypevalue, + dataStructureIdentifier: this.recordField.dataset.datastructureidentifier !== '' + ? JSON.parse(this.recordField.dataset.datastructureidentifier) + : '', + flexFormSheetName: this.recordField.dataset.flexformsheetname, + flexFormFieldName: this.recordField.dataset.flexformfieldname, + flexFormContainerName: this.recordField.dataset.flexformcontainername, + flexFormContainerIdentifier: this.recordField.dataset.flexformcontaineridentifier, + flexFormContainerFieldName: this.recordField.dataset.flexformcontainerfieldname, + flexFormSectionContainerIsNew: this.recordField.dataset.flexformsectioncontainerisnew, + command: this.recordField.dataset.command, + }; + return TYPO3.settings.ajaxUrls.record_tree_data + '&' + $.param(params); + } +} + +export = SelectTreeElement; diff --git a/Build/types/TYPO3/index.d.ts b/Build/types/TYPO3/index.d.ts index 2e41db07977ced82f0c97823533757fe3126520d..e4872a5076605c5d46fa5aa55b204636ff0868fa 100644 --- a/Build/types/TYPO3/index.d.ts +++ b/Build/types/TYPO3/index.d.ts @@ -16,7 +16,6 @@ declare namespace TYPO3 { export let Modal: any; export let OpendocsMenu: any; export let Permissions: any; - export let Popover: any; export let Severity: any; export let ShortcutMenu: any; export let Storage: any; @@ -35,6 +34,16 @@ declare namespace TYPO3 { public validate(): void; } + export namespace FormEngine { + export namespace Element { + export class SelectTree { + public dispatch: {[key: string]: Function}; + public constructor(); + public initialize(selector: HTMLElement|JQuery, settings: {[key: string]: any}): boolean; + } + } + } + export class FormEngine { public readonly Validation: FormEngineValidation; public legacyFieldChangedCb(): void; @@ -80,6 +89,10 @@ declare module 'TYPO3/CMS/Backend/FormEngine' { export = new TYPO3.CMS.Backend.FormEngine(); } +declare module 'TYPO3/CMS/Backend/FormEngine/Element/SelectTree' { + export = TYPO3.CMS.Backend.FormEngine.Element.SelectTree; +} + declare module 'TYPO3/CMS/Backend/Wizard' { export = new TYPO3.CMS.Backend.Wizard(); } diff --git a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php index 7941fd4ac72f7b6e30e443360148a00daf018ca7..67b73dd0aacf55edf3d038cb677e83909eabae48 100644 --- a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php @@ -14,6 +14,8 @@ namespace TYPO3\CMS\Backend\Form\Element; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Utility\GeneralUtility; + /** * Render data as a tree. * @@ -78,7 +80,7 @@ class SelectTreeElement extends AbstractFormElement // Field configuration from TCA: $config = $parameterArray['fieldConf']['config']; - $readOnly = !empty($config['readOnly']) ? 'true' : 'false'; + $readOnly = !empty($config['readOnly']) ? 1 : 0; $exclusiveKeys = !empty($config['exclusiveKeys']) ? $config['exclusiveKeys'] : ''; $exclusiveKeys = $exclusiveKeys . ','; $appearance = !empty($config['treeConfig']['appearance']) ? $config['treeConfig']['appearance'] : []; @@ -91,6 +93,7 @@ class SelectTreeElement extends AbstractFormElement } $heightInPx = $height * $this->itemHeight; $treeWrapperId = 'tree_' . $formElementId; + $fieldId = 'tree_record_' . $formElementId; $fieldName = $this->data['fieldName']; @@ -140,7 +143,7 @@ class SelectTreeElement extends AbstractFormElement $html[] = '<div class="form-wizards-wrap">'; $html[] = '<div class="form-wizards-element">'; $html[] = '<div class="typo3-tceforms-tree">'; - $html[] = '<input class="treeRecord" type="hidden"'; + $html[] = '<input class="treeRecord" type="hidden" id="' . htmlspecialchars($fieldId) . '"'; $html[] = ' data-formengine-validation-rules="' . htmlspecialchars($this->getValidationDataAsJsonString($config)) . '"'; $html[] = ' data-relatedfieldname="' . htmlspecialchars($parameterArray['itemFormElName']) . '"'; $html[] = ' data-tablename="' . htmlspecialchars($this->data['tableName']) . '"'; @@ -165,7 +168,6 @@ class SelectTreeElement extends AbstractFormElement $html[] = '/>'; $html[] = '</div>'; $html[] = '<div id="' . $treeWrapperId . '" class="svg-tree-wrapper" style="height: ' . $heightInPx . 'px;"></div>'; - $html[] = '<script type="text/javascript">var ' . $treeWrapperId . ' = ' . $this->getTreeOnChangeJs() . '</script>'; $html[] = '</div>'; if ($readOnly === 'false' && !empty($fieldWizardHtml)) { $html[] = '<div class="form-wizards-items-bottom">'; @@ -182,8 +184,14 @@ class SelectTreeElement extends AbstractFormElement if ($showHeader) { $resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:core/Resources/Private/Language/locallang_csh_corebe.xlf'; } - $resultArray['requireJsModules']['selectTreeElement'] = [ - 'TYPO3/CMS/Backend/FormEngine/Element/SelectTreeElement' => 'function (SelectTreeElement) { SelectTreeElement.initialize(); }' + $resultArray['requireJsModules']['selectTreeElement'] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectTreeElement' => ' + function(SelectTreeElement) { + require([\'jquery\'], function($) { + $(function() { + new SelectTreeElement(' . GeneralUtility::quoteJSvalue($treeWrapperId) . ', ' . GeneralUtility::quoteJSvalue($fieldId) . ', ' . $this->getTreeOnChangeJs() . '); + }); + }); + }' ]; return $resultArray; diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js index eb5b40a8be8a88503893ef2d2d46bc6a1f6f9320..6affacd49743657beb766aacf312cd05fd204af7 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js @@ -193,9 +193,9 @@ define(['d3', 'TYPO3/CMS/Backend/SvgTree', 'TYPO3/CMS/Backend/FormEngine'], SelectTree.prototype.saveCheckboxes = function() { if (typeof this.settings.input !== 'undefined') { var selectedNodes = this.getSelectedNodes(); - this.settings.input.val(selectedNodes.map(function(d) { + this.settings.input.value = selectedNodes.map(function(d) { return d.identifier; - })); + }); } }; diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js index 643336ffc1674611122a9785906ed64515032184..1428e08668e3753cbb77f4817e151e39f474bcbc 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js @@ -10,69 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ - -/** - * Initialization of the selectTree js component used e.g. for category tree rendering - */ -define(['jquery', 'TYPO3/CMS/Backend/FormEngine/Element/SelectTree'], - function($, SelectTree) { - 'use strict'; - - var SelectTreeElement = {}; - - SelectTreeElement.initialize = function() { - $(document).ready(function() { - $('.typo3-tceforms-tree .treeRecord').each(function(i, element) { - - /** - * Hidden input field storing selected elements. - * Tree is initialized based on values stored in it's data attributes - * - * @type {*|jQuery|HTMLElement} - */ - var $treeInput = $(element); - var dataParams = { - tableName: $treeInput.data('tablename'), - fieldName: $treeInput.data('fieldname'), - uid: $treeInput.data('uid'), - recordTypeValue: $treeInput.data('recordtypevalue'), - dataStructureIdentifier: $treeInput.data('datastructureidentifier'), - flexFormSheetName: $treeInput.data('flexformsheetname'), - flexFormFieldName: $treeInput.data('flexformfieldname'), - flexFormContainerName: $treeInput.data('flexformcontainername'), - flexFormContainerIdentifier: $treeInput.data('flexformcontaineridentifier'), - flexFormContainerFieldName: $treeInput.data('flexformcontainerfieldname'), - flexFormSectionContainerIsNew: $treeInput.data('flexformsectioncontainerisnew'), - command: $treeInput.data('command') - }; - var $wrapper = $treeInput.parent().siblings('.svg-tree-wrapper'); - var dataUrl = TYPO3.settings.ajaxUrls.record_tree_data + '&' + $.param(dataParams); - var tree = new SelectTree(); - var initialized = tree.initialize($wrapper, { - dataUrl: dataUrl, - showIcons: true, - showCheckboxes: true, - readOnlyMode: $treeInput.data('read-only'), - input: $treeInput, - exclusiveNodesIdentifiers: $treeInput.data('tree-exclusive-keys'), - validation: $treeInput.data('formengine-validation-rules')[0], - expandUpToLevel: $treeInput.data('tree-expand-up-to-level') - }); - if (!initialized) { - return; - } - - tree.dispatch.on('nodeSelectedAfter.requestUpdate', window[$wrapper.attr('id')]); - - if ($treeInput.data('tree-show-toolbar')) { - require(['TYPO3/CMS/Backend/FormEngine/Element/TreeToolbar'], function(TreeToolbar) { - var selectTreeToolbar = new TreeToolbar(); - selectTreeToolbar.initialize($wrapper); - }); - } - }); - }); - }; - - return SelectTreeElement; - }); +define(["require","exports","TYPO3/CMS/Backend/FormEngine/Element/SelectTree"],function(e,t,r){"use strict";return function(){function t(e,t,r){this.treeWrapper=null,this.recordField=null,this.callback=null,this.treeWrapper=document.querySelector("#"+e),this.recordField=document.querySelector("#"+t),this.callback=r,this.initialize()}return t.prototype.initialize=function(){var t=this,i=this.generateRequestUrl(),a=new r,d={dataUrl:i,showIcons:!0,showCheckboxes:!0,readOnlyMode:1===parseInt(this.recordField.dataset.readOnly,10),input:this.recordField,exclusiveNodesIdentifiers:this.recordField.dataset.treeExclusiveKeys,validation:JSON.parse(this.recordField.dataset.formengineValidationRules)[0],expandUpToLevel:this.recordField.dataset.treeExpandUpToLevel};a.initialize(this.treeWrapper,d)&&(a.dispatch.on("nodeSelectedAfter.requestUpdate",this.callback),this.recordField.dataset.treeShowToolbar&&e(["TYPO3/CMS/Backend/FormEngine/Element/TreeToolbar"],function(e){(new e).initialize(t.treeWrapper)}))},t.prototype.generateRequestUrl=function(){var e={tableName:this.recordField.dataset.tablename,fieldName:this.recordField.dataset.fieldname,uid:this.recordField.dataset.uid,recordTypeValue:this.recordField.dataset.recordtypevalue,dataStructureIdentifier:""!==this.recordField.dataset.datastructureidentifier?JSON.parse(this.recordField.dataset.datastructureidentifier):"",flexFormSheetName:this.recordField.dataset.flexformsheetname,flexFormFieldName:this.recordField.dataset.flexformfieldname,flexFormContainerName:this.recordField.dataset.flexformcontainername,flexFormContainerIdentifier:this.recordField.dataset.flexformcontaineridentifier,flexFormContainerFieldName:this.recordField.dataset.flexformcontainerfieldname,flexFormSectionContainerIsNew:this.recordField.dataset.flexformsectioncontainerisnew,command:this.recordField.dataset.command};return TYPO3.settings.ajaxUrls.record_tree_data+"&"+$.param(e)},t}()}); \ No newline at end of file