8c396726f5a4fa3078797f2c9c118cd1f1d13d2f
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Public / JavaScript / DateTimePicker.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/Backend/DateTimePicker
16 * contains all logic for the date time picker used in FormEngine
17 * and EXT:belog and EXT:scheduler
18 */
19 define(['jquery'], function($) {
20 "use strict";
21
22 /**
23 * @type {{options: {fieldSelector: string, format: *}}}
24 * @exports TYPO3/CMS/Backend/DateTimePicker
25 */
26 var DateTimePicker = {
27 options: {
28 fieldSelector: '.t3js-datetimepicker',
29 format: (opener != null && typeof opener.top.TYPO3 !== 'undefined' ? opener.top : top).TYPO3.settings.DateTimePicker.DateFormat
30 }
31 };
32
33 /**
34 * initialize date fields to add a datepicker to each field
35 * note: this function can be called multiple times (e.g. after AJAX requests) because it only
36 * applies to fields which haven't been used yet.
37 */
38 DateTimePicker.initialize = function() {
39 // fetch the date time fields that haven't been initialized yet
40 var $dateTimeFields = $(DateTimePicker.options.fieldSelector).filter(function() {
41 return $(this).data('DateTimePicker') === undefined;
42 });
43
44 if ($dateTimeFields.length > 0) {
45 require(['moment', 'TYPO3/CMS/Backend/Storage', 'twbs/bootstrap-datetimepicker'], function(moment, Storage) {
46 var userLocale = Storage.Persistent.get('lang');
47 var setLocale = userLocale ? moment.locale(userLocale) : false;
48
49 // initialize the datepicker on each selected element
50 $dateTimeFields.each(function() {
51 DateTimePicker.initializeField(moment, $(this), setLocale);
52 });
53
54 $dateTimeFields.on('blur', function() {
55 var $element = $(this);
56 var $hiddenField = $element.parent().parent().find('input[type=hidden]');
57
58 if ($element.val() === '') {
59 $hiddenField.val('');
60 } else {
61 var type = $element.data('dateType');
62 var format = $element.data('DateTimePicker').format();
63 var date = moment.utc($element.val(), format);
64 if (date.isValid()) {
65 $hiddenField.val(DateTimePicker.formatDateForHiddenField(date, type));
66 } else {
67 $element.val(DateTimePicker.formatDateForHiddenField(moment.utc($hiddenField.val()), type));
68 }
69 }
70 });
71
72 // on datepicker change, write the selected date with the timezone offset to the hidden field
73 $dateTimeFields.on('dp.change', function(evt) {
74 var $element = $(this);
75 var $hiddenField = $element.parent().parent().find('input[type=hidden]');
76 var type = $element.data('dateType');
77 var value = '';
78
79 if ($element.val() !== '') {
80 value = DateTimePicker.formatDateForHiddenField(evt.date.utc(), type);
81 }
82 $hiddenField.val(value);
83
84 $(document).trigger('formengine.dp.change', [$(this)]);
85 });
86 });
87 }
88 };
89
90 /**
91 * Initialize a single field
92 *
93 * @param {moment} moment
94 * @param {object} $element
95 * @param {string} locale
96 */
97 DateTimePicker.initializeField = function(moment, $element, locale) {
98 var format = DateTimePicker.options.format;
99 var type = $element.data('dateType');
100 var options = {
101 sideBySide: true,
102 icons: {
103 time: 'fa fa-clock-o',
104 date: 'fa fa-calendar',
105 up: 'fa fa-chevron-up',
106 down: 'fa fa-chevron-down',
107 previous: 'fa fa-chevron-left',
108 next: 'fa fa-chevron-right',
109 today: 'fa fa-calendar-o',
110 clear: 'fa fa-trash'
111 }
112 };
113
114 // set options based on type
115 switch (type) {
116 case 'datetime':
117 options.format = format[1];
118 break;
119 case 'date':
120 options.format = format[0];
121 break;
122 case 'time':
123 options.format = 'HH:mm';
124 break;
125 case 'timesec':
126 options.format = 'HH:mm:ss';
127 break;
128 case 'year':
129 options.format = 'YYYY';
130 break;
131 }
132
133 // datepicker expects the min and max dates to be formatted with options.format but unix timestamp given
134 if ($element.data('dateMindate')) {
135 $element.data('dateMindate', moment.unix($element.data('dateMindate')).format(options.format));
136 }
137 if ($element.data('dateMaxdate')) {
138 $element.data('dateMaxdate', moment.unix($element.data('dateMaxdate')).format(options.format));
139 }
140
141 if (locale) {
142 options.locale = locale;
143 }
144
145 // initialize the date time picker on this element
146 $element.datetimepicker(options);
147 };
148
149 /**
150 * Format a given date for the hidden FormEngine field
151 *
152 * Format the value for the hidden field that is passed on to the backend, i.e. most likely DataHandler.
153 * The format for that is the timestamp for time fields, and a full-blown ISO-8601 timestamp for all date-related fields.
154 *
155 * @param {moment} date
156 * @param {string} type Type of the date
157 * @returns {string}
158 */
159 DateTimePicker.formatDateForHiddenField = function(date, type) {
160 if (type === 'time' || type === 'timesec') {
161 date.year(1970).month(0).date(1);
162 }
163 return date.format();
164 };
165
166 $(DateTimePicker.initialize);
167 return DateTimePicker;
168 });