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