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