c162a21bfd3a2657db9a3ca13d3884ff01d0ee75
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Resources / Public / JavaScript / Backend / FormEditor / ViewModel.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/ViewModel
16 */
17 define(['jquery',
18 'TYPO3/CMS/Form/Backend/FormEditor/TreeComponent',
19 'TYPO3/CMS/Form/Backend/FormEditor/ModalsComponent',
20 'TYPO3/CMS/Form/Backend/FormEditor/InspectorComponent',
21 'TYPO3/CMS/Form/Backend/FormEditor/StageComponent',
22 'TYPO3/CMS/Form/Backend/FormEditor/Helper',
23 'TYPO3/CMS/Backend/Icons',
24 'TYPO3/CMS/Backend/Notification'
25 ], function($, TreeComponent, ModalsComponent, InspectorComponent, StageComponent, Helper, Icons, Notification) {
26 'use strict';
27
28 return (function($, TreeComponent, ModalsComponent, InspectorComponent, StageComponent, Helper, Icons, Notification) {
29
30 /**
31 * @private
32 *
33 * @var object
34 */
35 var _configuration = {
36 domElementClassNames: {
37 formElementIsComposit: 't3-form-element-composit',
38 formElementIsTopLevel: 't3-form-element-toplevel',
39 hasError: 'has-error',
40 headerButtonBar: 'module-docheader-bar-column-left',
41 selectedCompositFormElement: 't3-form-form-composit-element-selected',
42 selectedFormElement: 't3-form-form-element-selected',
43 selectedRootFormElement: 't3-form-root-element-selected',
44 selectedStagePanel: 't3-form-form-stage-selected',
45 sortableHover: 'sortable-hover',
46 stageViewModeAbstract: 't3-form-stage-viewmode-abstract',
47 stageViewModePreview: 't3-form-stage-viewmode-preview',
48 validationErrors: 't3-form-validation-errors',
49 validationChildHasErrors: 't3-form-validation-child-has-error'
50 },
51 domElementDataAttributeNames: {
52 abstractType: 'data-element-abstract-type'
53 },
54 domElementDataAttributeValues: {
55 buttonHeaderClose: 'closeButton',
56 buttonHeaderNewPage: 'headerNewPage',
57 buttonHeaderPaginationNext: 'buttonPaginationNext',
58 buttonHeaderPaginationPrevious: 'buttonPaginationPrevious',
59 buttonHeaderRedo: 'redoButton',
60 buttonHeaderSave: 'saveButton',
61 buttonHeaderSettings: 'formSettingsButton',
62 buttonHeaderUndo: 'undoButton',
63 buttonHeaderViewModeAbstract: 'buttonViewModeAbstract',
64 buttonHeaderViewModePreview: 'buttonViewModePreview',
65 buttonStageNewElementBottom: 'stageNewElementBottom',
66 buttonStructureNewPage: 'treeNewPageBottom',
67 iconMailform: 'content-elements-mailform',
68 iconSave: 'actions-document-save',
69 iconSaveSpinner: 'spinner-circle-dark',
70 inspectorSection: 'inspectorSection',
71 moduleLoadingIndicator: 'moduleLoadingIndicator',
72 moduleWrapper: 'moduleWrapper',
73 stageArea: 'stageArea',
74 stageContainer: 'stageContainer',
75 stageNewElementRow: 'stageNewElementRow',
76 stagePanelHeading: 'panelHeading',
77 stageSection: 'stageSection',
78 structure: 'structure-element',
79 structureSection: 'structureSection',
80 structureRootContainer: 'treeRootContainer',
81 structureRootElement: 'treeRootElement'
82 },
83 panels: {
84 structure: {
85 width: 300
86 },
87 stage: {
88 marginLeft: 300,
89 marginRight: 325,
90 marginLeftCollapsed: 0,
91 marginRightCollapsed: -25
92 },
93 inspector: {
94 width: 350
95 }
96 }
97 };
98
99 /**
100 * @private
101 *
102 * @var bool
103 */
104 var _previewMode = false;
105
106 /**
107 * @private
108 *
109 * @var object
110 */
111 var _formEditorApp = null;
112
113 /**
114 * @private
115 *
116 * @var object
117 */
118 var _structureComponent = null;
119
120 /**
121 * @private
122 *
123 * @var object
124 */
125 var _modalsComponent = null;
126
127 /**
128 * @private
129 *
130 * @var object
131 */
132 var _inspectorsComponent = null;
133
134 /**
135 * @private
136 *
137 * @var object
138 */
139 var _stageComponent = null;
140
141 /* *************************************************************
142 * Private Methodes
143 * ************************************************************/
144
145 /**
146 * @private
147 *
148 * @return object
149 */
150 function getRootFormElement() {
151 return getFormEditorApp().getRootFormElement();
152 };
153
154 /**
155 * @private
156 *
157 * @param mixed test
158 * @param string message
159 * @param int messageCode
160 * @return void
161 */
162 function assert(test, message, messageCode) {
163 return getFormEditorApp().assert(test, message, messageCode);
164 };
165
166 /**
167 * @private
168 *
169 * @return object
170 */
171 function getUtility() {
172 return getFormEditorApp().getUtility();
173 };
174
175 /**
176 * @private
177 *
178 * @return object
179 */
180 function getCurrentlySelectedFormElement() {
181 return getFormEditorApp().getCurrentlySelectedFormElement();
182 };
183
184
185 /**
186 * @private
187 *
188 * @return object
189 */
190 function getPublisherSubscriber() {
191 return getFormEditorApp().getPublisherSubscriber();
192 };
193
194 /**
195 * @private
196 *
197 * @return void
198 */
199 function _addPropertyValidators() {
200 getFormEditorApp().addPropertyValidationValidator('NotEmpty', function(formElement, propertyPath) {
201 if (formElement.get(propertyPath) === '') {
202 return getFormEditorApp().getFormElementPropertyValidatorDefinition('NotEmpty')['errorMessage'] || 'invalid value';
203 }
204 });
205
206 getFormEditorApp().addPropertyValidationValidator('Integer', function(formElement, propertyPath) {
207 if (!$.isNumeric(formElement.get(propertyPath))) {
208 return getFormEditorApp().getFormElementPropertyValidatorDefinition('Integer')['errorMessage'] || 'invalid value';
209 }
210 });
211
212 getFormEditorApp().addPropertyValidationValidator('IntegerOrEmpty', function(formElement, propertyPath) {
213 if (formElement.get(propertyPath).length > 0 && !$.isNumeric(formElement.get(propertyPath))) {
214 return getFormEditorApp().getFormElementPropertyValidatorDefinition('Integer')['errorMessage'] || 'invalid value';
215 }
216 });
217
218 getFormEditorApp().addPropertyValidationValidator('NaiveEmail', function(formElement, propertyPath) {
219 if (!formElement.get(propertyPath).match(/\S+@\S+\.\S+/)) {
220 return getFormEditorApp().getFormElementPropertyValidatorDefinition('NaiveEmail')['errorMessage'] || 'invalid value';
221 }
222 });
223
224 getFormEditorApp().addPropertyValidationValidator('NaiveEmailOrEmpty', function(formElement, propertyPath) {
225 if (formElement.get(propertyPath).length > 0 && !formElement.get(propertyPath).match(/\S+@\S+\.\S+/)) {
226 return getFormEditorApp().getFormElementPropertyValidatorDefinition('NaiveEmailOrEmpty')['errorMessage'] || 'invalid value';
227 }
228 });
229
230 getFormEditorApp().addPropertyValidationValidator('FormElementIdentifierWithinCurlyBracesInclusive', function(formElement, propertyPath) {
231 var match, regex;
232 regex = /\{([a-z0-9-_]+)?\}/gi;
233 match = regex.exec(formElement.get(propertyPath));
234 if (match && ((match[1] && !getFormEditorApp().isFormElementIdentifierUsed(match[1])) || !match[1])) {
235 return getFormEditorApp().getFormElementPropertyValidatorDefinition('FormElementIdentifierWithinCurlyBracesInclusive')['errorMessage'] || 'invalid value';
236 }
237 });
238
239 getFormEditorApp().addPropertyValidationValidator('FormElementIdentifierWithinCurlyBracesExclusive', function(formElement, propertyPath) {
240 var match, regex;
241 regex = /^\{([a-z0-9-_]+)?\}$/i;
242 match = regex.exec(formElement.get(propertyPath));
243 if (!match || ((match[1] && !getFormEditorApp().isFormElementIdentifierUsed(match[1])) || !match[1])) {
244 return getFormEditorApp().getFormElementPropertyValidatorDefinition('FormElementIdentifierWithinCurlyBracesInclusive')['errorMessage'] || 'invalid value';
245 }
246 });
247 };
248
249 /**
250 * @private
251 *
252 * @param object additionalViewModelModules
253 * @return void
254 * @publish view/ready
255 * @throws 1475425785
256 */
257 function _loadAdditionalModules(additionalViewModelModules) {
258 var additionalViewModelModulesLength, isLastElement, loadedAdditionalViewModelModules;
259
260 if ('array' !== $.type(additionalViewModelModules)) {
261 return;
262 }
263 additionalViewModelModulesLength = additionalViewModelModules.length;
264
265 if (additionalViewModelModulesLength > 0) {
266 loadedAdditionalViewModelModules = 0;
267 for (var i = 0; i < additionalViewModelModulesLength; ++i) {
268 require([additionalViewModelModules[i]], function (additionalViewModelModule) {
269 assert(
270 'function' === $.type(additionalViewModelModule.bootstrap),
271 'The module "' + additionalViewModelModules[i] + '" does not implement the method "bootstrap"',
272 1475425785
273 );
274 additionalViewModelModule.bootstrap(getFormEditorApp());
275
276 loadedAdditionalViewModelModules++;
277 if (additionalViewModelModulesLength === loadedAdditionalViewModelModules) {
278 getPublisherSubscriber().publish('view/ready');
279 }
280 });
281 }
282 } else {
283 getPublisherSubscriber().publish('view/ready');
284 }
285 };
286
287 /**
288 * @private
289 *
290 * @return void
291 * @throws 1478268638
292 */
293 function _helperSetup() {
294 assert('function' === $.type(Helper.bootstrap),
295 'The view model helper does not implement the method "bootstrap"',
296 1478268638
297 );
298
299 Helper.bootstrap(getFormEditorApp());
300 };
301
302 /**
303 * @private
304 *
305 * @return void
306 * @throws 1478268639
307 */
308 function _structureComponentSetup() {
309 assert(
310 'function' === $.type(TreeComponent.bootstrap),
311 'The structure component does not implement the method "bootstrap"',
312 1478268639
313 );
314
315 _structureComponent = TreeComponent.bootstrap(
316 getFormEditorApp(),
317 $(getHelper().getDomElementDataAttribute('identifier', 'bracesWithKeyValue', [
318 getHelper().getDomElementDataAttributeValue('structure')
319 ]))
320 );
321
322 $( getHelper().getDomElementDataIdentifierSelector('iconMailform'),
323 $(getHelper().getDomElementDataIdentifierSelector('structureRootContainer'))
324 ).tooltip({
325 title: 'identifier: ' + getRootFormElement().get('identifier'),
326 placement: 'right'
327 });
328 };
329
330 /**
331 * @private
332 *
333 * @return void
334 * @throws 1478895106
335 */
336 function _modalsComponentSetup() {
337 assert(
338 'function' === $.type(ModalsComponent.bootstrap),
339 'The modals component does not implement the method "bootstrap"',
340 1478895106
341 );
342 _modalsComponent = ModalsComponent.bootstrap(getFormEditorApp());
343 };
344
345 /**
346 * @private
347 *
348 * @return void
349 * @throws 1478895106
350 */
351 function _inspectorsComponentSetup() {
352 assert(
353 'function' === $.type(InspectorComponent.bootstrap),
354 'The inspector component does not implement the method "bootstrap"',
355 1478895106
356 );
357 _inspectorsComponent = InspectorComponent.bootstrap(getFormEditorApp());
358 };
359
360 /**
361 * @private
362 *
363 * @return void
364 * @throws 1478986610
365 */
366 function _stageComponentSetup() {
367 assert(
368 'function' === $.type(InspectorComponent.bootstrap),
369 'The stage component does not implement the method "bootstrap"',
370 1478986610
371 );
372 _stageComponent = StageComponent.bootstrap(
373 getFormEditorApp(),
374 $(getHelper().getDomElementDataAttribute('identifier', 'bracesWithKeyValue', [
375 getHelper().getDomElementDataAttributeValue('stageArea')
376 ]))
377 );
378
379 getStage().getStagePanelDomElement().on("click", function(e) {
380 if (
381 $(e.target).attr(getHelper().getDomElementDataAttribute('identifier')) === getHelper().getDomElementDataAttributeValue('stagePanelHeading')
382 || $(e.target).attr(getHelper().getDomElementDataAttribute('identifier')) === getHelper().getDomElementDataAttributeValue('stageSection')
383 || $(e.target).attr(getHelper().getDomElementDataAttribute('identifier')) === getHelper().getDomElementDataAttributeValue('stageArea')
384 ) {
385 selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex());
386 }
387 getPublisherSubscriber().publish('view/stage/panel/clicked', []);
388 });
389 };
390
391 /**
392 * @private
393 *
394 * @return void
395 * @publish view/header/button/save/clicked
396 * @publish view/stage/abstract/button/newElement/clicked
397 * @publish view/header/button/newPage/clicked
398 * @publish view/structure/button/newPage/clicked
399 * @publish view/header/button/close/clicked
400 */
401 function _buttonsSetup() {
402 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderSave')).on("click", function(e) {
403 getPublisherSubscriber().publish('view/header/button/save/clicked', []);
404 });
405
406 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderSettings')).on('click', function(e) {
407 getPublisherSubscriber().publish('view/header/formSettings/clicked', []);
408 });
409
410 $(getHelper().getDomElementDataIdentifierSelector('buttonStageNewElementBottom')).on('click', function(e) {
411 getPublisherSubscriber().publish(
412 'view/stage/abstract/button/newElement/clicked', [
413 'view/insertElements/perform/bottom'
414 ]
415 );
416 });
417
418 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderNewPage')).on('click', function(e) {
419 getPublisherSubscriber().publish('view/header/button/newPage/clicked', ['view/insertPages/perform']);
420 });
421
422 $(getHelper().getDomElementDataIdentifierSelector('buttonStructureNewPage')).on('click', function(e) {
423 getPublisherSubscriber().publish('view/structure/button/newPage/clicked', ['view/insertPages/perform']);
424 });
425
426 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderClose')).on('click', function(e) {
427 if (!getFormEditorApp().getUnsavedContent()) {
428 return;
429 }
430 e.preventDefault();
431 getPublisherSubscriber().publish('view/header/button/close/clicked', []);
432 });
433
434 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')).on('click', function(e) {
435 getPublisherSubscriber().publish('view/undoButton/clicked', []);
436 });
437
438 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')).on('click', function(e) {
439 getPublisherSubscriber().publish('view/redoButton/clicked', []);
440 });
441
442 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModeAbstract')).on('click', function(e) {
443 getPublisherSubscriber().publish('view/viewModeButton/abstract/clicked', []);
444 });
445
446 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModePreview')).on('click', function(e) {
447 getPublisherSubscriber().publish('view/viewModeButton/preview/clicked', []);
448 });
449
450 $(getHelper().getDomElementDataIdentifierSelector('structureRootContainer')).on("click", function(e) {
451 getPublisherSubscriber().publish('view/structure/root/selected');
452 });
453
454 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderPaginationNext')).on('click', function(e) {
455 getPublisherSubscriber().publish('view/paginationNext/clicked', []);
456 });
457
458 $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderPaginationPrevious')).on('click', function(e) {
459 getPublisherSubscriber().publish('view/paginationPrevious/clicked', []);
460 });
461 };
462
463 /* *************************************************************
464 * Public Methodes
465 * ************************************************************/
466
467 /**
468 * @public
469 *
470 * @return object
471 */
472 function getFormEditorApp() {
473 return _formEditorApp;
474 };
475
476 /**
477 * @public
478 *
479 * @param object
480 * @return object
481 */
482 function getHelper(configuration) {
483 if (getUtility().isUndefinedOrNull(configuration)) {
484 return Helper.setConfiguration(_configuration);
485 }
486 return Helper.setConfiguration(configuration);
487 };
488
489 /**
490 * @public
491 *
492 * @param object formElement
493 * @param string formElementDefinitionKey
494 * @return mixed
495 */
496 function getFormElementDefinition(formElement, formElementDefinitionKey) {
497 return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
498 };
499
500 /**
501 * @public
502 *
503 * @return object (derefernced)
504 */
505 function getConfiguration() {
506 return $.extend(true, {}, _configuration);
507 };
508
509 /**
510 * @public
511 *
512 * @return int
513 */
514 function getPreviewMode() {
515 return _previewMode;
516 };
517
518 /**
519 * @public
520 *
521 * @param bool
522 * @return void
523 */
524 function setPreviewMode(previewMode) {
525 _previewMode = !!previewMode;
526 };
527
528 /* *************************************************************
529 * Structure
530 * ************************************************************/
531
532 /**
533 * @public
534 *
535 * @return object
536 */
537 function getStructure() {
538 return _structureComponent;
539 };
540
541 /**
542 * @public
543 *
544 * @return void
545 * @publish view/structure/renew/postProcess
546 */
547 function renewStructure() {
548 getStructure().renew();
549 getPublisherSubscriber().publish('view/structure/renew/postProcess');
550 };
551
552 /**
553 * @public
554 *
555 * @param object
556 * @return void
557 */
558 function addStructureSelection(formElement) {
559 getStructure().getTreeNode(formElement).addClass(getHelper().getDomElementClassName('selectedFormElement'));
560 };
561
562 /**
563 * @public
564 *
565 * @param object
566 * @return void
567 */
568 function removeStructureSelection(formElement) {
569 getStructure().getTreeNode(formElement).removeClass(getHelper().getDomElementClassName('selectedFormElement'));
570 };
571
572 /**
573 * @public
574 *
575 * @return void
576 */
577 function removeAllStructureSelections() {
578 $(getHelper().getDomElementClassName('selectedFormElement', true), getStructure().getTreeDomElement())
579 .removeClass(getHelper().getDomElementClassName('selectedFormElement'));
580 };
581
582 /**
583 * @public
584 *
585 * @return object
586 */
587 function getStructureRootElement() {
588 return $(getHelper().getDomElementDataAttribute('identifier', 'bracesWithKeyValue', [
589 getHelper().getDomElementDataAttributeValue('structureRootElement')
590 ]));
591 };
592
593 /**
594 * @public
595 *
596 * @return void
597 */
598 function removeStructureRootElementSelection() {
599 $(getHelper().getDomElementDataAttribute('identifier', 'bracesWithKeyValue', [
600 getHelper().getDomElementDataAttributeValue('structureRootContainer')
601 ])).removeClass(getHelper().getDomElementClassName('selectedRootFormElement'));
602 };
603
604 /**
605 * @public
606 *
607 * @return void
608 */
609 function addStructureRootElementSelection() {
610 $(getHelper().getDomElementDataAttribute('identifier', 'bracesWithKeyValue', [
611 getHelper().getDomElementDataAttributeValue('structureRootContainer')
612 ])).addClass(getHelper().getDomElementClassName('selectedRootFormElement'));
613 };
614
615 /**
616 * @public
617 *
618 * @param string title
619 * @return void
620 */
621 function setStructureRootElementTitle(title) {
622 if (getUtility().isUndefinedOrNull(title)) {
623 title = $('<span></span>')
624 .text((getRootFormElement().get('label') ? getRootFormElement().get('label') : getRootFormElement().get('identifier')))
625 .text();
626 }
627 getStructureRootElement().text(title);
628 };
629
630 /**
631 * @public
632 *
633 * @return void
634 */
635 function addStructureValidationResults() {
636 var validationResults;
637
638 getStructure().getAllTreeNodes()
639 .removeClass(getHelper().getDomElementClassName('validationErrors'))
640 .removeClass(getHelper().getDomElementClassName('validationChildHasErrors'));
641
642 removeElementValidationErrorClass(getStructureRootElement());
643
644 validationResults = getFormEditorApp().validateFormElementRecursive(getRootFormElement());
645 for (var i = 0, len = validationResults.length; i < len; ++i) {
646 var hasError = false, pathParts, validationElement;
647 for (var j = 0, len2 = validationResults[i]['validationResults'].length; j < len2; ++j) {
648 if (
649 validationResults[i]['validationResults'][j]['validationResults']
650 && validationResults[i]['validationResults'][j]['validationResults'].length > 0
651 ) {
652 hasError = true;
653 break;
654 }
655 }
656
657 if (hasError) {
658 if (i === 0) {
659 setElementValidationErrorClass(getStructureRootElement());
660 } else {
661 validationElement = getStructure().getTreeNode(validationResults[i]['formElementIdentifierPath']);
662 setElementValidationErrorClass(validationElement);
663
664 pathParts = validationResults[i]['formElementIdentifierPath'].split('/');
665 while(pathParts.pop()) {
666 validationElement = getStructure().getTreeNode(pathParts.join('/'));
667 if ('object' === $.type(validationElement)) {
668 setElementValidationErrorClass(validationElement, 'validationChildHasErrors');
669 }
670 }
671 }
672 }
673 }
674 };
675
676 /* *************************************************************
677 * Modals
678 * ************************************************************/
679
680 /**
681 * @public
682 *
683 * @return object
684 */
685 function getModals() {
686 return _modalsComponent
687 };
688
689 /**
690 * @public
691 *
692 * @param object formElement
693 * @return void
694 */
695 function showRemoveFormElementModal(formElement) {
696 if (getUtility().isUndefinedOrNull(formElement)) {
697 formElement = getCurrentlySelectedFormElement();
698 }
699 getModals().showRemoveFormElementModal(formElement);
700 };
701
702 /**
703 * @public
704 *
705 * @param string collectionElementIdentifier
706 * @param string collectionName
707 * @param object formElement
708 * @return void
709 */
710 function showRemoveCollectionElementModal(collectionElementIdentifier, collectionName, formElement) {
711 if (getUtility().isUndefinedOrNull(formElement)) {
712 formElement = getCurrentlySelectedFormElement();
713 }
714 getModals().showRemoveCollectionElementModal(collectionElementIdentifier, collectionName, formElement);
715 };
716
717 /**
718 * @public
719 *
720 * @return void
721 */
722 function showCloseConfirmationModal() {
723 getModals().showCloseConfirmationModal();
724 };
725
726 /**
727 * @public
728 *
729 * @param string targetEvent
730 * @param object configuration
731 * @return void
732 */
733 function showInsertElementsModal(targetEvent, configuration) {
734 getModals().showInsertElementsModal(targetEvent, configuration);
735 };
736
737 /**
738 * @public
739 *
740 * @param string targetEvent
741 * @return void
742 */
743 function showInsertPagesModal(targetEvent) {
744 getModals().showInsertPagesModal(targetEvent);
745 };
746
747 /**
748 * @public
749 *
750 * @param bool
751 * @return void
752 */
753 function showValidationErrorsModal() {
754 var validationResults;
755 validationResults = getFormEditorApp().validateFormElementRecursive(getRootFormElement());
756
757 getModals().showValidationErrorsModal(validationResults);
758 };
759
760 /* *************************************************************
761 * Inspector
762 * ************************************************************/
763
764 /**
765 * @public
766 *
767 * @return object
768 */
769 function getInspector() {
770 return _inspectorsComponent
771 };
772
773 /**
774 * @public
775 *
776 * @param object
777 * @param bool
778 * @return void
779 */
780 function renderInspectorEditors(formElement, useFadeEffect) {
781 var render;
782 if (getUtility().isUndefinedOrNull(useFadeEffect)) {
783 useFadeEffect = true;
784 }
785
786 /**
787 * @private
788 *
789 * @param function
790 * @return void
791 */
792 render = function(callback) {
793 getInspector().renderEditors(formElement, callback);
794 };
795
796 if (!!useFadeEffect) {
797 getInspector().getInspectorDomElement().fadeOut('fast', function() {
798 render(function() {
799 getInspector().getInspectorDomElement().fadeIn('fast');
800 });
801 });
802 } else {
803 render();
804 }
805 };
806
807 /**
808 * @public
809 *
810 * @param string
811 * @param string
812 * @return void
813 */
814 function renderInspectorCollectionElementEditors(collectionName, collectionElementIdentifier) {
815 getInspector().renderCollectionElementEditors(collectionName, collectionElementIdentifier);
816 };
817
818 /**
819 * @public
820 *
821 * @param string content
822 * @return void
823 */
824 function setInspectorFormElementHeaderEditorContent(content) {
825 getInspector().setFormElementHeaderEditorContent(content);
826 };
827
828 /* *************************************************************
829 * Stage
830 * ************************************************************/
831
832 /**
833 * @public
834 *
835 * @return object
836 */
837 function getStage() {
838 return _stageComponent;
839 };
840
841 /**
842 * @public
843 *
844 * @param string title
845 * @return void
846 */
847 function setStageHeadline(title) {
848 getStage().setStageHeadline(title);
849 };
850
851 /**
852 * @public
853 *
854 * @return void
855 */
856 function addStagePanelSelection() {
857 getStage().getStagePanelDomElement().addClass(getHelper().getDomElementClassName('selectedStagePanel'));
858 };
859
860 /**
861 * @public
862 *
863 * @return void
864 */
865 function removeStagePanelSelection() {
866 getStage().getStagePanelDomElement().removeClass(getHelper().getDomElementClassName('selectedStagePanel'));
867 };
868
869 /**
870 * @public
871 *
872 * @return void
873 */
874 function renderPagination() {
875 getStage().renderPagination();
876 };
877
878 /**
879 * @public
880 *
881 * @return void
882 */
883 function renderUndoRedo() {
884 getStage().renderUndoRedo();
885 };
886
887 /**
888 * @public
889 *
890 * @param bool
891 * @param bool
892 * @return void
893 * @publish view/stage/abstract/render/postProcess
894 * @publish view/stage/abstract/render/preProcess
895 */
896 function renderAbstractStageArea(useFadeEffect, toolbarUseFadeEffect) {
897 var render, renderPostProcess;
898
899 $(getHelper().getDomElementDataIdentifierSelector('structureSection'))
900 .animate({
901 'left': '0px'
902 }, 'slow');
903 $(getHelper().getDomElementDataIdentifierSelector('inspectorSection'))
904 .animate({
905 'right': '0px'
906 }, 'slow');
907 $(getHelper().getDomElementDataIdentifierSelector('stageContainer'))
908 .animate({
909 'margin-left': _configuration['panels']['stage']['marginLeft'] + 'px',
910 'margin-right': _configuration['panels']['stage']['marginRight'] + 'px'
911 }, 'slow');
912
913 if (getUtility().isUndefinedOrNull(useFadeEffect)) {
914 useFadeEffect = true;
915 }
916
917 if (getUtility().isUndefinedOrNull(toolbarUseFadeEffect)) {
918 toolbarUseFadeEffect = true;
919 }
920
921 setButtonActive($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModeAbstract')));
922 removeButtonActive($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModePreview')));
923
924 /**
925 * @private
926 *
927 * @param function
928 * @return void
929 */
930 render = function(callback) {
931 $(getHelper().getDomElementDataIdentifierSelector('stageContainer'))
932 .addClass(getHelper().getDomElementClassName('stageViewModeAbstract'))
933 .removeClass(getHelper().getDomElementClassName('stageViewModePreview'));
934
935 getStage().renderAbstractStageArea(undefined, callback);
936 };
937
938 /**
939 * @private
940 *
941 * @return void
942 */
943 renderPostProcess = function() {
944 var formElementTypeDefinition;
945
946 formElementTypeDefinition = getFormElementDefinition(getCurrentlySelectedFormElement());
947 getStage().getAllFormElementDomElements().hover(function() {
948 getStage().getAllFormElementDomElements().parent().removeClass(getHelper().getDomElementClassName('sortableHover'));
949 if (
950 $(this).parent().hasClass(getHelper().getDomElementClassName('formElementIsComposit'))
951 && !$(this).parent().hasClass(getHelper().getDomElementClassName('formElementIsTopLevel'))
952 ) {
953 $(this).parent().addClass(getHelper().getDomElementClassName('sortableHover'));
954 }
955 });
956
957 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderNewPage')));
958 if (
959 formElementTypeDefinition['_isTopLevelFormElement']
960 && !formElementTypeDefinition['_isCompositeFormElement']
961 && !getFormEditorApp().isRootFormElementSelected()
962 ) {
963 hideComponent($(getHelper().getDomElementDataIdentifierSelector('buttonStageNewElementBottom')));
964 hideComponent($(getHelper().getDomElementDataIdentifierSelector('stageNewElementRow')));
965 } else {
966 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonStageNewElementBottom')));
967 showComponent($(getHelper().getDomElementDataIdentifierSelector('stageNewElementRow')));
968 }
969
970 refreshSelectedElementItemsBatch(toolbarUseFadeEffect);
971 getPublisherSubscriber().publish('view/stage/abstract/render/postProcess');
972 };
973
974 if (useFadeEffect) {
975 $(getHelper().getDomElementDataIdentifierSelector('stageSection')).fadeOut(400, function() {
976 render(function() {
977 getPublisherSubscriber().publish('view/stage/abstract/render/preProcess');
978 $(getHelper().getDomElementDataIdentifierSelector('stageSection')).fadeIn(400);
979 renderPostProcess();
980 getPublisherSubscriber().publish('view/stage/abstract/render/postProcess');
981 });
982 });
983 } else {
984 render(function() {
985 getPublisherSubscriber().publish('view/stage/abstract/render/preProcess');
986 renderPostProcess();
987 getPublisherSubscriber().publish('view/stage/abstract/render/postProcess');
988 });
989 }
990 };
991
992 /**
993 * @public
994 *
995 * @param string html
996 * @return void
997 * @publish view/stage/preview/render/postProcess
998 */
999 function renderPreviewStageArea(html) {
1000 $(getHelper().getDomElementDataIdentifierSelector('structureSection'))
1001 .animate({
1002 'left': '-=' + _configuration['panels']['structure']['width'] + 'px'
1003 }, 'slow');
1004 $(getHelper().getDomElementDataIdentifierSelector('inspectorSection'))
1005 .animate({
1006 'right': '-=' + _configuration['panels']['inspector']['width'] + 'px'
1007 }, 'slow');
1008 $(getHelper().getDomElementDataIdentifierSelector('stageContainer'))
1009 .animate({
1010 'margin-left': _configuration['panels']['stage']['marginLeftCollapsed'] + 'px',
1011 'margin-right': _configuration['panels']['stage']['marginRightCollapsed'] + 'px'
1012 }, 'slow');
1013
1014 setButtonActive($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModePreview')));
1015 removeButtonActive($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModeAbstract')));
1016
1017 $(getHelper().getDomElementDataIdentifierSelector('stageSection')).fadeOut(400, function() {
1018 $(getHelper().getDomElementDataIdentifierSelector('stageContainer'))
1019 .addClass(getHelper().getDomElementClassName('stageViewModePreview'))
1020 .removeClass(getHelper().getDomElementClassName('stageViewModeAbstract'));
1021
1022 hideComponent($(getHelper().getDomElementDataIdentifierSelector('buttonStageNewElementBottom')));
1023 hideComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderNewPage')));
1024
1025 getStage().renderPreviewStageArea(html);
1026 $(getHelper().getDomElementDataIdentifierSelector('stageSection')).fadeIn(400);
1027 getPublisherSubscriber().publish('view/stage/preview/render/postProcess');
1028 });
1029 };
1030
1031 /**
1032 * @public
1033 *
1034 * @return void
1035 */
1036 function addAbstractViewValidationResults() {
1037 var validationResults;
1038
1039 validationResults = getFormEditorApp().validateFormElementRecursive(getRootFormElement());
1040 for (var i = 0, len = validationResults.length; i < len; ++i) {
1041 var hasError = false, validationElement;
1042 for (var j = 0, len2 = validationResults[i]['validationResults'].length; j < len2; ++j) {
1043 if (
1044 validationResults[i]['validationResults'][j]['validationResults']
1045 && validationResults[i]['validationResults'][j]['validationResults'].length > 0
1046 ) {
1047 hasError = true;
1048 break;
1049 }
1050 }
1051
1052 if (hasError) {
1053 if (i > 0) {
1054 validationElement = getStage().getAbstractViewFormElementDomElement(validationResults[i]['formElementIdentifierPath']);
1055 setElementValidationErrorClass(validationElement);
1056 }
1057 }
1058 }
1059 };
1060
1061 /* *************************************************************
1062 * Form element methods
1063 * ************************************************************/
1064
1065 /**
1066 * @public
1067 *
1068 * @param string formElementType
1069 * @param string|object referenceFormElement
1070 * @param bool
1071 * @return object
1072 * @publish view/formElement/inserted
1073 */
1074 function createAndAddFormElement(formElementType, referenceFormElement, disablePublishersOnSet) {
1075 var newFormElement;
1076
1077 newFormElement = getFormEditorApp().createAndAddFormElement(formElementType, referenceFormElement);
1078 if (!!!disablePublishersOnSet) {
1079 getPublisherSubscriber().publish('view/formElement/inserted', [newFormElement]);
1080 }
1081 return newFormElement;
1082 };
1083
1084 /**
1085 * @public
1086 *
1087 * @param string|object formElementToMove
1088 * @param string position
1089 * @param string|object referenceFormElement
1090 * @param bool
1091 * @return object
1092 * @publish view/formElement/moved
1093 */
1094 function moveFormElement(formElementToMove, position, referenceFormElement, disablePublishersOnSet) {
1095 var movedFormElement;
1096
1097 movedFormElement = getFormEditorApp().moveFormElement(formElementToMove, position, referenceFormElement, false);
1098 if (!!!disablePublishersOnSet) {
1099 getPublisherSubscriber().publish('view/formElement/moved', [movedFormElement]);
1100 }
1101 return movedFormElement;
1102 };
1103
1104 /**
1105 * @public
1106 *
1107 * @param object formElement
1108 * @param bool
1109 * @return object
1110 * @publish view/formElement/removed
1111 */
1112 function removeFormElement(formElement, disablePublishersOnSet) {
1113 var parentFormElement;
1114
1115 if (getUtility().isUndefinedOrNull(formElement)) {
1116 formElement = getCurrentlySelectedFormElement();
1117 }
1118
1119 if (
1120 getFormElementDefinition(formElement, '_isTopLevelFormElement')
1121 && getFormElementDefinition(formElement, '_isCompositeFormElement')
1122 && getRootFormElement().get('renderables').length === 1
1123 ) {
1124 Notification.error(
1125 getFormElementDefinition(getRootFormElement(), 'modalRemoveElementLastAvailablePageFlashMessageTitle'),
1126 getFormElementDefinition(getRootFormElement(), 'modalRemoveElementLastAvailablePageFlashMessageMessage'),
1127 2
1128 );
1129 } else {
1130 parentFormElement = getFormEditorApp().removeFormElement(formElement, false);
1131 if (!!!disablePublishersOnSet) {
1132 getPublisherSubscriber().publish('view/formElement/removed', [parentFormElement]);
1133 }
1134 }
1135 return parentFormElement;
1136 };
1137
1138 /**
1139 * @public
1140 *
1141 * @param string collectionElementIdentifier
1142 * @param string collectionName
1143 * @param object formElement
1144 * @param object collectionElementConfiguration
1145 * @param string referenceCollectionElementIdentifier
1146 * @param bool
1147 * @return void
1148 * @publish view/collectionElement/new/added
1149 */
1150 function createAndAddPropertyCollectionElement(collectionElementIdentifier, collectionName, formElement, collectionElementConfiguration, referenceCollectionElementIdentifier, disablePublishersOnSet) {
1151 getFormEditorApp().createAndAddPropertyCollectionElement(
1152 collectionElementIdentifier,
1153 collectionName,
1154 formElement,
1155 collectionElementConfiguration,
1156 referenceCollectionElementIdentifier
1157 );
1158 if (!!!disablePublishersOnSet) {
1159 getPublisherSubscriber().publish('view/collectionElement/new/added', [
1160 collectionElementIdentifier,
1161 collectionName,
1162 formElement,
1163 collectionElementConfiguration,
1164 referenceCollectionElementIdentifier
1165 ]);
1166 }
1167 };
1168
1169 /**
1170 * @public
1171 *
1172 * @param string collectionElementToMove
1173 * @param string position
1174 * @param string referenceCollectionElement
1175 * @param string collectionName
1176 * @param object formElement
1177 * @param bool
1178 * @return void
1179 */
1180 function movePropertyCollectionElement(collectionElementToMove, position, referenceCollectionElement, collectionName, formElement, disablePublishersOnSet) {
1181 if (getUtility().isUndefinedOrNull(formElement)) {
1182 formElement = getCurrentlySelectedFormElement();
1183 }
1184 getFormEditorApp().movePropertyCollectionElement(
1185 collectionElementToMove,
1186 position,
1187 referenceCollectionElement,
1188 collectionName,
1189 formElement,
1190 false
1191 );
1192 if (!!!disablePublishersOnSet) {
1193 getPublisherSubscriber().publish('view/collectionElement/moved', [
1194 collectionElementToMove,
1195 position,
1196 referenceCollectionElement,
1197 collectionName,
1198 formElement]
1199 );
1200 }
1201 };
1202
1203 /**
1204 * @public
1205 *
1206 * @param string collectionElementIdentifier
1207 * @param string collectionName
1208 * @param object formElement
1209 * @param bool
1210 * @return void
1211 * @publish view/collectionElement/removed
1212 */
1213 function removePropertyCollectionElement(collectionElementIdentifier, collectionName, formElement, disablePublishersOnSet) {
1214 var collectionElementConfiguration;
1215
1216 getFormEditorApp().removePropertyCollectionElement(collectionElementIdentifier, collectionName, formElement);
1217
1218 collectionElementConfiguration = getFormEditorApp().getPropertyCollectionElementConfiguration(
1219 collectionElementIdentifier,
1220 collectionName
1221 );
1222 if ('array' === $.type(collectionElementConfiguration['editors'])) {
1223 for (var i = 0, len1 = collectionElementConfiguration['editors'].length; i < len1; ++i) {
1224 if ('array' === $.type(collectionElementConfiguration['editors'][i]['additionalElementPropertyPaths'])) {
1225 for (var j = 0, len2 = collectionElementConfiguration['editors'][i]['additionalElementPropertyPaths'].length; j < len2; ++j) {
1226 getCurrentlySelectedFormElement().unset(collectionElementConfiguration['editors'][i]['additionalElementPropertyPaths'][j], true);
1227 }
1228 }
1229 }
1230 }
1231
1232 if (!!!disablePublishersOnSet) {
1233 getPublisherSubscriber().publish('view/collectionElement/removed', [
1234 collectionElementIdentifier,
1235 collectionName,
1236 formElement]
1237 );
1238 }
1239 };
1240
1241 /* *************************************************************
1242 * Batch methodes
1243 * ************************************************************/
1244
1245 /**
1246 * @public
1247 *
1248 * @param bool
1249 * @return void
1250 */
1251 function refreshSelectedElementItemsBatch(toolbarUseFadeEffect) {
1252 var formElementTypeDefinition, selectedElement;
1253
1254 if (getUtility().isUndefinedOrNull(toolbarUseFadeEffect)) {
1255 toolbarUseFadeEffect = true;
1256 }
1257
1258 formElementTypeDefinition = getFormElementDefinition(getCurrentlySelectedFormElement());
1259
1260 getStage().removeAllStageToolbars();
1261 removeAllStageElementSelectionsBatch();
1262 removeAllStructureSelections();
1263
1264 if (!getFormEditorApp().isRootFormElementSelected()) {
1265 removeStructureRootElementSelection();
1266 addStructureSelection();
1267
1268 selectedElement = getStage().getAbstractViewFormElementDomElement();
1269
1270 if (formElementTypeDefinition['_isTopLevelFormElement']) {
1271 addStagePanelSelection();
1272 } else {
1273 selectedElement.addClass(getHelper().getDomElementClassName('selectedFormElement'));
1274 getStage().createAndAddAbstractViewFormElementToolbar(selectedElement, undefined, toolbarUseFadeEffect);
1275 }
1276
1277 getStage().getAllFormElementDomElements().parent().removeClass(getHelper().getDomElementClassName('selectedCompositFormElement'));
1278 if (!formElementTypeDefinition['_isTopLevelFormElement'] && formElementTypeDefinition['_isCompositeFormElement']) {
1279 selectedElement.parent().addClass(getHelper().getDomElementClassName('selectedCompositFormElement'));
1280 }
1281 }
1282 };
1283
1284 /**
1285 * @public
1286 *
1287 * @param int
1288 * @return void
1289 * @throws 1478651732
1290 * @throws 1478651733
1291 * @throws 1478651734
1292 */
1293 function selectPageBatch(pageIndex) {
1294 assert('number' === $.type(pageIndex), 'Invalid parameter "pageIndex"', 1478651732);
1295 assert(pageIndex >= 0, 'Invalid parameter "pageIndex"', 1478651733);
1296 assert(pageIndex < getRootFormElement().get('renderables').length, 'Invalid parameter "pageIndex"', 1478651734);
1297
1298 getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement().get('renderables')[pageIndex]);
1299 renewStructure();
1300 renderPagination()
1301 refreshSelectedElementItemsBatch();
1302 renderInspectorEditors();
1303 };
1304
1305 /**
1306 * @public
1307 *
1308 * @return void
1309 */
1310 function removeAllStageElementSelectionsBatch() {
1311 getStage().getAllFormElementDomElements().removeClass(getHelper().getDomElementClassName('selectedFormElement'));
1312 removeStagePanelSelection();
1313 getStage().getAllFormElementDomElements().parent().removeClass(getHelper().getDomElementClassName('sortableHover'));
1314 };
1315
1316 /**
1317 * @public
1318 *
1319 * @return void
1320 */
1321 function onViewReadyBatch() {
1322 $(getHelper().getDomElementDataIdentifierSelector('structureSection'))
1323 .css({
1324 width: _configuration['panels']['structure']['width'] + 'px',
1325 left: '-=' + _configuration['panels']['structure']['width'] + 'px'
1326 });
1327 $(getHelper().getDomElementDataIdentifierSelector('inspectorSection'))
1328 .css({
1329 width: _configuration['panels']['inspector']['width'] + 'px',
1330 right: '-=' + _configuration['panels']['inspector']['width'] + 'px'
1331 });
1332
1333 $(getHelper().getDomElementClassName('headerButtonBar', true))
1334 .css({
1335 'margin-left': _configuration['panels']['structure']['width'] + 'px'
1336 });
1337
1338 $(getHelper().getDomElementDataIdentifierSelector('stageContainer'))
1339 .css({
1340 'margin-left': _configuration['panels']['stage']['marginLeft'] + 'px',
1341 'margin-right': _configuration['panels']['stage']['marginRight'] + 'px'
1342 });
1343
1344 hideComponent($(getHelper().getDomElementDataIdentifierSelector('buttonStageNewElementBottom')));
1345 hideComponent($(getHelper().getDomElementDataIdentifierSelector('stageNewElementRow')));
1346
1347 setStageHeadline();
1348 setStructureRootElementTitle();
1349 renderAbstractStageArea(false);
1350 renewStructure();
1351 addStructureRootElementSelection();
1352 renderInspectorEditors();
1353 renderPagination();
1354
1355 hideComponent($(getHelper().getDomElementDataIdentifierSelector('moduleLoadingIndicator')));
1356 showComponent($(getHelper().getDomElementDataIdentifierSelector('moduleWrapper')));
1357 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderSave')));
1358 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderSettings')));
1359 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderClose')));
1360 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderNewPage')));
1361 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
1362 showComponent($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
1363 setButtonActive($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderViewModeAbstract')));
1364 };
1365
1366 /**
1367 * @public
1368 *
1369 * @param object
1370 * @param object
1371 * @return void
1372 */
1373 function onAbstractViewDndStartBatch(draggedFormElementDomElement, draggedFormPlaceholderDomElement) {
1374 draggedFormPlaceholderDomElement.removeClass(getHelper().getDomElementClassName('sortableHover'));
1375 };
1376
1377 /**
1378 * @public
1379 *
1380 * @param object
1381 * @param string
1382 * @param object
1383 * @return void
1384 */
1385 function onAbstractViewDndChangeBatch(placeholderDomElement, parentFormElementIdentifierPath, enclosingCompositeFormElement) {
1386 getStage().getAllFormElementDomElements().parent().removeClass(getHelper().getDomElementClassName('sortableHover'));
1387 if (enclosingCompositeFormElement) {
1388 getStage().getAbstractViewParentFormElementWithinDomElement(placeholderDomElement).parent().addClass(getHelper().getDomElementClassName('sortableHover'));
1389 }
1390 };
1391
1392 /**
1393 * @public
1394 *
1395 * @param object
1396 * @param string
1397 * @param string
1398 * @param string
1399 * @return void
1400 * @throws 1472502237
1401 */
1402 function onAbstractViewDndUpdateBatch(movedDomElement, movedFormElementIdentifierPath, previousFormElementIdentifierPath, nextFormElementIdentifierPath) {
1403 var movedFormElement, parentFormElementIdentifierPath;
1404 if (nextFormElementIdentifierPath) {
1405 movedFormElement = moveFormElement(movedFormElementIdentifierPath, 'before', nextFormElementIdentifierPath);
1406 } else if (previousFormElementIdentifierPath) {
1407 movedFormElement = moveFormElement(movedFormElementIdentifierPath, 'after', previousFormElementIdentifierPath);
1408 } else {
1409 parentFormElementIdentifierPath = getStage().getAbstractViewParentFormElementIdentifierPathWithinDomElement(movedDomElement);
1410 if (parentFormElementIdentifierPath) {
1411 movedFormElement = moveFormElement(movedFormElementIdentifierPath, 'inside', parentFormElementIdentifierPath);
1412 } else {
1413 assert(false, 'Next element, previous or parent element need to be set.', 1472502237);
1414 }
1415 }
1416
1417 getStage()
1418 .getAbstractViewFormElementWithinDomElement(movedDomElement)
1419 .attr(
1420 getHelper().getDomElementDataAttribute('elementIdentifier'),
1421 movedFormElement.get('__identifierPath')
1422 );
1423 };
1424
1425 /**
1426 * @public
1427 *
1428 * @param object
1429 * @param string
1430 * @param object
1431 * @return void
1432 */
1433 function onStructureDndChangeBatch(placeholderDomElement, parentFormElementIdentifierPath, enclosingCompositeFormElement) {
1434 getStructure()
1435 .getAllTreeNodes()
1436 .parent()
1437 .removeClass(getHelper().getDomElementClassName('sortableHover'));
1438
1439 getStage()
1440 .getAllFormElementDomElements()
1441 .parent()
1442 .removeClass(getHelper().getDomElementClassName('sortableHover'));
1443
1444 if (enclosingCompositeFormElement) {
1445 getStructure()
1446 .getParentTreeNodeWithinDomElement(placeholderDomElement)
1447 .parent()
1448 .addClass(getHelper().getDomElementClassName('sortableHover'));
1449
1450 getStage()
1451 .getAbstractViewFormElementDomElement(enclosingCompositeFormElement)
1452 .parent()
1453 .addClass(getHelper().getDomElementClassName('sortableHover'));
1454 }
1455 };
1456
1457 /**
1458 * @public
1459 *
1460 * @param object
1461 * @param string
1462 * @param string
1463 * @param string
1464 * @return void
1465 * @throws 1479048646
1466 */
1467 function onStructureDndUpdateBatch(movedDomElement, movedFormElementIdentifierPath, previousFormElementIdentifierPath, nextFormElementIdentifierPath) {
1468 var movedFormElement, parentFormElementIdentifierPath;
1469 if (nextFormElementIdentifierPath) {
1470 movedFormElement = moveFormElement(movedFormElementIdentifierPath, 'before', nextFormElementIdentifierPath);
1471 } else if (previousFormElementIdentifierPath) {
1472 movedFormElement = moveFormElement(movedFormElementIdentifierPath, 'after', previousFormElementIdentifierPath);
1473 } else {
1474 parentFormElementIdentifierPath = getStructure().getParentTreeNodeIdentifierPathWithinDomElement(movedDomElement);
1475 if (parentFormElementIdentifierPath) {
1476 movedFormElement = moveFormElement(movedFormElementIdentifierPath, 'inside', parentFormElementIdentifierPath);
1477 } else {
1478 getFormEditorApp().assert(false, 'Next element, previous or parent element need to be set.', 1479048646);
1479 }
1480 }
1481
1482 getStructure()
1483 .getTreeNodeWithinDomElement(movedDomElement)
1484 .attr(
1485 getHelper().getDomElementDataAttribute('elementIdentifier'),
1486 movedFormElement.get('__identifierPath')
1487 );
1488 };
1489
1490 /* *************************************************************
1491 * Misc
1492 * ************************************************************/
1493
1494 /**
1495 * @public
1496 *
1497 * @return void
1498 */
1499 function closeEditor() {
1500 document.location.href = $(getHelper().getDomElementDataIdentifierSelector('buttonHeaderClose')).prop('href');
1501 };
1502
1503 /**
1504 * @public
1505 *
1506 * @param object
1507 * @param string
1508 * @return void
1509 */
1510 function setElementValidationErrorClass(element, classIdentifier) {
1511 if (getFormEditorApp().getUtility().isUndefinedOrNull(classIdentifier)) {
1512 element.addClass(getHelper().getDomElementClassName('validationErrors'));
1513 } else {
1514 element.addClass(getHelper().getDomElementClassName(classIdentifier));
1515 }
1516 };
1517
1518 /**
1519 * @public
1520 *
1521 * @param object
1522 * @param string
1523 * @return void
1524 */
1525 function removeElementValidationErrorClass(element, classIdentifier) {
1526 if (getFormEditorApp().getUtility().isUndefinedOrNull(classIdentifier)) {
1527 element.removeClass(getHelper().getDomElementClassName('validationErrors'));
1528 } else {
1529 element.removeClass(getHelper().getDomElementClassName(classIdentifier));
1530 }
1531 };
1532
1533 /**
1534 * @public
1535 *
1536 * @param object
1537 * @return void
1538 */
1539 function showComponent(element) {
1540 element.removeClass(getHelper().getDomElementClassName('hidden')).show();
1541 };
1542
1543 /**
1544 * @public
1545 *
1546 * @param object
1547 * @return void
1548 */
1549 function hideComponent(element) {
1550 element.addClass(getHelper().getDomElementClassName('hidden')).hide();
1551 };
1552
1553 /**
1554 * @public
1555 *
1556 * @param object
1557 * @return void
1558 */
1559 function enableButton(buttonElement) {
1560 buttonElement.prop('disabled', false).removeClass(getHelper().getDomElementClassName('disabled'));
1561 };
1562
1563 /**
1564 * @public
1565 *
1566 * @param object
1567 * @return void
1568 */
1569 function disableButton(buttonElement) {
1570 buttonElement.prop('disabled', 'disabled').addClass(getHelper().getDomElementClassName('disabled'));
1571 };
1572
1573 /**
1574 * @public
1575 *
1576 * @param object
1577 * @return void
1578 */
1579 function setButtonActive(buttonElement) {
1580 buttonElement.addClass(getHelper().getDomElementClassName('active'));
1581 };
1582
1583 /**
1584 * @public
1585 *
1586 * @param object
1587 * @return void
1588 */
1589 function removeButtonActive(buttonElement) {
1590 buttonElement.removeClass(getHelper().getDomElementClassName('active'));
1591 };
1592
1593 /**
1594 * @public
1595 *
1596 * @return void
1597 */
1598 function showSaveButtonSpinnerIcon() {
1599 Icons.getIcon(getHelper().getDomElementDataAttributeValue('iconSaveSpinner'), Icons.sizes.small).done(function(markup) {
1600 $(getHelper().getDomElementDataIdentifierSelector('iconSave')).replaceWith($(markup));
1601 });
1602 };
1603
1604 /**
1605 * @public
1606 *
1607 * @return void
1608 */
1609 function showSaveButtonSaveIcon() {
1610 Icons.getIcon(getHelper().getDomElementDataAttributeValue('iconSave'), Icons.sizes.small).done(function(markup) {
1611 $(getHelper().getDomElementDataIdentifierSelector('iconSaveSpinner')).replaceWith($(markup));
1612 });
1613 };
1614
1615 /**
1616 * @public
1617 *
1618 * @return void
1619 */
1620 function showSaveSuccessMessage() {
1621 Notification.success(
1622 getFormElementDefinition(getRootFormElement(), 'saveSuccessFlashMessageTitle'),
1623 getFormElementDefinition(getRootFormElement(), 'saveSuccessFlashMessageMessage'),
1624 2
1625 );
1626 };
1627
1628 /**
1629 * @public
1630 *
1631 * @param string
1632 * @param string
1633 * @return void
1634 */
1635 function showErrorFlashMessage(title, message) {
1636 Notification.error(title, message, 2);
1637 };
1638
1639 /**
1640 * @public
1641 *
1642 * @param object formEditorApp
1643 * @param object additionalViewModelModules
1644 * @return void
1645 */
1646 function bootstrap(formEditorApp, additionalViewModelModules) {
1647 _formEditorApp = formEditorApp;
1648
1649 _helperSetup();
1650 _structureComponentSetup();
1651 _modalsComponentSetup();
1652 _inspectorsComponentSetup();
1653 _stageComponentSetup();
1654 _buttonsSetup();
1655 _addPropertyValidators();
1656 _loadAdditionalModules(additionalViewModelModules);
1657 };
1658
1659 /**
1660 * Publish the public methods.
1661 * Implements the "Revealing Module Pattern".
1662 */
1663 return {
1664 addAbstractViewValidationResults: addAbstractViewValidationResults,
1665 addStagePanelSelection: addStagePanelSelection,
1666 addStructureRootElementSelection: addStructureRootElementSelection,
1667 addStructureSelection: addStructureSelection,
1668 addStructureValidationResults: addStructureValidationResults,
1669 bootstrap: bootstrap,
1670 closeEditor: closeEditor,
1671 createAndAddFormElement: createAndAddFormElement,
1672 createAndAddPropertyCollectionElement: createAndAddPropertyCollectionElement,
1673 disableButton: disableButton,
1674 enableButton: enableButton,
1675 getConfiguration: getConfiguration,
1676 getFormEditorApp: getFormEditorApp,
1677 getFormElementDefinition: getFormElementDefinition,
1678 getHelper: getHelper,
1679 getInspector: getInspector,
1680 getModals: getModals,
1681 getPreviewMode: getPreviewMode,
1682 getStage: getStage,
1683 getStructure: getStructure,
1684 getStructureRootElement: getStructureRootElement,
1685 hideComponent: hideComponent,
1686 moveFormElement: moveFormElement,
1687 movePropertyCollectionElement: movePropertyCollectionElement,
1688 onAbstractViewDndChangeBatch: onAbstractViewDndChangeBatch,
1689 onAbstractViewDndStartBatch: onAbstractViewDndStartBatch,
1690 onAbstractViewDndUpdateBatch: onAbstractViewDndUpdateBatch,
1691 onStructureDndChangeBatch: onStructureDndChangeBatch,
1692 onStructureDndUpdateBatch: onStructureDndUpdateBatch,
1693 onViewReadyBatch: onViewReadyBatch,
1694 refreshSelectedElementItemsBatch: refreshSelectedElementItemsBatch,
1695 removeAllStageElementSelectionsBatch: removeAllStageElementSelectionsBatch,
1696 removeAllStructureSelections: removeAllStructureSelections,
1697 removeButtonActive: removeButtonActive,
1698 removeElementValidationErrorClass: removeElementValidationErrorClass,
1699 removeFormElement: removeFormElement,
1700 removePropertyCollectionElement: removePropertyCollectionElement,
1701 removeStagePanelSelection: removeStagePanelSelection,
1702 removeStructureRootElementSelection: removeStructureRootElementSelection,
1703 removeStructureSelection: removeStructureSelection,
1704 renderAbstractStageArea: renderAbstractStageArea,
1705 renderInspectorEditors: renderInspectorEditors,
1706 renderInspectorCollectionElementEditors: renderInspectorCollectionElementEditors,
1707 renderPagination: renderPagination,
1708 renderPreviewStageArea: renderPreviewStageArea,
1709 renewStructure: renewStructure,
1710 renderUndoRedo: renderUndoRedo,
1711 selectPageBatch: selectPageBatch,
1712 setButtonActive: setButtonActive,
1713 setElementValidationErrorClass: setElementValidationErrorClass,
1714 setInspectorFormElementHeaderEditorContent: setInspectorFormElementHeaderEditorContent,
1715 setPreviewMode: setPreviewMode,
1716 setStageHeadline: setStageHeadline,
1717 setStructureRootElementTitle: setStructureRootElementTitle,
1718 showCloseConfirmationModal: showCloseConfirmationModal,
1719 showComponent: showComponent,
1720 showErrorFlashMessage: showErrorFlashMessage,
1721 showInsertElementsModal: showInsertElementsModal,
1722 showInsertPagesModal: showInsertPagesModal,
1723 showRemoveFormElementModal: showRemoveFormElementModal,
1724 showRemoveCollectionElementModal: showRemoveCollectionElementModal,
1725 showSaveButtonSaveIcon: showSaveButtonSaveIcon,
1726 showSaveButtonSpinnerIcon: showSaveButtonSpinnerIcon,
1727 showSaveSuccessMessage: showSaveSuccessMessage,
1728 showValidationErrorsModal: showValidationErrorsModal
1729 };
1730 })($, TreeComponent, ModalsComponent, InspectorComponent, StageComponent, Helper, Icons, Notification);
1731 });