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