[TASK] Migrate DateTimePicker to TypeScript 07/55907/2
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Mon, 26 Feb 2018 18:22:51 +0000 (19:22 +0100)
committerBenni Mack <benni@typo3.org>
Mon, 26 Feb 2018 19:23:41 +0000 (20:23 +0100)
Change-Id: I7783157819cebea7c4ee55a0b0612483daf9cbf3
Resolves: #82582
Releases: master
Reviewed-on: https://review.typo3.org/55907
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Build/types/TYPO3/index.d.ts
typo3/sysext/backend/Resources/Private/TypeScript/DateTimePicker.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/DateTimePicker.js

index 1fff037..31a7f8c 100644 (file)
@@ -87,5 +87,6 @@ interface JQueryTypedEvent<T extends Event> extends JQueryEventObject {
  */
 interface JQuery {
   clearable(options?: any): JQuery;
+  datetimepicker(options?: any): JQuery;
   dragUploader(options?: DragUploaderOptions): JQuery;
 }
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/DateTimePicker.ts b/typo3/sysext/backend/Resources/Private/TypeScript/DateTimePicker.ts
new file mode 100644 (file)
index 0000000..63da0ca
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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!
+ */
+
+import * as $ from 'jquery';
+import moment = require('moment');
+import PersistentStorage = require('./Storage/Persistent');
+
+/**
+ * Module: TYPO3/CMS/Backend/DateTimePicker
+ * contains all logic for the date time picker used in FormEngine
+ * and EXT:belog and EXT:scheduler
+ */
+class DateTimePicker {
+  private fieldSelector: string = '.t3js-datetimepicker';
+  private format: string = (opener != null && typeof opener.top.TYPO3 !== 'undefined' ? opener.top : top)
+    .TYPO3.settings.DateTimePicker.DateFormat;
+
+  /**
+   * Format a given date for the hidden FormEngine field
+   *
+   * Format the value for the hidden field that is passed on to the backend, i.e. most likely DataHandler.
+   * The format for that is the timestamp for time fields, and a full-blown ISO-8601 timestamp for all date-related fields.
+   *
+   * @param {moment} date
+   * @param {string} type
+   * @returns {string}
+   */
+  private static formatDateForHiddenField(date: any, type: string): string {
+    if (type === 'time' || type === 'timesec') {
+      date.year(1970).month(0).date(1);
+    }
+    return date.format();
+  }
+
+  constructor() {
+    $((): void => {
+      this.initialize();
+    });
+  }
+
+  /**
+   * initialize date fields to add a datepicker to each field
+   * note: this function can be called multiple times (e.g. after AJAX requests) because it only
+   * applies to fields which haven't been used yet.
+   */
+  private initialize(): void {
+    // fetch the date time fields that haven't been initialized yet
+    const $dateTimeFields = $(this.fieldSelector).filter((index: number, element: HTMLElement): boolean => {
+      return typeof $(element).data('DateTimePicker') === 'undefined';
+    });
+
+    if ($dateTimeFields.length > 0) {
+      require(['twbs/bootstrap-datetimepicker'], (): void => {
+        let userLocale = PersistentStorage.get('lang');
+        // Fix our made up locale "ch"
+        if (userLocale === 'ch') {
+          userLocale = 'zh-cn';
+        }
+        const setLocale = userLocale ? moment.locale(userLocale) : false;
+
+        // initialize the datepicker on each selected element
+        $dateTimeFields.each((index: number, element: HTMLElement): void => {
+          this.initializeField($(element), setLocale);
+        });
+
+        $dateTimeFields.on('blur', (e: JQueryEventObject): void => {
+          const $element = $(e.currentTarget);
+          const $hiddenField = $element.parent().parent().find('input[type="hidden"]');
+
+          if ($element.val() === '') {
+            $hiddenField.val('');
+          } else {
+            const type = $element.data('dateType');
+            const format = $element.data('DateTimePicker').format();
+            const date = moment.utc($element.val(), format);
+            if (date.isValid()) {
+              $hiddenField.val(DateTimePicker.formatDateForHiddenField(date, type));
+            } else {
+              $element.val(DateTimePicker.formatDateForHiddenField(moment.utc($hiddenField.val()), type));
+            }
+          }
+        });
+
+        // on datepicker change, write the selected date with the timezone offset to the hidden field
+        $dateTimeFields.on('dp.change', (e: any): void => {
+          const $element = $(e.currentTarget);
+          const $hiddenField = $element.parent().parent().find('input[type=hidden]');
+          const type = $element.data('dateType');
+          let value = '';
+
+          if ($element.val() !== '') {
+            value = DateTimePicker.formatDateForHiddenField(e.date.utc(), type);
+          }
+          $hiddenField.val(value);
+
+          $(document).trigger('formengine.dp.change', [$(this)]);
+        });
+      });
+    }
+  }
+
+  /**
+   * Initialize a single field
+   *
+   * @param {JQuery} $element
+   * @param {string} locale
+   */
+  private initializeField($element: JQuery, locale: string): void {
+    const format = this.format;
+    const type = $element.data('dateType');
+    const options = {
+      format: '',
+      locale: '',
+      sideBySide: true,
+      showTodayButton: true,
+      toolbarPlacement: 'bottom',
+      icons: {
+        time: 'fa fa-clock-o',
+        date: 'fa fa-calendar',
+        up: 'fa fa-chevron-up',
+        down: 'fa fa-chevron-down',
+        previous: 'fa fa-chevron-left',
+        next: 'fa fa-chevron-right',
+        today: 'fa fa-calendar-o',
+        clear: 'fa fa-trash'
+      }
+    };
+
+    // set options based on type
+    switch (type) {
+      case 'datetime':
+        options.format = format[1];
+        break;
+      case 'date':
+        options.format = format[0];
+        break;
+      case 'time':
+        options.format = 'HH:mm';
+        break;
+      case 'timesec':
+        options.format = 'HH:mm:ss';
+        break;
+      case 'year':
+        options.format = 'YYYY';
+        break;
+      default:
+    }
+
+    // datepicker expects the min and max dates to be formatted with options.format but unix timestamp given
+    if ($element.data('dateMindate')) {
+      $element.data('dateMindate', moment.unix($element.data('dateMindate')).format(options.format));
+    }
+    if ($element.data('dateMaxdate')) {
+      $element.data('dateMaxdate', moment.unix($element.data('dateMaxdate')).format(options.format));
+    }
+
+    if (locale) {
+      options.locale = locale;
+    }
+
+    // initialize the date time picker on this element
+    $element.datetimepicker(options);
+  }
+}
+
+export = new DateTimePicker();
index 4332626..c8155e9 100644 (file)
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: TYPO3/CMS/Backend/DateTimePicker
- * contains all logic for the date time picker used in FormEngine
- * and EXT:belog and EXT:scheduler
- */
-define(['jquery'], function($) {
-  "use strict";
-
-  /**
-   * @type {{options: {fieldSelector: string, format: *}}}
-   * @exports TYPO3/CMS/Backend/DateTimePicker
-   */
-  var DateTimePicker = {
-    options: {
-      fieldSelector: '.t3js-datetimepicker',
-      format: (opener != null && typeof opener.top.TYPO3 !== 'undefined' ? opener.top : top).TYPO3.settings.DateTimePicker.DateFormat
-    }
-  };
-
-  /**
-   * initialize date fields to add a datepicker to each field
-   * note: this function can be called multiple times (e.g. after AJAX requests) because it only
-   * applies to fields which haven't been used yet.
-   */
-  DateTimePicker.initialize = function() {
-    // fetch the date time fields that haven't been initialized yet
-    var $dateTimeFields = $(DateTimePicker.options.fieldSelector).filter(function() {
-      return $(this).data('DateTimePicker') === undefined;
-    });
-
-    if ($dateTimeFields.length > 0) {
-      require(['moment', 'TYPO3/CMS/Backend/Storage/Persistent', 'twbs/bootstrap-datetimepicker'], function(moment, PersistentStorage) {
-        var userLocale = PersistentStorage.get('lang');
-        // Fix our made up locale "ch"
-        if (userLocale === 'ch') {
-          userLocale = 'zh-cn';
-        }
-        var setLocale = userLocale ? moment.locale(userLocale) : false;
-
-        // initialize the datepicker on each selected element
-        $dateTimeFields.each(function() {
-          DateTimePicker.initializeField(moment, $(this), setLocale);
-        });
-
-        $dateTimeFields.on('blur', function() {
-          var $element = $(this);
-          var $hiddenField = $element.parent().parent().find('input[type=hidden]');
-
-          if ($element.val() === '') {
-            $hiddenField.val('');
-          } else {
-            var type = $element.data('dateType');
-            var format = $element.data('DateTimePicker').format();
-            var date = moment.utc($element.val(), format);
-            if (date.isValid()) {
-              $hiddenField.val(DateTimePicker.formatDateForHiddenField(date, type));
-            } else {
-              $element.val(DateTimePicker.formatDateForHiddenField(moment.utc($hiddenField.val()), type));
-            }
-          }
-        });
-
-        // on datepicker change, write the selected date with the timezone offset to the hidden field
-        $dateTimeFields.on('dp.change', function(evt) {
-          var $element = $(this);
-          var $hiddenField = $element.parent().parent().find('input[type=hidden]');
-          var type = $element.data('dateType');
-          var value = '';
-
-          if ($element.val() !== '') {
-            value = DateTimePicker.formatDateForHiddenField(evt.date.utc(), type);
-          }
-          $hiddenField.val(value);
-
-          $(document).trigger('formengine.dp.change', [$(this)]);
-        });
-      });
-    }
-  };
-
-  /**
-   * Initialize a single field
-   *
-   * @param {moment} moment
-   * @param {object} $element
-   * @param {string} locale
-   */
-  DateTimePicker.initializeField = function(moment, $element, locale) {
-    var format = DateTimePicker.options.format;
-    var type = $element.data('dateType');
-    var options = {
-      sideBySide: true,
-      showTodayButton: true,
-      toolbarPlacement: 'bottom',
-      icons: {
-        time: 'fa fa-clock-o',
-        date: 'fa fa-calendar',
-        up: 'fa fa-chevron-up',
-        down: 'fa fa-chevron-down',
-        previous: 'fa fa-chevron-left',
-        next: 'fa fa-chevron-right',
-        today: 'fa fa-calendar-o',
-        clear: 'fa fa-trash'
-      }
-    };
-
-    // set options based on type
-    switch (type) {
-      case 'datetime':
-        options.format = format[1];
-        break;
-      case 'date':
-        options.format = format[0];
-        break;
-      case 'time':
-        options.format = 'HH:mm';
-        break;
-      case 'timesec':
-        options.format = 'HH:mm:ss';
-        break;
-      case 'year':
-        options.format = 'YYYY';
-        break;
-    }
-
-    // datepicker expects the min and max dates to be formatted with options.format but unix timestamp given
-    if ($element.data('dateMindate')) {
-      $element.data('dateMindate', moment.unix($element.data('dateMindate')).format(options.format));
-    }
-    if ($element.data('dateMaxdate')) {
-      $element.data('dateMaxdate', moment.unix($element.data('dateMaxdate')).format(options.format));
-    }
-
-    if (locale) {
-      options.locale = locale;
-    }
-
-    // initialize the date time picker on this element
-    $element.datetimepicker(options);
-  };
-
-  /**
-   * Format a given date for the hidden FormEngine field
-   *
-   * Format the value for the hidden field that is passed on to the backend, i.e. most likely DataHandler.
-   * The format for that is the timestamp for time fields, and a full-blown ISO-8601 timestamp for all date-related fields.
-   *
-   * @param {moment} date
-   * @param {string} type Type of the date
-   * @returns {string}
-   */
-  DateTimePicker.formatDateForHiddenField = function(date, type) {
-    if (type === 'time' || type === 'timesec') {
-      date.year(1970).month(0).date(1);
-    }
-    return date.format();
-  };
-
-  $(DateTimePicker.initialize);
-  return DateTimePicker;
-});
+define(["require","exports","jquery","moment","./Storage/Persistent"],function(a,b,c,d,e){"use strict";var f=function(){function b(){var a=this;this.fieldSelector=".t3js-datetimepicker",this.format=(null!=opener&&"undefined"!=typeof opener.top.TYPO3?opener.top:top).TYPO3.settings.DateTimePicker.DateFormat,c(function(){a.initialize()})}return b.formatDateForHiddenField=function(a,b){return"time"!==b&&"timesec"!==b||a.year(1970).month(0).date(1),a.format()},b.prototype.initialize=function(){var f=this,g=c(this.fieldSelector).filter(function(a,b){return"undefined"==typeof c(b).data("DateTimePicker")});g.length>0&&a(["twbs/bootstrap-datetimepicker"],function(){var a=e.get("lang");"ch"===a&&(a="zh-cn");var h=!!a&&d.locale(a);g.each(function(a,b){f.initializeField(c(b),h)}),g.on("blur",function(a){var e=c(a.currentTarget),f=e.parent().parent().find('input[type="hidden"]');if(""===e.val())f.val("");else{var g=e.data("dateType"),h=e.data("DateTimePicker").format(),i=d.utc(e.val(),h);i.isValid()?f.val(b.formatDateForHiddenField(i,g)):e.val(b.formatDateForHiddenField(d.utc(f.val()),g))}}),g.on("dp.change",function(a){var d=c(a.currentTarget),e=d.parent().parent().find("input[type=hidden]"),g=d.data("dateType"),h="";""!==d.val()&&(h=b.formatDateForHiddenField(a.date.utc(),g)),e.val(h),c(document).trigger("formengine.dp.change",[c(f)])})})},b.prototype.initializeField=function(a,b){var c=this.format,e=a.data("dateType"),f={format:"",locale:"",sideBySide:!0,showTodayButton:!0,toolbarPlacement:"bottom",icons:{time:"fa fa-clock-o",date:"fa fa-calendar",up:"fa fa-chevron-up",down:"fa fa-chevron-down",previous:"fa fa-chevron-left",next:"fa fa-chevron-right",today:"fa fa-calendar-o",clear:"fa fa-trash"}};switch(e){case"datetime":f.format=c[1];break;case"date":f.format=c[0];break;case"time":f.format="HH:mm";break;case"timesec":f.format="HH:mm:ss";break;case"year":f.format="YYYY"}a.data("dateMindate")&&a.data("dateMindate",d.unix(a.data("dateMindate")).format(f.format)),a.data("dateMaxdate")&&a.data("dateMaxdate",d.unix(a.data("dateMaxdate")).format(f.format)),b&&(f.locale=b),a.datetimepicker(f)},b}();return new f});
\ No newline at end of file