[TASK] Migrate FormEngineFlexForm to TypeScript 34/56234/6
authorAndreas Wolf <dev@a-w.io>
Fri, 16 Mar 2018 15:12:52 +0000 (16:12 +0100)
committerFrank Naegler <frank.naegler@typo3.org>
Wed, 31 Oct 2018 13:18:16 +0000 (14:18 +0100)
Change-Id: I3151b16f72baf31e13f841ecc95be4ca389cf36e
Resolves: #82587
Releases: master
Reviewed-on: https://review.typo3.org/56234
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Build/types/TYPO3/index.d.ts
typo3/sysext/backend/Resources/Private/TypeScript/FormEngine/FlexForm/FlexFormElementOptions.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Private/TypeScript/FormEngineFlexForm.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/FlexForm/FlexFormElementOptions.js [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/FormEngineFlexForm.js

index 3e420a6..391a56d 100644 (file)
@@ -19,7 +19,7 @@ declare namespace TYPO3 {
   export let Storage: any;
   export let Tooltip: any;
   export let Utility: any;
-  export const lang: any;
+  export const lang: { [key: string]: string };
   export const settings: any;
   export const configuration: any;
   export namespace CMS {
@@ -27,6 +27,8 @@ declare namespace TYPO3 {
       export class FormEngineValidation {
         public readonly errorClass: string;
         public markFieldAsChanged($field: JQuery): void;
+        public initializeInputFields(): void;
+        public validate(): void;
       }
 
       export class FormEngine {
@@ -40,6 +42,7 @@ declare namespace TYPO3 {
           exclusiveValues?: string,
           $optionEl?: JQuery
         ): void;
+        public reinitialize(): void;
       }
 
       export class Wizard {
@@ -121,6 +124,8 @@ interface JQuery {
 
   dragUploader(options?: any): JQuery;
 
+  t3FormEngineFlexFormElement(options?: any): JQuery;
+
   // To be able to use twbs/bootstrap-slider we have to override the definition of jquerui
   slider(options: { [key: string]: any }): any;
 
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/FormEngine/FlexForm/FlexFormElementOptions.ts b/typo3/sysext/backend/Resources/Private/TypeScript/FormEngine/FlexForm/FlexFormElementOptions.ts
new file mode 100644 (file)
index 0000000..08885e9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+export interface FlexFormElementOptions {
+  deleteIconSelector: string;
+  sectionSelector: string;
+  sectionContentSelector: string;
+  sectionHeaderSelector: string;
+  sectionHeaderPreviewSelector: string;
+  sectionActionInputFieldSelector: string;
+  sectionToggleInputFieldSelector: string;
+  sectionToggleIconOpenSelector: string;
+  sectionToggleIconCloseSelector: string;
+  sectionToggleButtonSelector: string;
+  flexFormToggleAllSectionsSelector: string;
+  sectionDeletedClass: string;
+  allowRestructure: boolean;
+  flexformId: boolean | string;
+}
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/FormEngineFlexForm.ts b/typo3/sysext/backend/Resources/Private/TypeScript/FormEngineFlexForm.ts
new file mode 100644 (file)
index 0000000..a564446
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Module: TYPO3/CMS/Backend/FormEngineFlexForm
+ * Contains all JS functions related to TYPO3 Flexforms
+ * available under the latest jQuery version
+ * can be used by $('myflexform').t3FormEngineFlexFormElement({options});, all .t3-flex-form containers will be called on load
+ *
+ * currently TYPO3.FormEngine.FlexFormElement represents one Flexform element
+ * which can contain one ore more sections
+ */
+
+import * as $ from 'jquery';
+import 'jquery-ui/sortable';
+
+import {FlexFormElementOptions} from './FormEngine/FlexForm/FlexFormElementOptions';
+import FormEngine = require('TYPO3/CMS/Backend/FormEngine');
+import Modal = require('TYPO3/CMS/Backend/Modal');
+
+/**
+ *
+ * @param {HTMLElement} el
+ * @param {Object} options
+ * @constructor
+ * @exports TYPO3/CMS/Backend/FormEngineFlexForm
+ */
+class FlexFormElement {
+  // setting some default values
+  private static defaults: FlexFormElementOptions = {
+    deleteIconSelector: '.t3js-delete',
+    sectionSelector: '.t3js-flex-section',
+    sectionContentSelector: '.t3js-flex-section-content',
+    sectionHeaderSelector: '.t3js-flex-section-header',
+    sectionHeaderPreviewSelector: '.t3js-flex-section-header-preview',
+    sectionActionInputFieldSelector: '.t3js-flex-control-action',
+    sectionToggleInputFieldSelector: '.t3js-flex-control-toggle',
+    sectionToggleIconOpenSelector: '.t3js-flex-control-toggle-icon-open',
+    sectionToggleIconCloseSelector: '.t3js-flex-control-toggle-icon-close',
+    sectionToggleButtonSelector: '[data-toggle="formengine-flex"]',
+    flexFormToggleAllSectionsSelector: '.t3js-form-field-toggle-flexsection',
+    sectionDeletedClass: 't3js-flex-section-deleted',
+    allowRestructure: false, // whether the form can be modified
+    flexformId: false
+  };
+
+  private $el: JQuery;
+
+  // shorthand options notation
+  private opts: FlexFormElementOptions;
+
+  constructor(private el: HTMLElement, options: FlexFormElementOptions) {
+    const that = this;
+    // store DOM element and jQuery object for later use
+    this.el = el;
+    this.$el = $(el);
+
+    // remove any existing backups
+    const old_this = this.$el.data('TYPO3.FormEngine.FlexFormElement');
+    if (typeof old_this !== 'undefined') {
+      this.$el.removeData('TYPO3.FormEngine.FlexFormElement');
+    }
+
+    // add a reverse reference to the DOM element
+    this.$el.data('TYPO3.FormEngine.FlexFormElement', this);
+
+    if (!options) {
+      options = FlexFormElement.defaults;
+    }
+
+    // set some values from existing properties
+    options.allowRestructure = <boolean>this.$el.data('t3-flex-allow-restructure');
+    options.flexformId = this.$el.attr('id');
+
+    // store options and merge with default options
+    this.opts = $.extend({}, FlexFormElement.defaults, options);
+
+    // initialize events
+    this.initializeEvents();
+
+    // generate the preview text if a section is hidden on load
+    this.$el.find(this.opts.sectionSelector).each(function(this: HTMLElement): void {
+      that.generateSectionPreview($(this));
+    });
+
+    return this;
+  }
+
+  /**
+   * init all events related to the flexform. As this method is called multiple times,
+   * some handlers need to be off'ed first to prevent event stacking.
+   */
+  public initializeEvents(): this {
+    // Toggling all sections on/off by clicking all toggle buttons of each section
+    this.$el.prev(this.opts.flexFormToggleAllSectionsSelector).off('click').on('click', () => {
+      this.$el.find(this.opts.sectionToggleButtonSelector).trigger('click');
+    });
+
+    if (this.opts.allowRestructure) {
+      // create a sortable when dragging on the header of a section
+      this.createSortable();
+
+      // allow delete of a single section
+      this.$el.off('click').on('click', this.opts.deleteIconSelector, (evt) => {
+        evt.preventDefault();
+
+        const confirmTitle = TYPO3.lang['flexform.section.delete.title'] || 'Are you sure?';
+        const confirmMessage = TYPO3.lang['flexform.section.delete.message'] || 'Are you sure you want to delete this section?';
+        const $confirm = Modal.confirm(confirmTitle, confirmMessage);
+        $confirm.on('confirm.button.cancel', () => {
+          Modal.currentModal.trigger('modal-dismiss');
+        });
+        $confirm.on('confirm.button.ok', () => {
+          $(evt.target).closest(this.opts.sectionSelector).hide().addClass(this.opts.sectionDeletedClass);
+          this.setActionStatus();
+          FormEngine.Validation.validate();
+          Modal.currentModal.trigger('modal-dismiss');
+        });
+      });
+
+      // allow the toggle open/close of the main selection
+      this.$el.on('click', this.opts.sectionToggleButtonSelector, (evt) => {
+        evt.preventDefault();
+        const $sectionEl = $(evt.currentTarget).closest(this.opts.sectionSelector);
+        this.toggleSection($sectionEl);
+      }).on('click', this.opts.sectionToggleButtonSelector + ' .form-irre-header-control', function(evt: Event): void {
+        evt.stopPropagation();
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Allow flexform sections to be sorted
+   */
+  public createSortable(): void {
+    this.$el.sortable({
+      containment: 'parent',
+      handle: '.t3js-sortable-handle',
+      axis: 'y',
+      tolerance: 'pointer',
+      stop: () => {
+        this.setActionStatus();
+        $(document).trigger('flexform:sorting-changed');
+      }
+    });
+  }
+
+  // Updates the "action"-status for a section. This is used to move and delete elements.
+  private setActionStatus(): void {
+    const that = this;
+    // Traverse and find how many sections are open or closed, and save the value accordingly
+    this.$el.find(this.opts.sectionActionInputFieldSelector).each(function(this: HTMLElement, index: number): void {
+      const actionValue = ($(this).parents(that.opts.sectionSelector).hasClass(that.opts.sectionDeletedClass) ? 'DELETE' : index);
+      $(this).val(actionValue);
+    });
+  }
+
+  // Toggling flexform elements on/off
+  // hides the flexform section and shows a preview text
+  // or shows the form parts
+  private toggleSection($sectionEl: JQuery): void {
+   const $contentEl = $sectionEl.find(this.opts.sectionContentSelector);
+
+   // display/hide the content of this flexform section
+   $contentEl.toggle();
+
+   if ($contentEl.is(':visible')) {
+     // show the open icon, and set the hidden field for toggling to "hidden"
+     $sectionEl.find(this.opts.sectionToggleIconOpenSelector).show();
+     $sectionEl.find(this.opts.sectionToggleIconCloseSelector).hide();
+     $sectionEl.find(this.opts.sectionToggleInputFieldSelector).val(0);
+   } else {
+     // show the close icon, and set the hidden field for toggling to "1"
+     $sectionEl.find(this.opts.sectionToggleIconOpenSelector).hide();
+     $sectionEl.find(this.opts.sectionToggleIconCloseSelector).show();
+     $sectionEl.find(this.opts.sectionToggleInputFieldSelector).val(1);
+   }
+
+   // see if the preview content needs to be generated
+   this.generateSectionPreview($sectionEl);
+  }
+
+  // function to generate the section preview in the header
+  // if the section content is hidden
+  // called on load and when toggling an icon
+  private generateSectionPreview($sectionEl: JQuery): void {
+    const $contentEl = $sectionEl.find(this.opts.sectionContentSelector);
+    let previewContent = '';
+
+    if (!$contentEl.is(':visible')) {
+      $contentEl.find('input[type=text], textarea').each(function(this: HTMLElement): void {
+        let content = $($.parseHTML($(this).val())).text();
+        if (content.length > 50) {
+          content = content.substring(0, 50) + '...';
+        }
+        previewContent += (previewContent ? ' / ' : '') + content;
+      });
+    }
+
+    // create a preview container span element
+    if ($sectionEl.find(this.opts.sectionHeaderPreviewSelector).length === 0) {
+      $sectionEl.find(this.opts.sectionHeaderSelector).find('.t3js-record-title').parent()
+        .append('<span class="' + this.opts.sectionHeaderPreviewSelector.replace(/\./, '') + '"></span>');
+    }
+
+    $sectionEl.find(this.opts.sectionHeaderPreviewSelector).text(previewContent);
+  }
+}
+
+
+
+// register the flex functions as jQuery Plugin
+$.fn.t3FormEngineFlexFormElement = function(options: FlexFormElementOptions): JQuery {
+  // apply all util functions to ourself (for use in templates, etc.)
+  return this.each(function(this: HTMLElement): void {
+    const _ = new FlexFormElement(this, options);
+  });
+};
+
+// Initialization Code
+$(function(): void {
+  // run the flexform functions on all containers (which contains one or more sections)
+  $('.t3-flex-container').t3FormEngineFlexFormElement();
+
+  // Add handler to fetch container data on click on "add container" buttons
+  $('.t3js-flex-container-add').on('click', function(this: HTMLElement, e: Event): void {
+    const me = $(this);
+    e.preventDefault();
+    $.ajax({
+      url: TYPO3.settings.ajaxUrls.record_flex_container_add,
+      type: 'POST',
+      cache: false,
+      data: {
+        vanillaUid: me.data('vanillauid'),
+        databaseRowUid: me.data('databaserowuid'),
+        command: me.data('command'),
+        tableName: me.data('tablename'),
+        fieldName: me.data('fieldname'),
+        recordTypeValue: me.data('recordtypevalue'),
+        dataStructureIdentifier: me.data('datastructureidentifier'),
+        flexFormSheetName: me.data('flexformsheetname'),
+        flexFormFieldName: me.data('flexformfieldname'),
+        flexFormContainerName: me.data('flexformcontainername')
+      },
+      success: function(response: any): void {
+        me.closest('.t3-form-field-container').find('.t3-flex-container').append(response.html);
+        $('.t3-flex-container').t3FormEngineFlexFormElement();
+        if (response.scriptCall && response.scriptCall.length > 0) {
+          $.each(response.scriptCall, function(index: number, value: string): void {
+            /* tslint:disable-next-line:no-eval */
+            eval(value);
+          });
+        }
+        if (response.stylesheetFiles && response.stylesheetFiles.length > 0) {
+          $.each(response.stylesheetFiles, function(index: number, stylesheetFile: string): void {
+            let element = document.createElement('link');
+            element.rel = 'stylesheet';
+            element.type = 'text/css';
+            element.href = stylesheetFile;
+            document.head.appendChild(element);
+          });
+        }
+        FormEngine.reinitialize();
+        FormEngine.Validation.initializeInputFields();
+        FormEngine.Validation.validate();
+      }
+    });
+  });
+
+});
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/FlexForm/FlexFormElementOptions.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/FlexForm/FlexFormElementOptions.js
new file mode 100644 (file)
index 0000000..d580a28
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+define(["require","exports"],function(e,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0})});
\ No newline at end of file
index 5cd9abf..f17a1ad 100644 (file)
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: TYPO3/CMS/Backend/FormEngineFlexForm
- * Contains all JS functions related to TYPO3 Flexforms
- * available under the latest jQuery version
- * can be used by $('myflexform').t3FormEngineFlexFormElement({options});, all .t3-flex-form containers will be called on load
- *
- * currently TYPO3.FormEngine.FlexFormElement represents one Flexform element
- * which can contain one ore more sections
- */
-define(['jquery',
-  'TYPO3/CMS/Backend/Modal',
-  'TYPO3/CMS/Backend/FormEngine'
-], function($, Modal) {
-
-  /**
-   *
-   * @param {HTMLElement} el
-   * @param {Object} options
-   * @constructor
-   * @exports TYPO3/CMS/Backend/FormEngineFlexForm
-   */
-  TYPO3.FormEngine.FlexFormElement = function(el, options) {
-    var me = this;     // avoid scope issues
-    var opts;  // shorthand options notation
-
-    // initialization function; private
-    me.initialize = function() {
-      // store DOM element and jQuery object for later use
-      me.el = el;
-      me.$el = $(el);
-
-      // remove any existing backups
-      var old_me = me.$el.data('TYPO3.FormEngine.FlexFormElement');
-      if (typeof old_me !== 'undefined') {
-        me.$el.removeData('TYPO3.FormEngine.FlexFormElement');
-      }
-
-      // add a reverse reference to the DOM element
-      me.$el.data('TYPO3.FormEngine.FlexFormElement', me);
-
-      if (!options) {
-        options = {};
-      }
-
-      // set some values from existing properties
-      options.allowRestructure = me.$el.data('t3-flex-allow-restructure');
-      options.flexformId = me.$el.attr('id');
-
-      // store options and merge with default options
-      opts = me.options = $.extend({}, TYPO3.FormEngine.FlexFormElement.defaults, options);
-
-      // initialize events
-      me.initializeEvents();
-
-      // generate the preview text if a section is hidden on load
-      me.$el.find(opts.sectionSelector).each(function() {
-        me.generateSectionPreview($(this));
-      });
-
-      return me;
-    };
-
-    /**
-     * init all events related to the flexform. As this method is called multiple times,
-     * some handlers need to be off'ed first to prevent event stacking.
-     */
-    me.initializeEvents = function() {
-      // Toggling all sections on/off by clicking all toggle buttons of each section
-      me.$el.prev(opts.flexFormToggleAllSectionsSelector).off('click').on('click', function() {
-        me.$el.find(opts.sectionToggleButtonSelector).trigger('click');
-      });
-
-      if (opts.allowRestructure) {
-        // create a sortable when dragging on the header of a section
-        me.createSortable();
-
-        // allow delete of a single section
-        me.$el.off('click').on('click', opts.deleteIconSelector, function(evt) {
-          evt.preventDefault();
-
-          var confirmTitle = TYPO3.lang['flexform.section.delete.title'] || 'Are you sure?';
-          var confirmMessage = TYPO3.lang['flexform.section.delete.message'] || 'Are you sure you want to delete this section?';
-          var $confirm = Modal.confirm(confirmTitle, confirmMessage);
-          $confirm.on('confirm.button.cancel', function() {
-            Modal.currentModal.trigger('modal-dismiss');
-          });
-          $confirm.on('confirm.button.ok', function(event) {
-            $(evt.target).closest(opts.sectionSelector).hide().addClass(opts.sectionDeletedClass);
-            me.setActionStatus();
-            TYPO3.FormEngine.Validation.validate();
-            Modal.currentModal.trigger('modal-dismiss');
-          });
-        });
-
-        // allow the toggle open/close of the main selection
-        me.$el.on('click', opts.sectionToggleButtonSelector, function(evt) {
-          evt.preventDefault();
-          var $sectionEl = $(this).closest(opts.sectionSelector);
-          me.toggleSection($sectionEl);
-        }).on('click', opts.sectionToggleButtonSelector + ' .form-irre-header-control', function(evt) {
-          evt.stopPropagation();
-        });
-      }
-
-      return me;
-    };
-
-    // initialize ourself
-    me.initialize();
-  };
-
-  // setting some default values
-  TYPO3.FormEngine.FlexFormElement.defaults = {
-    'deleteIconSelector': '.t3js-delete',
-    'sectionSelector': '.t3js-flex-section',
-    'sectionContentSelector': '.t3js-flex-section-content',
-    'sectionHeaderSelector': '.t3js-flex-section-header',
-    'sectionHeaderPreviewSelector': '.t3js-flex-section-header-preview',
-    'sectionActionInputFieldSelector': '.t3js-flex-control-action',
-    'sectionToggleInputFieldSelector': '.t3js-flex-control-toggle',
-    'sectionToggleIconOpenSelector': '.t3js-flex-control-toggle-icon-open',
-    'sectionToggleIconCloseSelector': '.t3js-flex-control-toggle-icon-close',
-    'sectionToggleButtonSelector': '[data-toggle="formengine-flex"]',
-    'flexFormToggleAllSectionsSelector': '.t3js-form-field-toggle-flexsection',
-    'sectionDeletedClass': 't3js-flex-section-deleted',
-    'allowRestructure': 0,     // whether the form can be modified
-    'flexformId': false
-  };
-
-
-  /**
-   * Allow flexform sections to be sorted
-   */
-  TYPO3.FormEngine.FlexFormElement.prototype.createSortable = function() {
-    var me = this;
-
-    require(['jquery-ui/sortable'], function() {
-      me.$el.sortable({
-        containment: 'parent',
-        handle: '.t3js-sortable-handle',
-        axis: 'y',
-        tolerance: 'pointer',
-        stop: function() {
-          me.setActionStatus();
-          $(document).trigger('flexform:sorting-changed');
-        }
-      });
-    });
-  };
-
-  // Updates the "action"-status for a section. This is used to move and delete elements.
-  TYPO3.FormEngine.FlexFormElement.prototype.setActionStatus = function() {
-    var me = this;
-
-    // Traverse and find how many sections are open or closed, and save the value accordingly
-    me.$el.find(me.options.sectionActionInputFieldSelector).each(function(index) {
-      var actionValue = ($(this).parents(me.options.sectionSelector).hasClass(me.options.sectionDeletedClass) ? 'DELETE' : index);
-      $(this).val(actionValue);
-    });
-  };
-
-  // Toggling flexform elements on/off
-  // hides the flexform section and shows a preview text
-  // or shows the form parts
-  TYPO3.FormEngine.FlexFormElement.prototype.toggleSection = function($sectionEl) {
-
-    var $contentEl = $sectionEl.find(this.options.sectionContentSelector);
-
-    // display/hide the content of this flexform section
-    $contentEl.toggle();
-
-    if ($contentEl.is(':visible')) {
-      // show the open icon, and set the hidden field for toggling to "hidden"
-      $sectionEl.find(this.options.sectionToggleIconOpenSelector).show();
-      $sectionEl.find(this.options.sectionToggleIconCloseSelector).hide();
-      $sectionEl.find(this.options.sectionToggleInputFieldSelector).val(0);
-    } else {
-      // show the close icon, and set the hidden field for toggling to "1"
-      $sectionEl.find(this.options.sectionToggleIconOpenSelector).hide();
-      $sectionEl.find(this.options.sectionToggleIconCloseSelector).show();
-      $sectionEl.find(this.options.sectionToggleInputFieldSelector).val(1);
-    }
-
-    // see if the preview content needs to be generated
-    this.generateSectionPreview($sectionEl);
-  };
-
-  // function to generate the section preview in the header
-  // if the section content is hidden
-  // called on load and when toggling an icon
-  TYPO3.FormEngine.FlexFormElement.prototype.generateSectionPreview = function($sectionEl) {
-    var $contentEl = $sectionEl.find(this.options.sectionContentSelector);
-    var previewContent = '';
-
-    if (!$contentEl.is(':visible')) {
-      $contentEl.find('input[type=text], textarea').each(function() {
-        var content = $($.parseHTML($(this).val())).text();
-        if (content.length > 50) {
-          content = content.substring(0, 50) + '...';
-        }
-        previewContent += (previewContent ? ' / ' : '') + content;
-      });
-    }
-
-    // create a preview container span element
-    if ($sectionEl.find(this.options.sectionHeaderPreviewSelector).length === 0) {
-      $sectionEl.find(this.options.sectionHeaderSelector).find('.t3js-record-title').parent()
-        .append('<span class="' + this.options.sectionHeaderPreviewSelector.replace(/\./, '') + '"></span>');
-    }
-
-    $sectionEl.find(this.options.sectionHeaderPreviewSelector).text(previewContent);
-  };
-
-  // register the flex functions as jQuery Plugin
-  $.fn.t3FormEngineFlexFormElement = function(options) {
-    // apply all util functions to ourself (for use in templates, etc.)
-    return this.each(function() {
-      (new TYPO3.FormEngine.FlexFormElement(this, options));
-    });
-  };
-
-  // Initialization Code
-  $(function() {
-    // run the flexform functions on all containers (which contains one or more sections)
-    $('.t3-flex-container').t3FormEngineFlexFormElement();
-
-    // Add handler to fetch container data on click on "add container" buttons
-    $('.t3js-flex-container-add').on('click', function(e) {
-      var me = $(this);
-      e.preventDefault();
-      $.ajax({
-        url: TYPO3.settings.ajaxUrls['record_flex_container_add'],
-        type: 'POST',
-        cache: false,
-        data: {
-          vanillaUid: me.data('vanillauid'),
-          databaseRowUid: me.data('databaserowuid'),
-          command: me.data('command'),
-          tableName: me.data('tablename'),
-          fieldName: me.data('fieldname'),
-          recordTypeValue: me.data('recordtypevalue'),
-          dataStructureIdentifier: me.data('datastructureidentifier'),
-          flexFormSheetName: me.data('flexformsheetname'),
-          flexFormFieldName: me.data('flexformfieldname'),
-          flexFormContainerName: me.data('flexformcontainername')
-        },
-        success: function(response) {
-          me.closest('.t3-form-field-container').find('.t3-flex-container').append(response.html);
-          $('.t3-flex-container').t3FormEngineFlexFormElement();
-          if (response.scriptCall && response.scriptCall.length > 0) {
-            $.each(response.scriptCall, function(index, value) {
-              eval(value);
-            });
-          }
-          if (response.stylesheetFiles && response.stylesheetFiles.length > 0) {
-            $.each(response.stylesheetFiles, function(index, stylesheetFile) {
-              var element = document.createElement('link');
-              element['rel'] = 'stylesheet';
-              element['type'] = 'text/css';
-              element['href'] = stylesheetFile;
-              document.head.appendChild(element);
-            });
-          }
-          TYPO3.FormEngine.reinitialize();
-          TYPO3.FormEngine.Validation.initializeInputFields();
-          TYPO3.FormEngine.Validation.validate();
-        }
-      });
-    });
-
-  });
-});
+define(["require","exports","jquery","TYPO3/CMS/Backend/FormEngine","TYPO3/CMS/Backend/Modal","jquery-ui/sortable"],function(require,exports,$,FormEngine,Modal){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var FlexFormElement=function(){function e(t,o){this.el=t;var n=this;return this.el=t,this.$el=$(t),void 0!==this.$el.data("TYPO3.FormEngine.FlexFormElement")&&this.$el.removeData("TYPO3.FormEngine.FlexFormElement"),this.$el.data("TYPO3.FormEngine.FlexFormElement",this),o||(o=e.defaults),o.allowRestructure=this.$el.data("t3-flex-allow-restructure"),o.flexformId=this.$el.attr("id"),this.opts=$.extend({},e.defaults,o),this.initializeEvents(),this.$el.find(this.opts.sectionSelector).each(function(){n.generateSectionPreview($(this))}),this}return e.prototype.initializeEvents=function(){var e=this;return this.$el.prev(this.opts.flexFormToggleAllSectionsSelector).off("click").on("click",function(){e.$el.find(e.opts.sectionToggleButtonSelector).trigger("click")}),this.opts.allowRestructure&&(this.createSortable(),this.$el.off("click").on("click",this.opts.deleteIconSelector,function(t){t.preventDefault();var o=TYPO3.lang["flexform.section.delete.title"]||"Are you sure?",n=TYPO3.lang["flexform.section.delete.message"]||"Are you sure you want to delete this section?",i=Modal.confirm(o,n);i.on("confirm.button.cancel",function(){Modal.currentModal.trigger("modal-dismiss")}),i.on("confirm.button.ok",function(){$(t.target).closest(e.opts.sectionSelector).hide().addClass(e.opts.sectionDeletedClass),e.setActionStatus(),FormEngine.Validation.validate(),Modal.currentModal.trigger("modal-dismiss")})}),this.$el.on("click",this.opts.sectionToggleButtonSelector,function(t){t.preventDefault();var o=$(t.currentTarget).closest(e.opts.sectionSelector);e.toggleSection(o)}).on("click",this.opts.sectionToggleButtonSelector+" .form-irre-header-control",function(e){e.stopPropagation()})),this},e.prototype.createSortable=function(){var e=this;this.$el.sortable({containment:"parent",handle:".t3js-sortable-handle",axis:"y",tolerance:"pointer",stop:function(){e.setActionStatus(),$(document).trigger("flexform:sorting-changed")}})},e.prototype.setActionStatus=function(){var e=this;this.$el.find(this.opts.sectionActionInputFieldSelector).each(function(t){var o=$(this).parents(e.opts.sectionSelector).hasClass(e.opts.sectionDeletedClass)?"DELETE":t;$(this).val(o)})},e.prototype.toggleSection=function(e){var t=e.find(this.opts.sectionContentSelector);t.toggle(),t.is(":visible")?(e.find(this.opts.sectionToggleIconOpenSelector).show(),e.find(this.opts.sectionToggleIconCloseSelector).hide(),e.find(this.opts.sectionToggleInputFieldSelector).val(0)):(e.find(this.opts.sectionToggleIconOpenSelector).hide(),e.find(this.opts.sectionToggleIconCloseSelector).show(),e.find(this.opts.sectionToggleInputFieldSelector).val(1)),this.generateSectionPreview(e)},e.prototype.generateSectionPreview=function(e){var t=e.find(this.opts.sectionContentSelector),o="";t.is(":visible")||t.find("input[type=text], textarea").each(function(){var e=$($.parseHTML($(this).val())).text();e.length>50&&(e=e.substring(0,50)+"..."),o+=(o?" / ":"")+e}),0===e.find(this.opts.sectionHeaderPreviewSelector).length&&e.find(this.opts.sectionHeaderSelector).find(".t3js-record-title").parent().append('<span class="'+this.opts.sectionHeaderPreviewSelector.replace(/\./,"")+'"></span>'),e.find(this.opts.sectionHeaderPreviewSelector).text(o)},e.defaults={deleteIconSelector:".t3js-delete",sectionSelector:".t3js-flex-section",sectionContentSelector:".t3js-flex-section-content",sectionHeaderSelector:".t3js-flex-section-header",sectionHeaderPreviewSelector:".t3js-flex-section-header-preview",sectionActionInputFieldSelector:".t3js-flex-control-action",sectionToggleInputFieldSelector:".t3js-flex-control-toggle",sectionToggleIconOpenSelector:".t3js-flex-control-toggle-icon-open",sectionToggleIconCloseSelector:".t3js-flex-control-toggle-icon-close",sectionToggleButtonSelector:'[data-toggle="formengine-flex"]',flexFormToggleAllSectionsSelector:".t3js-form-field-toggle-flexsection",sectionDeletedClass:"t3js-flex-section-deleted",allowRestructure:!1,flexformId:!1},e}();$.fn.t3FormEngineFlexFormElement=function(e){return this.each(function(){new FlexFormElement(this,e)})},$(function(){$(".t3-flex-container").t3FormEngineFlexFormElement(),$(".t3js-flex-container-add").on("click",function(e){var me=$(this);e.preventDefault(),$.ajax({url:TYPO3.settings.ajaxUrls.record_flex_container_add,type:"POST",cache:!1,data:{vanillaUid:me.data("vanillauid"),databaseRowUid:me.data("databaserowuid"),command:me.data("command"),tableName:me.data("tablename"),fieldName:me.data("fieldname"),recordTypeValue:me.data("recordtypevalue"),dataStructureIdentifier:me.data("datastructureidentifier"),flexFormSheetName:me.data("flexformsheetname"),flexFormFieldName:me.data("flexformfieldname"),flexFormContainerName:me.data("flexformcontainername")},success:function(response){me.closest(".t3-form-field-container").find(".t3-flex-container").append(response.html),$(".t3-flex-container").t3FormEngineFlexFormElement(),response.scriptCall&&response.scriptCall.length>0&&$.each(response.scriptCall,function(index,value){eval(value)}),response.stylesheetFiles&&response.stylesheetFiles.length>0&&$.each(response.stylesheetFiles,function(e,t){var o=document.createElement("link");o.rel="stylesheet",o.type="text/css",o.href=t,document.head.appendChild(o)}),FormEngine.reinitialize(),FormEngine.Validation.initializeInputFields(),FormEngine.Validation.validate()}})})})});
\ No newline at end of file