fa1931b8f5150d4b461eecfc8e46169ebab35b5b
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Resources / Public / JavaScript / Backend / FormEditor / InspectorComponent.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Form/Backend/FormEditor/InspectorComponent
16 */
17
18 /**
19 * Add legacy functions to be accessible in the global scope.
20 * This is needed by TYPO3/CMS/Recordlist/ElementBrowser
21 */
22 var setFormValueFromBrowseWin;
23
24 define(['jquery',
25 'TYPO3/CMS/Form/Backend/FormEditor/Helper',
26 'TYPO3/CMS/Backend/Icons',
27 'TYPO3/CMS/Backend/Notification',
28 'TYPO3/CMS/Form/Backend/Vendor/jquery.mjs.nestedSortable'
29 ], function($, Helper, Icons, Notification) {
30 'use strict';
31
32 return (function($, Helper, Icons, Notification) {
33
34 /**
35 * @private
36 *
37 * @var object
38 */
39 var _configuration = null;
40
41 /**
42 * @private
43 *
44 * @var object
45 */
46 var _defaultConfiguration = {
47 domElementClassNames: {
48 buttonFormElementRemove: 't3-form-remove-element-button',
49 collectionElement: 't3-form-collection-element',
50 finisherEditorPrefix: 't3-form-inspector-finishers-editor-',
51 inspectorEditor: 'form-editor',
52 inspectorInputGroup: 'input-group',
53 validatorEditorPrefix: 't3-form-inspector-validators-editor-'
54 },
55 domElementDataAttributeNames: {
56 contentElementSelectorTarget: 'data-insert-target',
57 finisher: 'data-finisher-identifier',
58 validator: 'data-validator-identifier'
59 },
60 domElementDataAttributeValues: {
61 collapse: 'actions-view-table-expand',
62 editorControlsInputGroup: 'inspectorEditorControlsGroup',
63 editorWrapper: 'editorWrapper',
64 editorControlsWrapper: 'inspectorEditorControlsWrapper',
65 formElementHeaderEditor: 'inspectorFormElementHeaderEditor',
66 formElementSelectorControlsWrapper: 'inspectorEditorFormElementSelectorControlsWrapper',
67 formElementSelectorSplitButtonContainer: 'inspectorEditorFormElementSelectorSplitButtonContainer',
68 formElementSelectorSplitButtonListContainer: 'inspectorEditorFormElementSelectorSplitButtonListContainer',
69 iconNotAvailable: 'actions-close',
70 iconPage: 'apps-pagetree-page-default',
71 iconTtContent: 'mimetypes-x-content-text',
72 inspector: 'inspector',
73 'Inspector-CheckboxEditor': 'Inspector-CheckboxEditor',
74 'Inspector-CollectionElementHeaderEditor': 'Inspector-CollectionElementHeaderEditor',
75 'Inspector-FinishersEditor': 'Inspector-FinishersEditor',
76 'Inspector-FormElementHeaderEditor': 'Inspector-FormElementHeaderEditor',
77 'Inspector-PropertyGridEditor': 'Inspector-PropertyGridEditor',
78 'Inspector-RemoveElementEditor': 'Inspector-RemoveElementEditor',
79 'Inspector-RequiredValidatorEditor': 'Inspector-RequiredValidatorEditor',
80 'Inspector-SingleSelectEditor': 'Inspector-SingleSelectEditor',
81 'Inspector-MultiSelectEditor': 'Inspector-MultiSelectEditor',
82 'Inspector-GridColumnViewPortConfigurationEditor': 'Inspector-GridColumnViewPortConfigurationEditor',
83 'Inspector-TextareaEditor': 'Inspector-TextareaEditor',
84 'Inspector-TextEditor': 'Inspector-TextEditor',
85 'Inspector-Typo3WinBrowserEditor': 'Inspector-Typo3WinBrowserEditor',
86 'Inspector-ValidatorsEditor': 'Inspector-ValidatorsEditor',
87 inspectorFinishers: 'inspectorFinishers',
88 inspectorValidators: 'inspectorValidators',
89 propertyGridEditorAddRow: 'addRow',
90 propertyGridEditorAddRowItem: 'addRowItem',
91 propertyGridEditorContainer: 'propertyGridContainer',
92 propertyGridEditorDeleteRow: 'deleteRow',
93 propertyGridEditorLabel: 'label',
94 propertyGridEditorRowItem: 'rowItem',
95 propertyGridEditorSelectValue: 'selectValue',
96 propertyGridEditorSortRow: 'sortRow',
97 propertyGridEditorValue: 'value',
98 viewportButton: 'viewportButton'
99 },
100 domElementIdNames: {
101 finisherPrefix: 't3-form-inspector-finishers-',
102 validatorPrefix: 't3-form-inspector-validators-'
103 },
104 isSortable: true
105 };
106
107 /**
108 * @private
109 *
110 * @var object
111 */
112 var _formEditorApp = null;
113
114 /* *************************************************************
115 * Private Methodes
116 * ************************************************************/
117
118 /**
119 * @private
120 *
121 * @return void
122 * @throws 1478268638
123 */
124 function _helperSetup() {
125 assert('function' === $.type(Helper.bootstrap),
126 'The view model helper does not implement the method "bootstrap"',
127 1478268638
128 );
129 Helper.bootstrap(getFormEditorApp());
130 };
131
132 /**
133 * @private
134 *
135 * @return object
136 */
137 function getFormEditorApp() {
138 return _formEditorApp;
139 };
140
141 /**
142 * @private
143 *
144 * @return object
145 */
146 function getViewModel() {
147 return getFormEditorApp().getViewModel();
148 };
149
150 /**
151 * @private
152 *
153 * @param object
154 * @return object
155 */
156 function getHelper(configuration) {
157 if (getUtility().isUndefinedOrNull(configuration)) {
158 return Helper.setConfiguration(_configuration);
159 }
160 return Helper.setConfiguration(configuration);
161 };
162
163 /**
164 * @private
165 *
166 * @return object
167 */
168 function getUtility() {
169 return getFormEditorApp().getUtility();
170 };
171
172 /**
173 * @private
174 *
175 * @param mixed test
176 * @param string message
177 * @param int messageCode
178 * @return void
179 */
180 function assert(test, message, messageCode) {
181 return getFormEditorApp().assert(test, message, messageCode);
182 };
183
184 /**
185 * @private
186 *
187 * @return object
188 */
189 function getCurrentlySelectedFormElement() {
190 return getFormEditorApp().getCurrentlySelectedFormElement();
191 };
192
193 /**
194 * @private
195 *
196 * @return object
197 */
198 function getRootFormElement() {
199 return getFormEditorApp().getRootFormElement();
200 };
201
202 /**
203 * @private
204 *
205 * @return object
206 */
207 function getPublisherSubscriber() {
208 return getFormEditorApp().getPublisherSubscriber();
209 };
210
211 /**
212 * @private
213 *
214 * @param object
215 * @param string
216 * @return mixed
217 */
218 function getFormElementDefinition(formElement, formElementDefinitionKey) {
219 return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
220 };
221
222 /**
223 * @private
224 *
225 * @param object
226 * @param object
227 * @param string
228 * @param string
229 * @return void
230 * @publish view/inspector/editor/insert/perform
231 */
232 function _renderEditorDispatcher(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
233 switch (editorConfiguration['templateName']) {
234 case 'Inspector-FormElementHeaderEditor':
235 renderFormElementHeaderEditor(
236 editorConfiguration,
237 editorHtml,
238 collectionElementIdentifier,
239 collectionName
240 );
241 break;
242 case 'Inspector-CollectionElementHeaderEditor':
243 renderCollectionElementHeaderEditor(
244 editorConfiguration,
245 editorHtml,
246 collectionElementIdentifier,
247 collectionName
248 );
249 break;
250 case 'Inspector-TextEditor':
251 renderTextEditor(
252 editorConfiguration,
253 editorHtml,
254 collectionElementIdentifier,
255 collectionName
256 );
257 break;
258 case 'Inspector-FinishersEditor':
259 renderCollectionElementSelectionEditor(
260 'finishers',
261 editorConfiguration,
262 editorHtml,
263 collectionElementIdentifier,
264 collectionName
265 );
266 break;
267 case 'Inspector-ValidatorsEditor':
268 renderCollectionElementSelectionEditor(
269 'validators',
270 editorConfiguration,
271 editorHtml,
272 collectionElementIdentifier,
273 collectionName
274 );
275 break;
276 case 'Inspector-RemoveElementEditor':
277 renderRemoveElementEditor(
278 editorConfiguration,
279 editorHtml,
280 collectionElementIdentifier,
281 collectionName
282 );
283 break;
284 case 'Inspector-RequiredValidatorEditor':
285 renderRequiredValidatorEditor(
286 editorConfiguration,
287 editorHtml,
288 collectionElementIdentifier,
289 collectionName
290 );
291 break;
292 case 'Inspector-CheckboxEditor':
293 renderCheckboxEditor(
294 editorConfiguration,
295 editorHtml,
296 collectionElementIdentifier,
297 collectionName
298 );
299 break;
300 case 'Inspector-SingleSelectEditor':
301 renderSingleSelectEditor(
302 editorConfiguration,
303 editorHtml,
304 collectionElementIdentifier,
305 collectionName
306 );
307 break;
308 case 'Inspector-MultiSelectEditor':
309 renderMultiSelectEditor(
310 editorConfiguration,
311 editorHtml,
312 collectionElementIdentifier,
313 collectionName
314 );
315 break;
316 case 'Inspector-GridColumnViewPortConfigurationEditor':
317 renderGridColumnViewPortConfigurationEditor(
318 editorConfiguration,
319 editorHtml,
320 collectionElementIdentifier,
321 collectionName
322 );
323 break;
324 case 'Inspector-PropertyGridEditor':
325 renderPropertyGridEditor(
326 editorConfiguration,
327 editorHtml,
328 collectionElementIdentifier,
329 collectionName
330 );
331 break;
332 case 'Inspector-TextareaEditor':
333 renderTextareaEditor(
334 editorConfiguration,
335 editorHtml,
336 collectionElementIdentifier,
337 collectionName
338 );
339 break;
340 case 'Inspector-Typo3WinBrowserEditor':
341 renderTypo3WinBrowserEditor(
342 editorConfiguration,
343 editorHtml,
344 collectionElementIdentifier,
345 collectionName
346 );
347 break;
348 }
349 getPublisherSubscriber().publish('view/inspector/editor/insert/perform', [
350 editorConfiguration, editorHtml, collectionElementIdentifier, collectionName
351 ]);
352 };
353
354 /**
355 * @private
356 *
357 * opens a popup window with the element browser
358 *
359 * @param string mode
360 * @param string params
361 * @param int width
362 * @param int height
363 */
364 function _openTypo3WinBrowser(mode, params, width, height) {
365 var openedPopupWindow, url;
366 url = TYPO3.settings.FormEditor.typo3WinBrowserUrl
367 + '&mode=' + mode + '&bparams=' + params;
368 openedPopupWindow = window.open(
369 url,
370 'Typo3WinBrowser',
371 'height=' + height + ',width=' + width + ',status=0,menubar=0,resizable=1,scrollbars=1'
372 );
373 openedPopupWindow.focus();
374 };
375
376 /**
377 * @private
378 *
379 * @param string
380 * @param string
381 * @return object
382 */
383 function _getCollectionElementClass(collectionName, collectionElementIdentifier) {
384 if (collectionName === 'finishers') {
385 return getHelper()
386 .getDomElementClassName('finisherEditorPrefix') + collectionElementIdentifier;
387 } else {
388 return getHelper()
389 .getDomElementClassName('validatorEditorPrefix') + collectionElementIdentifier;
390 }
391 };
392
393 /**
394 * @private
395 *
396 * @param string
397 * @param string
398 * @param bool
399 * @return object
400 */
401 function _getCollectionElementId(collectionName, collectionElementIdentifier, asSelector) {
402 if (collectionName === 'finishers') {
403 return getHelper()
404 .getDomElementIdName('finisherPrefix', asSelector) + collectionElementIdentifier;
405 } else {
406 return getHelper()
407 .getDomElementIdName('validatorPrefix', asSelector) + collectionElementIdentifier;
408 }
409 };
410
411 /**
412 * @private
413 *
414 * @param object
415 * @param string
416 * @return void
417 */
418 function _addSortableCollectionElementsEvents(sortableDomElement, collectionName) {
419 sortableDomElement.addClass(getHelper().getDomElementClassName('sortable')).sortable({
420 revert: 'true',
421 items: getHelper().getDomElementClassName('collectionElement', true),
422 cancel: getHelper().getDomElementClassName('jQueryUiStateDisabled', true) + ',input,select',
423 delay: 200,
424 update: function(e, o) {
425 var dataAttributeName, nextCollectionElementIdentifier, movedCollectionElementIdentifier, previousCollectionElementIdentifier;
426
427 if (collectionName === 'finishers') {
428 dataAttributeName = getHelper().getDomElementDataAttribute('finisher');
429 } else {
430 dataAttributeName = getHelper().getDomElementDataAttribute('validator');
431 }
432
433 movedCollectionElementIdentifier = $(o.item).attr(dataAttributeName);
434 previousCollectionElementIdentifier = $(o.item)
435 .prevAll(getHelper().getDomElementClassName('collectionElement', true))
436 .first()
437 .attr(dataAttributeName);
438 nextCollectionElementIdentifier = $(o.item)
439 .nextAll(getHelper().getDomElementClassName('collectionElement', true))
440 .first()
441 .attr(dataAttributeName);
442
443 getPublisherSubscriber().publish('view/inspector/collectionElements/dnd/update', [
444 movedCollectionElementIdentifier,
445 previousCollectionElementIdentifier,
446 nextCollectionElementIdentifier,
447 collectionName
448 ]);
449 }
450 });
451 };
452
453 /**
454 * @private
455 *
456 * @param object editorHtml
457 * @param bool multiSelection
458 * @param string propertyPath
459 * @param string propertyPathPrefix
460 * @return void
461 */
462 function _setPropertyGridData(editorHtml, multiSelection, propertyPath, propertyPathPrefix) {
463 var defaultValue, newPropertyData;
464
465 if (multiSelection) {
466 defaultValue = [];
467
468 $( getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
469 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked',
470 $(editorHtml)
471 ).each(function(i) {
472 defaultValue.push(
473 $(this)
474 .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
475 .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
476 .val()
477 );
478 });
479 getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', defaultValue);
480 } else {
481 getCurrentlySelectedFormElement().set(
482 propertyPathPrefix + 'defaultValue',
483 $(
484 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
485 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked',
486 $(editorHtml)
487 ).first()
488 .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
489 .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
490 .val(),
491 true
492 );
493 }
494
495 newPropertyData = [];
496 $(
497 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
498 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
499 $(editorHtml)
500 ).each(function(i) {
501 var value, label, tmpObject;
502
503 value = $(this)
504 .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
505 .val();
506 label = $(this)
507 .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'))
508 .val();
509
510 if ('' === value) {
511 value = label;
512 }
513
514 tmpObject = {};
515 tmpObject[value] = label;
516 newPropertyData.push({
517 _label: label,
518 _value: value
519 });
520 });
521
522 getCurrentlySelectedFormElement().set(propertyPathPrefix + propertyPath, newPropertyData);
523 };
524
525 /**
526 * @private
527 *
528 * @param object
529 * @return object
530 */
531 function _getEditorWrapperDomElement(editorDomElement) {
532 return $(getHelper().getDomElementDataIdentifierSelector('editorWrapper'), $(editorDomElement));
533 };
534
535 /**
536 * @private
537 *
538 * @param object
539 * @return object
540 */
541 function _getEditorControlsWrapperDomElement(editorDomElement) {
542 return $(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'), $(editorDomElement));
543 };
544
545 /**
546 * @private
547 *
548 * @param string
549 * @param object
550 * @return void
551 */
552 function _validateCollectionElement(propertyPath, editorHtml) {
553 var hasError, propertyPrefix, validationResults;
554
555 validationResults = getFormEditorApp().validateCurrentlySelectedFormElementProperty(propertyPath);
556
557 if (validationResults.length > 0) {
558 getHelper()
559 .getTemplatePropertyDomElement('validationErrors', editorHtml)
560 .text(validationResults[0]);
561 getViewModel().setElementValidationErrorClass(
562 getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml)
563 );
564 getViewModel().setElementValidationErrorClass(
565 _getEditorControlsWrapperDomElement(editorHtml),
566 'hasError'
567 );
568 } else {
569 getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml).text('');
570 getViewModel().removeElementValidationErrorClass(
571 getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml)
572 );
573 getViewModel().removeElementValidationErrorClass(
574 _getEditorControlsWrapperDomElement(editorHtml),
575 'hasError'
576 );
577 }
578
579 validationResults = getFormEditorApp().validateFormElement(getCurrentlySelectedFormElement());
580 propertyPrefix = propertyPath.split('.');
581 propertyPrefix = propertyPrefix[0] + '.' + propertyPrefix[1];
582
583 hasError = false;
584 for (var i = 0, len = validationResults.length; i < len; ++i) {
585 if (
586 validationResults[i]['propertyPath'].indexOf(propertyPrefix, 0) === 0
587 && validationResults[i]['validationResults']
588 && validationResults[i]['validationResults'].length > 0
589 ) {
590 hasError = true;
591 break;
592 }
593 }
594
595 if (hasError) {
596 getViewModel().setElementValidationErrorClass(
597 _getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
598 );
599 } else {
600 getViewModel().removeElementValidationErrorClass(
601 _getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
602 );
603 }
604 };
605
606 /* *************************************************************
607 * Public Methodes
608 * ************************************************************/
609
610 /**
611 * @public
612 *
613 * callback from TYPO3/CMS/Recordlist/ElementBrowser
614 *
615 * @param string fieldReference
616 * @param string elValue
617 * @param string elName
618 * @return void
619 */
620 setFormValueFromBrowseWin = function(fieldReference, elValue, elName) {
621 var result;
622 result = elValue.split('_');
623
624 $(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKeyValue', [fieldReference]))
625 .val(result.pop())
626 .trigger('paste');
627 };
628
629 /**
630 * @public
631 *
632 * @return object
633 */
634 function getInspectorDomElement() {
635 return $(getHelper().getDomElementDataIdentifierSelector('inspector'));
636 };
637
638 /**
639 * @public
640 *
641 * @return object
642 */
643 function getFinishersContainerDomElement() {
644 return $(getHelper().getDomElementDataIdentifierSelector('inspectorFinishers'), getInspectorDomElement());
645 };
646
647 /**
648 * @public
649 *
650 * @return object
651 */
652 function getValidatorsContainerDomElement() {
653 return $(getHelper().getDomElementDataIdentifierSelector('inspectorValidators'), getInspectorDomElement());
654 };
655
656 /**
657 * @public
658 *
659 * @param string
660 * @param string
661 * @return object
662 */
663 function getCollectionElementDomElement(collectionName, collectionElementIdentifier) {
664 if (collectionName === 'finishers') {
665 return $(getHelper().getDomElementDataAttribute(
666 'finisher',
667 'bracesWithKeyValue',
668 [collectionElementIdentifier]
669 ), getFinishersContainerDomElement());
670 } else {
671 return $(getHelper().getDomElementDataAttribute(
672 'validator',
673 'bracesWithKeyValue',
674 [collectionElementIdentifier]
675 ), getValidatorsContainerDomElement());
676 }
677 };
678
679 /**
680 * @public
681 *
682 * @param object
683 * @param function
684 * @return void
685 */
686 function renderEditors(formElement, callback) {
687 var formElementTypeDefinition;
688 if (getUtility().isUndefinedOrNull(formElement)) {
689 formElement = getCurrentlySelectedFormElement();
690 }
691
692 getInspectorDomElement().off().empty();
693
694 formElementTypeDefinition = getFormElementDefinition(formElement);
695 if ('array' !== $.type(formElementTypeDefinition['editors'])) {
696 return;
697 }
698
699 for (var i = 0, len = formElementTypeDefinition['editors'].length; i < len; ++i) {
700 var html, template;
701
702 template = getHelper()
703 .getTemplate(formElementTypeDefinition['editors'][i]['templateName'])
704 .clone();
705 if (!template.length) {
706 continue;
707 }
708 html = $(template.html());
709
710 $(html)
711 .first()
712 .addClass(getHelper().getDomElementClassName('inspectorEditor'));
713 getInspectorDomElement().append($(html));
714
715 _renderEditorDispatcher(formElementTypeDefinition['editors'][i], html);
716 }
717
718 if ('function' === $.type(callback)) {
719 callback();
720 }
721 };
722
723 /**
724 * @public
725 *
726 * @param string collectionName
727 * @param string collectionElementIdentifier
728 * @return void
729 * @publish view/inspector/collectionElements/dnd/update
730 * @throws 1478354853
731 * @throws 1478354854
732 */
733 function renderCollectionElementEditors(collectionName, collectionElementIdentifier) {
734 var collapseWrapper, collectionContainer, collectionContainerElementWrapper, collectionElementConfiguration, collectionElementEditorsLength;
735
736 assert(
737 getUtility().isNonEmptyString(collectionName),
738 'Invalid parameter "collectionName"',
739 1478354853
740 );
741 assert(
742 getUtility().isNonEmptyString(collectionElementIdentifier),
743 'Invalid parameter "collectionElementIdentifier"',
744 1478354854
745 );
746
747 collectionElementConfiguration = getFormEditorApp().getPropertyCollectionElementConfiguration(
748 collectionElementIdentifier,
749 collectionName
750 );
751 if ('array' !== $.type(collectionElementConfiguration['editors'])) {
752 return;
753 }
754
755 collectionContainerElementWrapper = $('<div></div>').
756 addClass(getHelper().getDomElementClassName('collectionElement'));
757 if (collectionName === 'finishers') {
758 collectionContainer = getFinishersContainerDomElement();
759 collectionContainerElementWrapper
760 .attr(getHelper().getDomElementDataAttribute('finisher'), collectionElementIdentifier);
761 } else {
762 collectionContainer = getValidatorsContainerDomElement();
763 collectionContainerElementWrapper
764 .attr(getHelper().getDomElementDataAttribute('validator'), collectionElementIdentifier);
765 }
766 collectionContainer.append(collectionContainerElementWrapper);
767
768 collectionElementEditorsLength = collectionElementConfiguration['editors'].length;
769 if (
770 collectionElementEditorsLength > 0
771 && collectionElementConfiguration['editors'][0]['identifier'] === 'header'
772 ) {
773 collapseWrapper = $('<div role="tabpanel"></div>')
774 .addClass('panel-collapse collapse')
775 .prop('id', _getCollectionElementId(
776 collectionName,
777 collectionElementIdentifier
778 ));
779 }
780
781 for (var i = 0; i < collectionElementEditorsLength; ++i) {
782 var html, template;
783
784 template = getHelper()
785 .getTemplate(collectionElementConfiguration['editors'][i]['templateName'])
786 .clone();
787 if (!template.length) {
788 continue;
789 }
790 html = $(template.html());
791
792 $(html).first()
793 .addClass(_getCollectionElementClass(
794 collectionName,
795 collectionElementConfiguration['editors'][i]['identifier']
796 ))
797 .addClass(getHelper().getDomElementClassName('inspectorEditor'));
798
799 if (i === 0 && collapseWrapper) {
800 getCollectionElementDomElement(collectionName, collectionElementIdentifier)
801 .append(html)
802 .append(collapseWrapper);
803 } else if (
804 i === (collectionElementEditorsLength - 1)
805 && collapseWrapper
806 && collectionElementConfiguration['editors'][i]['identifier'] === 'removeButton'
807 ) {
808 getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
809 } else if (i > 0 && collapseWrapper) {
810 collapseWrapper.append(html);
811 } else {
812 getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
813 }
814
815 _renderEditorDispatcher(
816 collectionElementConfiguration['editors'][i],
817 html,
818 collectionElementIdentifier,
819 collectionName
820 );
821 }
822
823 if (
824 collectionElementEditorsLength === 2
825 && collectionElementConfiguration['editors'][0]['identifier'] === 'header'
826 && collectionElementConfiguration['editors'][1]['identifier'] === 'removeButton'
827 ) {
828 $(getHelper().getDomElementDataIdentifierSelector('collapse'), collectionContainerElementWrapper).remove();
829 }
830
831 if (_configuration['isSortable']) {
832 _addSortableCollectionElementsEvents(collectionContainer, collectionName);
833 }
834 };
835
836 /**
837 * @public
838 *
839 * @string collectionName
840 * @param object editorConfiguration
841 * @param object editorHtml
842 * @return void
843 * @publish view/inspector/collectionElement/existing/selected
844 * @publish view/inspector/collectionElement/new/selected
845 * @throws 1475423098
846 * @throws 1475423099
847 * @throws 1475423100
848 * @throws 1475423101
849 * @throws 1478362968
850 */
851 function renderCollectionElementSelectionEditor(collectionName, editorConfiguration, editorHtml) {
852 var alreadySelectedCollectionElements, selectElement, collectionContainer;
853 assert(
854 getUtility().isNonEmptyString(collectionName),
855 'Invalid configuration "collectionName"',
856 1478362968
857 );
858 assert(
859 'object' === $.type(editorConfiguration),
860 'Invalid parameter "editorConfiguration"',
861 1475423098
862 );
863 assert(
864 'object' === $.type(editorHtml),
865 'Invalid parameter "editorHtml"',
866 1475423099
867 );
868 assert(
869 getUtility().isNonEmptyString(editorConfiguration['label']),
870 'Invalid configuration "label"',
871 1475423100
872 );
873 assert(
874 'array' === $.type(editorConfiguration['selectOptions']),
875 'Invalid configuration "selectOptions"',
876 1475423101
877 );
878
879 if (collectionName === 'finishers') {
880 collectionContainer = getFinishersContainerDomElement();
881 alreadySelectedCollectionElements = getRootFormElement().get(collectionName);
882 } else {
883 collectionContainer = getValidatorsContainerDomElement();
884 alreadySelectedCollectionElements = getCurrentlySelectedFormElement().get(collectionName);
885 }
886
887 collectionContainer.off().empty();
888
889 getHelper().getTemplatePropertyDomElement('label', editorHtml).text(editorConfiguration['label']);
890 selectElement = getHelper().getTemplatePropertyDomElement('selectOptions', editorHtml);
891
892 if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
893 for (var i = 0, len = alreadySelectedCollectionElements.length; i < len; ++i) {
894 getPublisherSubscriber().publish('view/inspector/collectionElement/existing/selected', [
895 alreadySelectedCollectionElements[i]['identifier'],
896 collectionName
897 ]);
898 }
899 }
900
901 for (var i = 0, len1 = editorConfiguration['selectOptions'].length; i < len1; ++i) {
902 var appendOption = true;
903 if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
904 for (var j = 0, len2 = alreadySelectedCollectionElements.length; j < len2; ++j) {
905 if (alreadySelectedCollectionElements[j]['identifier'] === editorConfiguration['selectOptions'][i]['value']) {
906 appendOption = false;
907 break;
908 }
909 }
910 }
911 if (appendOption) {
912 selectElement.append(new Option(
913 editorConfiguration['selectOptions'][i]['label'],
914 editorConfiguration['selectOptions'][i]['value']
915 ));
916 }
917 }
918
919 selectElement.on('change', function() {
920 if ($(this).val() !== '') {
921 var value = $(this).val();
922 $('option[value="' + value + '"]', $(this)).remove();
923
924 getFormEditorApp().getPublisherSubscriber().publish(
925 'view/inspector/collectionElement/new/selected',
926 [value, collectionName]
927 );
928 }
929 });
930 };
931
932 /**
933 * @public
934 *
935 * @param object editorConfiguration
936 * @param object editorHtml
937 * @param string collectionElementIdentifier
938 * @param string collectionName
939 * @return void
940 * @throws 1475421525
941 * @throws 1475421526
942 * @throws 1475421527
943 * @throws 1475421528
944 */
945 function renderFormElementHeaderEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
946 assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475421525);
947 assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475421526);
948
949 Icons.getIcon(
950 getFormElementDefinition(getCurrentlySelectedFormElement(), 'iconIdentifier'),
951 Icons.sizes.small,
952 null,
953 Icons.states.default
954 ).done(function(icon) {
955 getHelper().getTemplatePropertyDomElement('header-label', editorHtml)
956 .append($(icon).addClass(getHelper().getDomElementClassName('icon')))
957 .append(buildTitleByFormElement());
958 });
959 };
960
961 /**
962 * @public
963 *
964 * @param object editorConfiguration
965 * @param object editorHtml
966 * @param string collectionElementIdentifier
967 * @param string collectionName
968 * @return void
969 * @throws 1475421257
970 * @throws 1475421258
971 * @throws 1475421259
972 */
973 function renderCollectionElementHeaderEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
974 var collectionElementConfiguration, setData;
975
976 assert(
977 'object' === $.type(editorConfiguration),
978 'Invalid parameter "editorConfiguration"',
979 1475421258
980 );
981 assert(
982 getUtility().isNonEmptyString(editorConfiguration['label']),
983 'Invalid configuration "label"',
984 1475421257
985 );
986 assert(
987 'object' === $.type(editorHtml),
988 'Invalid parameter "editorHtml"',
989 1475421259
990 );
991
992 setData = function(icon) {
993 getHelper()
994 .getTemplatePropertyDomElement('header-label', editorHtml)
995 .prepend($(icon));
996
997 Icons.getIcon(
998 getHelper().getDomElementDataAttributeValue('collapse'),
999 Icons.sizes.small,
1000 null,
1001 Icons.states.default,
1002 Icons.markupIdentifiers.inline
1003 ).done(function(icon) {
1004 var iconWrap;
1005 iconWrap = $('<a></a>')
1006 .attr('href', _getCollectionElementId(collectionName, collectionElementIdentifier, true))
1007 .attr('data-toggle', 'collapse')
1008 .attr('aria-expanded', 'true')
1009 .attr('aria-controls', _getCollectionElementId(collectionName, collectionElementIdentifier))
1010 .addClass('collapsed')
1011 .append($(icon));
1012
1013 getHelper()
1014 .getTemplatePropertyDomElement('header-label', editorHtml)
1015 .prepend(iconWrap);
1016 });
1017 };
1018
1019 collectionElementConfiguration = getFormEditorApp().getFormEditorDefinition(collectionName, collectionElementIdentifier);
1020 if (collectionName === 'validators') {
1021 Icons.getIcon(
1022 collectionElementConfiguration['iconIdentifier'],
1023 Icons.sizes.small,
1024 null,
1025 Icons.states.default
1026 ).done(function(icon) {
1027 setData(icon);
1028 });
1029 } else {
1030 Icons.getIcon(
1031 collectionElementConfiguration['iconIdentifier'],
1032 Icons.sizes.small,
1033 null,
1034 Icons.states.default
1035 ).done(function(icon) {
1036 setData(icon);
1037 });
1038 }
1039
1040 if (editorConfiguration['label']) {
1041 getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
1042 }
1043 };
1044
1045 /**
1046 * @public
1047 *
1048 * @param object editorConfiguration
1049 * @param object editorHtml
1050 * @param string collectionElementIdentifier
1051 * @param string collectionName
1052 * @return void
1053 * @throws 1475421053
1054 * @throws 1475421054
1055 * @throws 1475421055
1056 * @throws 1475421056
1057 */
1058 function renderTextEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1059 var propertyData, propertyPath;
1060 assert(
1061 'object' === $.type(editorConfiguration),
1062 'Invalid parameter "editorConfiguration"',
1063 1475421053
1064 );
1065 assert(
1066 'object' === $.type(editorHtml),
1067 'Invalid parameter "editorHtml"',
1068 1475421054
1069 );
1070 assert(
1071 getUtility().isNonEmptyString(editorConfiguration['label']),
1072 'Invalid configuration "label"',
1073 1475421055
1074 );
1075 assert(
1076 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1077 'Invalid configuration "propertyPath"',
1078 1475421056
1079 );
1080
1081 getHelper()
1082 .getTemplatePropertyDomElement('label', editorHtml)
1083 .append(editorConfiguration['label']);
1084 if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
1085 getHelper()
1086 .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1087 .text(editorConfiguration['fieldExplanationText']);
1088 } else {
1089 getHelper()
1090 .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1091 .remove();
1092 }
1093
1094 propertyPath = getFormEditorApp().buildPropertyPath(
1095 editorConfiguration['propertyPath'],
1096 collectionElementIdentifier,
1097 collectionName
1098 );
1099 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1100
1101 _validateCollectionElement(propertyPath, editorHtml);
1102
1103 getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
1104
1105 renderFormElementSelectorEditorAddition(editorConfiguration, editorHtml, propertyPath);
1106
1107 getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function() {
1108 if (
1109 !!editorConfiguration['doNotSetIfPropertyValueIsEmpty']
1110 && !getUtility().isNonEmptyString($(this).val())
1111 ) {
1112 getCurrentlySelectedFormElement().unset(propertyPath);
1113 } else {
1114 getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
1115 }
1116 _validateCollectionElement(propertyPath, editorHtml);
1117 if (
1118 !getUtility().isUndefinedOrNull(editorConfiguration['additionalElementPropertyPaths'])
1119 && 'array' === $.type(editorConfiguration['additionalElementPropertyPaths'])
1120 ) {
1121 for (var i = 0, len = editorConfiguration['additionalElementPropertyPaths'].length; i < len; ++i) {
1122 if (
1123 !!editorConfiguration['doNotSetIfPropertyValueIsEmpty']
1124 && !getUtility().isNonEmptyString($(this).val())
1125 ) {
1126 getCurrentlySelectedFormElement().unset(editorConfiguration['additionalElementPropertyPaths'][i]);
1127 } else {
1128 getCurrentlySelectedFormElement().set(editorConfiguration['additionalElementPropertyPaths'][i], $(this).val());
1129 }
1130 }
1131 }
1132 });
1133 };
1134
1135 /**
1136 * @public
1137 *
1138 * @param object editorConfiguration
1139 * @param object editorHtml
1140 * @param string collectionElementIdentifier
1141 * @param string collectionName
1142 * @return void
1143 * @throws 1475421048
1144 * @throws 1475421049
1145 * @throws 1475421050
1146 * @throws 1475421051
1147 * @throws 1475421052
1148 */
1149 function renderSingleSelectEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1150 var propertyData, propertyPath, selectElement;
1151 assert(
1152 'object' === $.type(editorConfiguration),
1153 'Invalid parameter "editorConfiguration"',
1154 1475421048
1155 );
1156 assert(
1157 'object' === $.type(editorHtml),
1158 'Invalid parameter "editorHtml"',
1159 1475421049
1160 );
1161 assert(
1162 getUtility().isNonEmptyString(editorConfiguration['label']),
1163 'Invalid configuration "label"',
1164 1475421050
1165 );
1166 assert(
1167 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1168 'Invalid configuration "propertyPath"',
1169 1475421051
1170 );
1171 assert(
1172 'array' === $.type(editorConfiguration['selectOptions']),
1173 'Invalid configuration "selectOptions"',
1174 1475421052
1175 );
1176
1177 propertyPath = getFormEditorApp().buildPropertyPath(
1178 editorConfiguration['propertyPath'],
1179 collectionElementIdentifier,
1180 collectionName
1181 );
1182
1183 getHelper()
1184 .getTemplatePropertyDomElement('label', editorHtml)
1185 .append(editorConfiguration['label']);
1186
1187 selectElement = getHelper()
1188 .getTemplatePropertyDomElement('selectOptions', editorHtml);
1189
1190 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1191
1192 for (var i = 0, len = editorConfiguration['selectOptions'].length; i < len; ++i) {
1193 var option;
1194
1195 if (editorConfiguration['selectOptions'][i]['value'] === propertyData) {
1196 option = new Option(editorConfiguration['selectOptions'][i]['label'], i, false, true);
1197 } else {
1198 option = new Option(editorConfiguration['selectOptions'][i]['label'], i);
1199 }
1200 $(option).data({value: editorConfiguration['selectOptions'][i]['value']});
1201 selectElement.append(option);
1202 }
1203
1204 selectElement.on('change', function() {
1205 getCurrentlySelectedFormElement().set(propertyPath, $('option:selected', $(this)).data('value'));
1206 });
1207 };
1208
1209 /**
1210 * @public
1211 *
1212 * @param object editorConfiguration
1213 * @param object editorHtml
1214 * @param string collectionElementIdentifier
1215 * @param string collectionName
1216 * @return void
1217 * @throws 1485712399
1218 * @throws 1485712400
1219 * @throws 1485712401
1220 * @throws 1485712402
1221 * @throws 1485712403
1222 */
1223 function renderMultiSelectEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1224 var propertyData, propertyPath, selectElement;
1225 assert(
1226 'object' === $.type(editorConfiguration),
1227 'Invalid parameter "editorConfiguration"',
1228 1485712399
1229 );
1230 assert(
1231 'object' === $.type(editorHtml),
1232 'Invalid parameter "editorHtml"',
1233 1485712400
1234 );
1235 assert(
1236 getUtility().isNonEmptyString(editorConfiguration['label']),
1237 'Invalid configuration "label"',
1238 1485712401
1239 );
1240 assert(
1241 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1242 'Invalid configuration "propertyPath"',
1243 1485712402
1244 );
1245 assert(
1246 'array' === $.type(editorConfiguration['selectOptions']),
1247 'Invalid configuration "selectOptions"',
1248 1485712403
1249 );
1250
1251 propertyPath = getFormEditorApp().buildPropertyPath(
1252 editorConfiguration['propertyPath'],
1253 collectionElementIdentifier,
1254 collectionName
1255 );
1256
1257 getHelper()
1258 .getTemplatePropertyDomElement('label', editorHtml)
1259 .append(editorConfiguration['label']);
1260
1261 selectElement = getHelper()
1262 .getTemplatePropertyDomElement('selectOptions', editorHtml);
1263
1264 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1265
1266 for (var i = 0, len1 = editorConfiguration['selectOptions'].length; i < len1; ++i) {
1267 var option, value;
1268
1269 option = null;
1270 for (var propertyDataKey in propertyData) {
1271 if (!propertyData.hasOwnProperty(propertyDataKey)) {
1272 continue;
1273 }
1274 if (editorConfiguration['selectOptions'][i]['value'] === propertyData[propertyDataKey]) {
1275 option = new Option(editorConfiguration['selectOptions'][i]['label'], i, false, true);
1276 break;
1277 }
1278 }
1279
1280 if (!option) {
1281 option = new Option(editorConfiguration['selectOptions'][i]['label'], i);
1282 }
1283
1284 $(option).data({value: editorConfiguration['selectOptions'][i]['value']});
1285
1286 selectElement.append(option);
1287 }
1288
1289 selectElement.on('change', function() {
1290 var selectValues = [];
1291 $('option:selected', $(this)).each(function(i) {
1292 selectValues.push($(this).data('value'));
1293 });
1294
1295 getCurrentlySelectedFormElement().set(propertyPath, selectValues);
1296 });
1297 };
1298
1299 /**
1300 * @public
1301 *
1302 * @param object editorConfiguration
1303 * @param object editorHtml
1304 * @param string collectionElementIdentifier
1305 * @param string collectionName
1306 * @return void
1307 * @throws 1489528242
1308 * @throws 1489528243
1309 * @throws 1489528244
1310 * @throws 1489528245
1311 * @throws 1489528246
1312 * @throws 1489528247
1313 */
1314 function renderGridColumnViewPortConfigurationEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1315 var editorControlsWrapper, initNumbersOfColumnsField, numbersOfColumnsTemplate, selectElement, viewportButtonTemplate;
1316 assert(
1317 'object' === $.type(editorConfiguration),
1318 'Invalid parameter "editorConfiguration"',
1319 1489528242
1320 );
1321 assert(
1322 'object' === $.type(editorHtml),
1323 'Invalid parameter "editorHtml"',
1324 1489528243
1325 );
1326 assert(
1327 getUtility().isNonEmptyString(editorConfiguration['label']),
1328 'Invalid configuration "label"',
1329 1489528244
1330 );
1331 assert(
1332 'array' === $.type(editorConfiguration['configurationOptions']['viewPorts']),
1333 'Invalid configurationOptions "viewPorts"',
1334 1489528245
1335 );
1336 assert(
1337 !getUtility().isUndefinedOrNull(editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['label']),
1338 'Invalid configurationOptions "numbersOfColumnsToUse"',
1339 1489528246
1340 );
1341 assert(
1342 !getUtility().isUndefinedOrNull(editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['propertyPath']),
1343 'Invalid configuration "selectOptions"',
1344 1489528247
1345 );
1346
1347 if (!getFormElementDefinition(getCurrentlySelectedFormElement().get('__parentRenderable'), '_isGridRowFormElement')) {
1348 editorHtml.remove();
1349 return;
1350 }
1351
1352 getHelper()
1353 .getTemplatePropertyDomElement('label', editorHtml)
1354 .append(editorConfiguration['label']);
1355
1356
1357 viewportButtonTemplate = $(getHelper()
1358 .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
1359 .clone();
1360
1361 $(getHelper()
1362 .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
1363 .remove();
1364
1365 numbersOfColumnsTemplate = getHelper()
1366 .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
1367 .clone();
1368
1369 getHelper()
1370 .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
1371 .remove();
1372
1373 editorControlsWrapper = _getEditorControlsWrapperDomElement(editorHtml);
1374
1375 initNumbersOfColumnsField = function(element) {
1376 var numbersOfColumnsTemplateClone, propertyPath;
1377
1378 getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
1379 .off()
1380 .empty()
1381 .remove();
1382
1383 numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
1384 _getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
1385
1386 $('input', numbersOfColumnsTemplateClone).focus();
1387
1388 getHelper()
1389 .getTemplatePropertyDomElement('numbersOfColumnsToUse-label', numbersOfColumnsTemplateClone)
1390 .append(
1391 editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['label']
1392 .replace('{@viewPortLabel}', element.data('viewPortLabel'))
1393 );
1394
1395 getHelper()
1396 .getTemplatePropertyDomElement('numbersOfColumnsToUse-fieldExplanationText', numbersOfColumnsTemplateClone)
1397 .append(editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['fieldExplanationText']);
1398
1399 propertyPath = editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['propertyPath']
1400 .replace('{@viewPortIdentifier}', element.data('viewPortIdentifier'));
1401
1402 getHelper()
1403 .getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone)
1404 .val(getCurrentlySelectedFormElement().get(propertyPath));
1405
1406 getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone).on('keyup paste change', function() {
1407 var that = $(this);
1408 if (!$.isNumeric(that.val())) {
1409 that.val('');
1410 } else {
1411 getCurrentlySelectedFormElement().set(propertyPath, that.val());
1412 }
1413 });
1414 };
1415
1416 for (var i = 0, len = editorConfiguration['configurationOptions']['viewPorts'].length; i < len; ++i) {
1417 var numbersOfColumnsTemplateClone, viewportButtonTemplateClone, viewPortIdentifier, viewPortLabel;
1418
1419 viewPortIdentifier = editorConfiguration['configurationOptions']['viewPorts'][i]['viewPortIdentifier'];
1420 viewPortLabel = editorConfiguration['configurationOptions']['viewPorts'][i]['label'];
1421
1422 viewportButtonTemplateClone = $(viewportButtonTemplate).clone(true, true);
1423 viewportButtonTemplateClone.text(viewPortLabel);
1424 viewportButtonTemplateClone.data('viewPortIdentifier', viewPortIdentifier);
1425 viewportButtonTemplateClone.data('viewPortLabel', viewPortLabel);
1426 editorControlsWrapper.append(viewportButtonTemplateClone);
1427
1428 if (i === (len - 1)) {
1429 numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
1430 _getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
1431 initNumbersOfColumnsField(viewportButtonTemplateClone);
1432 viewportButtonTemplateClone.addClass(getHelper().getDomElementClassName('active'));
1433 }
1434
1435 $('button', editorControlsWrapper).on('click', function() {
1436 var that = $(this);
1437
1438 $('button', editorControlsWrapper).removeClass(getHelper().getDomElementClassName('active'));
1439 that.addClass(getHelper().getDomElementClassName('active'));
1440
1441 initNumbersOfColumnsField(that);
1442 });
1443 }
1444 };
1445
1446 /**
1447 * @public
1448 *
1449 * @param object editorConfiguration
1450 * @param object editorHtml
1451 * @param string collectionElementIdentifier
1452 * @param string collectionName
1453 * @return void
1454 * @throws 1475419226
1455 * @throws 1475419227
1456 * @throws 1475419228
1457 * @throws 1475419229
1458 * @throws 1475419230
1459 * @throws 1475419231
1460 * @throws 1475419232
1461 */
1462 function renderPropertyGridEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1463 var addRowTemplate, defaultValue, multiSelection, propertyData, propertyPathPrefix, rowItemTemplate, setData;
1464 assert(
1465 'object' === $.type(editorConfiguration),
1466 'Invalid parameter "editorConfiguration"',
1467 1475419226
1468 );
1469 assert(
1470 'object' === $.type(editorHtml),
1471 'Invalid parameter "editorHtml"',
1472 1475419227
1473 );
1474 assert(
1475 'boolean' === $.type(editorConfiguration['enableAddRow']),
1476 'Invalid configuration "enableAddRow"',
1477 1475419228
1478 );
1479 assert(
1480 'boolean' === $.type(editorConfiguration['enableDeleteRow']),
1481 'Invalid configuration "enableDeleteRow"',
1482 1475419230
1483 );
1484 assert(
1485 'boolean' === $.type(editorConfiguration['isSortable']),
1486 'Invalid configuration "isSortable"',
1487 1475419229
1488 );
1489 assert(
1490 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1491 'Invalid configuration "propertyPath"',
1492 1475419231
1493 );
1494 assert(
1495 getUtility().isNonEmptyString(editorConfiguration['label']),
1496 'Invalid configuration "label"',
1497 1475419232
1498 );
1499
1500 getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
1501 propertyPathPrefix = getFormEditorApp().buildPropertyPath(
1502 undefined,
1503 collectionElementIdentifier,
1504 collectionName,
1505 undefined,
1506 true
1507 );
1508 if (getUtility().isNonEmptyString(propertyPathPrefix)) {
1509 propertyPathPrefix = propertyPathPrefix + '.';
1510 }
1511
1512 if (getUtility().isUndefinedOrNull(editorConfiguration['multiSelection'])) {
1513 multiSelection = false;
1514 } else {
1515 multiSelection = !!editorConfiguration['multiSelection'];
1516 }
1517
1518 rowItemTemplate = $(
1519 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
1520 $(editorHtml)
1521 ).clone();
1522 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'), $(editorHtml)).remove();
1523
1524 if (!!editorConfiguration['enableDeleteRow']) {
1525 $( getHelper().getDomElementDataIdentifierSelector('propertyGridEditorDeleteRow'),
1526 $(rowItemTemplate)
1527 ).on('click', function() {
1528 if ($(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'), $(editorHtml)).length > 1) {
1529 $(this)
1530 .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
1531 .off()
1532 .empty()
1533 .remove();
1534
1535 _setPropertyGridData(
1536 $(editorHtml),
1537 multiSelection,
1538 editorConfiguration['propertyPath'],
1539 propertyPathPrefix
1540 );
1541 } else {
1542 Notification.error(
1543 editorConfiguration['removeLastAvailableRowFlashMessageTitle'],
1544 editorConfiguration['removeLastAvailableRowFlashMessageMessage'],
1545 2
1546 );
1547 }
1548 });
1549 } else {
1550 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorDeleteRow'), $(rowItemTemplate))
1551 .parent()
1552 .off()
1553 .empty();
1554 }
1555
1556 if (!!editorConfiguration['isSortable']) {
1557 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
1558 .addClass(getHelper().getDomElementClassName('sortable'))
1559 .sortable({
1560 revert: 'true',
1561 items: getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
1562 update: function(e, o) {
1563 _setPropertyGridData($(editorHtml), multiSelection, editorConfiguration['propertyPath'], propertyPathPrefix);
1564 }
1565 });
1566 } else {
1567 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSortRow'), $(rowItemTemplate))
1568 .parent()
1569 .off()
1570 .empty();
1571 }
1572
1573 $( getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue'),
1574 $(rowItemTemplate)
1575 ).on('change', function() {
1576 if (!multiSelection) {
1577 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked', $(editorHtml))
1578 .not($(this))
1579 .prop('checked', false);
1580 }
1581 _setPropertyGridData($(editorHtml), multiSelection, editorConfiguration['propertyPath'], propertyPathPrefix);
1582 });
1583
1584 $( getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel') + ',' +
1585 getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'),
1586 $(rowItemTemplate)
1587 ).on('keyup paste', function() {
1588 _setPropertyGridData($(editorHtml), multiSelection, editorConfiguration['propertyPath'], propertyPathPrefix);
1589 });
1590
1591 $( getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'),
1592 $(rowItemTemplate)
1593 ).on('focusout', function() {
1594 if ('' === $(this)
1595 .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
1596 .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
1597 .val()
1598 ) {
1599 $(this)
1600 .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
1601 .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
1602 .val($(this).val());
1603 }
1604 });
1605
1606 if (!!editorConfiguration['enableAddRow']) {
1607 addRowTemplate = $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).clone();
1608 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).remove();
1609
1610 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRow'), $(addRowTemplate)).on('click', function() {
1611 $(this)
1612 .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'))
1613 .before($(rowItemTemplate).clone(true, true));
1614 });
1615 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
1616 .prepend($(addRowTemplate).clone(true, true));
1617 } else {
1618 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).remove();
1619 }
1620
1621 defaultValue = {};
1622 if (multiSelection) {
1623 if (!getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue'))) {
1624 defaultValue = getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue');
1625 }
1626 } else {
1627 if (!getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue'))) {
1628 defaultValue = {0: getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue')};
1629 }
1630 }
1631 propertyData = getCurrentlySelectedFormElement().get(propertyPathPrefix + editorConfiguration['propertyPath']) || {};
1632
1633 setData = function(label, value) {
1634 var isPreselected, newRowTemplate;
1635
1636 isPreselected = false;
1637 newRowTemplate = $(rowItemTemplate).clone(true, true);
1638
1639 for (var defaultValueKey in defaultValue) {
1640 if (!defaultValue.hasOwnProperty(defaultValueKey)) {
1641 continue;
1642 }
1643 if (defaultValue[defaultValueKey] === value) {
1644 isPreselected = true;
1645 break;
1646 }
1647 }
1648
1649 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'), $(newRowTemplate)).val(label);
1650 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'), $(newRowTemplate)).val(value);
1651 if (isPreselected) {
1652 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue'), $(newRowTemplate))
1653 .prop('checked', true);
1654 }
1655
1656 if (!!editorConfiguration['enableAddRow']) {
1657 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml))
1658 .before($(newRowTemplate));
1659 } else {
1660 $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
1661 .prepend($(newRowTemplate));
1662 }
1663 };
1664
1665 if ('object' === $.type(propertyData)) {
1666 for (var propertyDataKey in propertyData) {
1667 if (!propertyData.hasOwnProperty(propertyDataKey)) {
1668 continue;
1669 }
1670 setData(propertyData[propertyDataKey], propertyDataKey);
1671 }
1672 } else if ('array' === $.type(propertyData)) {
1673 for (var propertyDataKey in propertyData) {
1674 if (!propertyData.hasOwnProperty(propertyDataKey)) {
1675 continue;
1676 }
1677 if (getUtility().isUndefinedOrNull(propertyData[propertyDataKey]['_label'])) {
1678 setData(propertyData[propertyDataKey], propertyDataKey);
1679 } else {
1680 setData(propertyData[propertyDataKey]['_label'], propertyData[propertyDataKey]['_value']);
1681 }
1682 }
1683 }
1684 };
1685
1686 /**
1687 * @public
1688 *
1689 * @param object editorConfiguration
1690 * @param object editorHtml
1691 * @param string collectionElementIdentifier
1692 * @param string collectionName
1693 * @return void
1694 * @publish view/inspector/collectionElement/new/selected
1695 * @publish view/inspector/removeCollectionElement/perform
1696 * @throws 1475417093
1697 * @throws 1475417094
1698 * @throws 1475417095
1699 * @throws 1475417096
1700 */
1701 function renderRequiredValidatorEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1702 var propertyPath, propertyValue, validatorIdentifier;
1703 assert(
1704 'object' === $.type(editorConfiguration),
1705 'Invalid parameter "editorConfiguration"',
1706 1475417093
1707 );
1708 assert(
1709 'object' === $.type(editorHtml),
1710 'Invalid parameter "editorHtml"',
1711 1475417094
1712 );
1713 assert(
1714 getUtility().isNonEmptyString(editorConfiguration['validatorIdentifier']),
1715 'Invalid configuration "validatorIdentifier"',
1716 1475417095
1717 );
1718 assert(
1719 getUtility().isNonEmptyString(editorConfiguration['label']),
1720 'Invalid configuration "label"',
1721 1475417096
1722 );
1723
1724 validatorIdentifier = editorConfiguration['validatorIdentifier'];
1725 getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
1726
1727 if (getUtility().isNonEmptyString(editorConfiguration['propertyPath'])) {
1728 propertyPath = getFormEditorApp()
1729 .buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
1730 }
1731 if (getUtility().isNonEmptyString(editorConfiguration['propertyValue'])) {
1732 propertyValue = editorConfiguration['propertyValue'];
1733 } else {
1734 propertyValue = '';
1735 }
1736
1737 if (-1 !== getFormEditorApp().getIndexFromPropertyCollectionElement(validatorIdentifier, 'validators')) {
1738 $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
1739 if (getUtility().isNonEmptyString(propertyPath)) {
1740 getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
1741 }
1742 }
1743
1744 $('input[type="checkbox"]', $(editorHtml)).on('change', function() {
1745 if ($(this).is(":checked")) {
1746 getPublisherSubscriber().publish(
1747 'view/inspector/collectionElement/new/selected',
1748 [validatorIdentifier, 'validators']
1749 );
1750
1751 if (getUtility().isNonEmptyString(propertyPath)) {
1752 getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
1753 }
1754 } else {
1755 getPublisherSubscriber().publish(
1756 'view/inspector/removeCollectionElement/perform',
1757 [validatorIdentifier, 'validators']
1758 );
1759 if (getUtility().isNonEmptyString(propertyPath)) {
1760 getCurrentlySelectedFormElement().unset(propertyPath);
1761 }
1762 }
1763 });
1764 };
1765
1766 /**
1767 * @public
1768 *
1769 * @param object editorConfiguration
1770 * @param object editorHtml
1771 * @param string collectionElementIdentifier
1772 * @param string collectionName
1773 * @return void
1774 * @throws 1476218671
1775 * @throws 1476218672
1776 * @throws 1476218673
1777 * @throws 1476218674
1778 */
1779 function renderCheckboxEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1780 var propertyData, propertyPath;
1781 assert(
1782 'object' === $.type(editorConfiguration),
1783 'Invalid parameter "editorConfiguration"',
1784 1476218671
1785 );
1786 assert(
1787 'object' === $.type(editorHtml),
1788 'Invalid parameter "editorHtml"',
1789 1476218672
1790 );
1791 assert(
1792 getUtility().isNonEmptyString(editorConfiguration['label']),
1793 'Invalid configuration "label"',
1794 1476218673
1795 );
1796 assert(
1797 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1798 'Invalid configuration "propertyPath"',
1799 1476218674
1800 );
1801
1802 getHelper()
1803 .getTemplatePropertyDomElement('label', editorHtml)
1804 .append(editorConfiguration['label']);
1805
1806 propertyPath = getFormEditorApp()
1807 .buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
1808 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1809
1810 if (
1811 ('boolean' === $.type(propertyData) && propertyData)
1812 || propertyData === 'true'
1813 || propertyData === 1
1814 || propertyData === "1"
1815 ) {
1816 $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
1817 }
1818
1819 $('input[type="checkbox"]', $(editorHtml)).on('change', function() {
1820 if ($(this).is(":checked")) {
1821 getCurrentlySelectedFormElement().set(propertyPath, true);
1822 } else {
1823 getCurrentlySelectedFormElement().set(propertyPath, false);
1824 }
1825 });
1826 };
1827
1828 /**
1829 * @public
1830 *
1831 * @param object editorConfiguration
1832 * @param object editorHtml
1833 * @param string collectionElementIdentifier
1834 * @param string collectionName
1835 * @return void
1836 * @throws 1475412567
1837 * @throws 1475412568
1838 * @throws 1475416098
1839 * @throws 1475416099
1840 */
1841 function renderTextareaEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1842 var propertyPath, propertyData;
1843 assert(
1844 'object' === $.type(editorConfiguration),
1845 'Invalid parameter "editorConfiguration"',
1846 1475412567
1847 );
1848 assert(
1849 'object' === $.type(editorHtml),
1850 'Invalid parameter "editorHtml"',
1851 1475412568
1852 );
1853 assert(
1854 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1855 'Invalid configuration "propertyPath"',
1856 1475416098
1857 );
1858 assert(
1859 getUtility().isNonEmptyString(editorConfiguration['label']),
1860 'Invalid configuration "label"',
1861 1475416099
1862 );
1863
1864 propertyPath = getFormEditorApp()
1865 .buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
1866
1867 getHelper()
1868 .getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
1869
1870 if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
1871 getHelper()
1872 .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1873 .text(editorConfiguration['fieldExplanationText']);
1874 } else {
1875 getHelper()
1876 .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1877 .remove();
1878 }
1879
1880 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1881 $('textarea', $(editorHtml)).val(propertyData);
1882
1883 $('textarea', $(editorHtml)).on('keyup paste', function() {
1884 getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
1885 });
1886 };
1887
1888 /**
1889 * @public
1890 *
1891 * @param object editorConfiguration
1892 * @param object editorHtml
1893 * @param string collectionElementIdentifier
1894 * @param string collectionName
1895 * @return void
1896 * @throws 1477300587
1897 * @throws 1477300588
1898 * @throws 1477300589
1899 * @throws 1477300590
1900 * @throws 1477318981
1901 * @throws 1477319859
1902 */
1903 function renderTypo3WinBrowserEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
1904 var iconType, propertyPath, propertyData;
1905 assert(
1906 'object' === $.type(editorConfiguration),
1907 'Invalid parameter "editorConfiguration"',
1908 1477300587
1909 );
1910 assert(
1911 'object' === $.type(editorHtml),
1912 'Invalid parameter "editorHtml"',
1913 1477300588
1914 );
1915 assert(
1916 getUtility().isNonEmptyString(editorConfiguration['label']),
1917 'Invalid configuration "label"',
1918 1477300589
1919 );
1920 assert(
1921 getUtility().isNonEmptyString(editorConfiguration['buttonLabel']),
1922 'Invalid configuration "buttonLabel"',
1923 1477318981
1924 );
1925 assert(
1926 getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
1927 'Invalid configuration "propertyPath"',
1928 1477300590
1929 );
1930 assert(
1931 'tt_content' === editorConfiguration['browsableType'] || 'pages' === editorConfiguration['browsableType'],
1932 'Invalid configuration "browsableType"',
1933 1477319859
1934 );
1935
1936 getHelper()
1937 .getTemplatePropertyDomElement('label', editorHtml)
1938 .append(editorConfiguration['label']);
1939 getHelper()
1940 .getTemplatePropertyDomElement('buttonLabel', editorHtml)
1941 .append(editorConfiguration['buttonLabel']);
1942
1943 if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
1944 getHelper()
1945 .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1946 .text(editorConfiguration['fieldExplanationText']);
1947 } else {
1948 getHelper()
1949 .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1950 .remove();
1951 }
1952
1953 $('form', $(editorHtml)).prop('name', editorConfiguration['propertyPath']);
1954
1955 iconType = ('tt_content' === editorConfiguration['browsableType'])
1956 ? getHelper().getDomElementDataAttributeValue('iconTtContent')
1957 : getHelper().getDomElementDataAttributeValue('iconPage');
1958 Icons.getIcon(iconType, Icons.sizes.small).done(function(icon) {
1959 getHelper().getTemplatePropertyDomElement('image', editorHtml).append($(icon));
1960 });
1961
1962 getHelper().getTemplatePropertyDomElement('onclick', editorHtml).on('click', function() {
1963 var insertTarget, randomIdentifier;
1964
1965 randomIdentifier = Math.floor((Math.random() * 100000) + 1);
1966 insertTarget = $(this)
1967 .closest(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'))
1968 .find(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKey'));
1969
1970 insertTarget.attr(getHelper().getDomElementDataAttribute('contentElementSelectorTarget'), randomIdentifier);
1971 _openTypo3WinBrowser('db', randomIdentifier + '|||' + editorConfiguration['browsableType']);
1972 });
1973
1974 propertyPath = getFormEditorApp().buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
1975 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1976
1977 _validateCollectionElement(propertyPath, editorHtml);
1978 getHelper()
1979 .getTemplatePropertyDomElement('propertyPath', editorHtml)
1980 .val(propertyData);
1981
1982 getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function() {
1983 getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
1984 _validateCollectionElement(propertyPath, editorHtml);
1985 });
1986 };
1987
1988 /**
1989 * @public
1990 *
1991 * @param object editorConfiguration
1992 * @param object editorHtml
1993 * @param string collectionElementIdentifier
1994 * @param string collectionName
1995 * @return void
1996 * @throws 1475412563
1997 * @throws 1475412564
1998 */
1999 function renderRemoveElementEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
2000 assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475412563);
2001 assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475412564);
2002
2003 if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
2004
2005 $('button', $(editorHtml))
2006 .addClass(
2007 getHelper().getDomElementClassName('buttonFormElementRemove') + ' ' +
2008 getHelper().getDomElementClassName('buttonFormEditor')
2009 );
2010 } else {
2011 $('button', $(editorHtml)).addClass(
2012 getHelper().getDomElementClassName('buttonCollectionElementRemove')
2013 );
2014 }
2015
2016 $('button', $(editorHtml)).on('click', function(e) {
2017 if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
2018 getViewModel().showRemoveFormElementModal();
2019 } else {
2020 getViewModel().showRemoveCollectionElementModal(collectionElementIdentifier, collectionName);
2021 }
2022 });
2023 };
2024
2025 /**
2026 * @public
2027 *
2028 * @param object editorConfiguration
2029 * @param object editorHtml
2030 * @param string propertyPath
2031 * @return void
2032 * @throws 1484574704
2033 * @throws 1484574705
2034 * @throws 1484574706
2035 */
2036 function renderFormElementSelectorEditorAddition(editorConfiguration, editorHtml, propertyPath) {
2037 var nonCompositeNonToplevelFormElements, formElementSelectorControlsWrapper, formElementSelectorSplitButtonListContainer, itemTemplate;
2038
2039 assert(
2040 'object' === $.type(editorConfiguration),
2041 'Invalid parameter "editorConfiguration"',
2042 1484574704
2043 );
2044 assert(
2045 'object' === $.type(editorHtml),
2046 'Invalid parameter "editorHtml"',
2047 1484574705
2048 );
2049 assert(
2050 getUtility().isNonEmptyString(propertyPath),
2051 'Invalid parameter "propertyPath"',
2052 1484574706
2053 );
2054
2055 formElementSelectorControlsWrapper = $(
2056 getHelper().getDomElementDataIdentifierSelector('formElementSelectorControlsWrapper'), editorHtml
2057 );
2058
2059 if (editorConfiguration['enableFormelementSelectionButton'] === true) {
2060 if (formElementSelectorControlsWrapper.length === 0) {
2061 return;
2062 }
2063
2064 formElementSelectorSplitButtonListContainer = $(
2065 getHelper().getDomElementDataIdentifierSelector('formElementSelectorSplitButtonListContainer'), editorHtml
2066 );
2067
2068 formElementSelectorSplitButtonListContainer.off().empty();
2069 nonCompositeNonToplevelFormElements = getFormEditorApp().getNonCompositeNonToplevelFormElements();
2070
2071 if (nonCompositeNonToplevelFormElements.length === 0) {
2072 Icons.getIcon(
2073 getHelper().getDomElementDataAttributeValue('iconNotAvailable'),
2074 Icons.sizes.small,
2075 null,
2076 Icons.states.default
2077 ).done(function(icon) {
2078 itemTemplate = $('<li data-no-sorting>'
2079 + '<a href="#"></a>'
2080 + '</li>');
2081
2082 itemTemplate
2083 .append($(icon))
2084 .append(' ' + getFormElementDefinition(getRootFormElement(), 'inspectorEditorFormElementSelectorNoElements'));
2085 formElementSelectorSplitButtonListContainer.append(itemTemplate);
2086 });
2087 } else {
2088 for (var i = 0, len = nonCompositeNonToplevelFormElements.length; i < len; ++i) {
2089 var nonCompositeNonToplevelFormElement;
2090
2091 nonCompositeNonToplevelFormElement = nonCompositeNonToplevelFormElements[i];
2092 Icons.getIcon(
2093 getFormElementDefinition(nonCompositeNonToplevelFormElement, 'iconIdentifier'),
2094 Icons.sizes.small,
2095 null,
2096 Icons.states.default
2097 ).done(function(icon) {
2098 itemTemplate = $('<li data-no-sorting>'
2099 + '<a href="#" data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '">'
2100 + '</a>'
2101 + '</li>');
2102
2103 $('[data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '"]', itemTemplate)
2104 .append($(icon))
2105 .append(' ' + nonCompositeNonToplevelFormElement.get('label'));
2106
2107 $('a', itemTemplate).on('click', function() {
2108 var propertyData;
2109
2110 propertyData = getCurrentlySelectedFormElement().get(propertyPath);
2111
2112 if (propertyData.length === 0) {
2113 propertyData = '{' + $(this).attr('data-formelement-identifier') + '}';
2114 } else {
2115 propertyData = propertyData + ' ' + '{' + $(this).attr('data-formelement-identifier') + '}';
2116 }
2117
2118 getCurrentlySelectedFormElement().set(propertyPath, propertyData);
2119 getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
2120 _validateCollectionElement(propertyPath, editorHtml);
2121 });
2122
2123 formElementSelectorSplitButtonListContainer.append(itemTemplate);
2124 });
2125 }
2126 }
2127 } else {
2128 $(getHelper().getDomElementDataIdentifierSelector('editorControlsInputGroup'), editorHtml)
2129 .removeClass(getHelper().getDomElementClassName('inspectorInputGroup'));
2130 formElementSelectorControlsWrapper.off().empty().remove();
2131 }
2132 }
2133
2134 /**
2135 * @public
2136 *
2137 * @param string content
2138 * @return void
2139 */
2140 function setFormElementHeaderEditorContent(content) {
2141 if (getFormEditorApp().getUtility().isUndefinedOrNull(content)) {
2142 content = buildTitleByFormElement();
2143 }
2144
2145 $(getHelper()
2146 .getDomElementDataIdentifierSelector('formElementHeaderEditor'), getInspectorDomElement())
2147 .html(content);
2148 };
2149
2150 /**
2151 * @public
2152 *
2153 * @param object
2154 * @return object
2155 * @throws 1478967319
2156 */
2157 function buildTitleByFormElement(formElement) {
2158 var label;
2159 if (getUtility().isUndefinedOrNull(formElement)) {
2160 formElement = getCurrentlySelectedFormElement();
2161 }
2162 assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478967319);
2163
2164 return $('<span></span>').text((formElement.get('label')
2165 ? formElement.get('label')
2166 : formElement.get('identifier')));
2167 };
2168
2169 /**
2170 * @public
2171 *
2172 * @param object
2173 * @param object
2174 * @return this
2175 */
2176 function bootstrap(formEditorApp, configuration) {
2177 _formEditorApp = formEditorApp;
2178 _configuration = $.extend(true, _defaultConfiguration, configuration || {});
2179 _helperSetup();
2180 return this;
2181 };
2182
2183 /**
2184 * Publish the public methods.
2185 * Implements the "Revealing Module Pattern".
2186 */
2187 return {
2188 bootstrap: bootstrap,
2189 buildTitleByFormElement: buildTitleByFormElement,
2190 getCollectionElementDomElement: getCollectionElementDomElement,
2191 getFinishersContainerDomElement: getFinishersContainerDomElement,
2192 getInspectorDomElement: getInspectorDomElement,
2193 getValidatorsContainerDomElement: getValidatorsContainerDomElement,
2194 renderCheckboxEditor: renderCheckboxEditor,
2195 renderCollectionElementEditors: renderCollectionElementEditors,
2196 renderCollectionElementHeaderEditor: renderCollectionElementHeaderEditor,
2197 renderCollectionElementSelectionEditor: renderCollectionElementSelectionEditor,
2198 renderEditors: renderEditors,
2199 renderFormElementHeaderEditor: renderFormElementHeaderEditor,
2200 renderFormElementSelectorEditorAddition: renderFormElementSelectorEditorAddition,
2201 renderPropertyGridEditor: renderPropertyGridEditor,
2202 renderRemoveElementEditor: renderRemoveElementEditor,
2203 renderRequiredValidatorEditor: renderRequiredValidatorEditor,
2204 renderSingleSelectEditor: renderSingleSelectEditor,
2205 renderMultiSelectEditor: renderMultiSelectEditor,
2206 renderTextareaEditor: renderTextareaEditor,
2207 renderTextEditor: renderTextEditor,
2208 renderTypo3WinBrowserEditor: renderTypo3WinBrowserEditor,
2209 setFormElementHeaderEditorContent: setFormElementHeaderEditorContent
2210 };
2211 })($, Helper, Icons, Notification);
2212 });