6fbb0e0fa1dfff5896ffad72ed7dd1f9f76a528e
[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
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 = false;
48 if (userLocale) {
49 setLocale = moment.locale(userLocale);
50 }
51
52 // initialize the datepicker on each selected element
53 $dateTimeFields.each(function() {
54 var $element = $(this);
55 var format = DateTimePicker.options.format;
56 var type = $element.data('dateType');
57 var options = {
58 sideBySide: true,
59 icons: {
60 time: 'fa fa-clock-o',
61 date: 'fa fa-calendar',
62 up: 'fa fa-chevron-up',
63 down: 'fa fa-chevron-down',
64 previous: 'fa fa-chevron-left',
65 next: 'fa fa-chevron-right',
66 today: 'fa fa-calendar-o',
67 clear: 'fa fa-trash'
68 }
69 };
70
71 // set options based on type
72 switch (type) {
73 case 'datetime':
74 options.format = format[1];
75 break;
76 case 'date':
77 options.format = format[0];
78 break;
79 case 'time':
80 options.format = 'HH:mm';
81 break;
82 case 'timesec':
83 options.format = 'HH:mm:ss';
84 break;
85 case 'year':
86 options.format = 'YYYY';
87 break;
88 }
89
90 // datepicker expects the min and max dates to be formatted with options.format but unix timestamp given
91 if ($element.data('dateMindate')) {
92 $element.data('dateMindate', moment.unix($element.data('dateMindate')).format(options.format));
93 }
94 if ($element.data('dateMaxdate')) {
95 $element.data('dateMaxdate', moment.unix($element.data('dateMaxdate')).format(options.format));
96 }
97
98 if (setLocale) {
99 options.locale = setLocale;
100 }
101
102 // initialize the date time picker on this element
103 $element.datetimepicker(options);
104 });
105
106 $dateTimeFields.on('blur', function(event) {
107 var $element = $(this);
108 var $hiddenField = $element.parent().parent().find('input[type=hidden]');
109
110 if ($element.val() === '') {
111 $hiddenField.val('');
112 } else {
113 var format = $element.data('DateTimePicker').format();
114 var date = moment.utc($element.val(), format);
115 var calculateTimeZoneOffset = $element.data('date-offset');
116 var timeZoneOffset;
117
118 if (typeof calculateTimeZoneOffset !== 'undefined') {
119 timeZoneOffset = parseInt(calculateTimeZoneOffset);
120 } else {
121 timeZoneOffset = date.utcOffset() * 60 * -1;
122 }
123
124 if (date.isValid()) {
125 var value;
126 // Format the value for the hidden field that is passed on to the backend, i.e. most likely DataHandler.
127 // The format for that is the timestamp for time fields, and a full-blown ISO-8601 timestamp for all
128 // date-related fields.
129 switch ($element.data('dateType')) {
130 case 'time':
131 value = date.format('HH:mm');
132 break;
133 case 'timesec':
134 value = date.format('HH:mm:ss');
135 break;
136 default:
137 value = date.format();
138 }
139 $hiddenField.val(value);
140 } else {
141 $element.val(moment($hiddenField.val()).utc().format(format));
142 }
143 }
144 });
145
146 // on datepicker change, write the selected date with the timezone offset to the hidden field
147 $dateTimeFields.on('dp.change', function(event) {
148 var $element = $(this);
149 var $hiddenField = $element.parent().parent().find('input[type=hidden]');
150
151 if ($element.val() === '') {
152 $hiddenField.val('');
153 } else {
154 var date = event.date.utc();
155
156 var calculateTimeZoneOffset = $element.data('date-offset');
157 var timeZoneOffset, value;
158 if (typeof calculateTimeZoneOffset !== 'undefined') {
159 timeZoneOffset = parseInt(calculateTimeZoneOffset);
160 } else {
161 timeZoneOffset = date.utcOffset() * 60 * -1;
162 }
163
164 switch ($element.data('dateType')) {
165 case 'time':
166 value = date.format('HH:mm');
167 break;
168 case 'timesec':
169 value = date.format('HH:mm:ss');
170 break;
171 default:
172 value = date.format();
173 }
174 $hiddenField.val(value);
175 }
176 });
177 });
178 }
179 };
180
181 DateTimePicker.initialize();
182 return DateTimePicker;
183 });