2 * @preserve jQuery DateTimePicker plugin v2.4.0
3 * @homepage http://xdsoft.net/jqplugins/datetimepicker/
4 * (c) 2014, Chupurnov Valeriy.
6 /*global document,window,jQuery,setTimeout,clearTimeout*/
9 var default_options = {
13 "كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
16 "ن", "ث", "ع", "خ", "ج", "س", "ح"
21 "ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"
24 "l", "ma", "mi", "j", "v", "s", "d"
29 "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"
32 "Sen", "Sel", "Rab", "Kam", "Jum", "Sab", "Min"
37 "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
40 "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
43 fa: { // Persian/Farsi
45 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
48 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
53 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
56 "Вск", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
61 'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
64 "Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
69 "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
72 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
77 "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
80 "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
85 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
88 "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
93 "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
96 "zo", "ma", "di", "wo", "do", "vr", "za"
101 "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
104 "Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
109 "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
112 "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
117 "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
120 "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
125 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
128 'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
133 "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
136 "nd", "pn", "wt", "śr", "cz", "pt", "sb"
141 "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
144 "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
147 ch: { // Simplified Chinese
149 "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
152 "日", "一", "二", "三", "四", "五", "六"
157 "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
160 "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
165 "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
168 "일", "월", "화", "수", "목", "금", "토"
173 "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
176 "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
181 "January", "Februar", "Marts", "April", "Maj", "Juni", "July", "August", "September", "Oktober", "November", "December"
184 "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
189 "Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
192 "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
197 "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
200 "日", "月", "火", "水", "木", "金", "土"
205 "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"
208 "CN", "T2", "T3", "T4", "T5", "T6", "T7"
213 "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"
216 "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
221 "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
224 "Ne", "Po", "Út", "St", "Čt", "Pá", "So"
229 "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
232 "Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
243 startDate: false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
245 monthChangeSpinner: true,
247 closeOnDateSelect: false,
248 closeOnWithoutClick: true,
249 closeOnInputClick: true,
255 defaultTime: false, // use formatTime format (ex. '10:00' for formatTime: 'H:i')
256 defaultDate: false, // use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
269 onSelectDate: function () {},
270 onSelectTime: function () {},
271 onChangeMonth: function () {},
272 onChangeYear: function () {},
273 onChangeDateTime: function () {},
274 onShow: function () {},
275 onClose: function () {},
276 onGenerate: function () {},
278 withoutCopyright: true,
279 inverseButton: false,
282 prev : 'xdsoft_prev',
285 timeHeightInTimePicker: 25,
286 timepickerScrollbar: true,
296 validateOnBlur: true,
303 roundTime: 'round', // ceil, floor
313 if (!Array.prototype.indexOf) {
314 Array.prototype.indexOf = function (obj, start) {
316 for (i = (start || 0), j = this.length; i < j; i += 1) {
317 if (this[i] === obj) { return i; }
322 Date.prototype.countDaysInMonth = function () {
323 return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
325 $.fn.xdsoftScroller = function (percent) {
326 return this.each(function () {
327 var timeboxparent = $(this),
328 pointerEventToXY = function (e) {
329 var out = {x: 0, y: 0},
331 if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
332 touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
333 out.x = touch.clientX;
334 out.y = touch.clientY;
335 } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
354 calcOffset = function () {};
355 if (percent === 'hide') {
356 timeboxparent.find('.xdsoft_scrollbar').hide();
359 if (!$(this).hasClass('xdsoft_scroller_box')) {
360 timebox = timeboxparent.children().eq(0);
361 parentHeight = timeboxparent[0].clientHeight;
362 height = timebox[0].offsetHeight;
363 scrollbar = $('<div class="xdsoft_scrollbar"></div>');
364 scroller = $('<div class="xdsoft_scroller"></div>');
365 scrollbar.append(scroller);
367 timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
368 calcOffset = function calcOffset(event) {
369 var offset = pointerEventToXY(event).y - startY + startTopScroll;
373 if (offset + scroller[0].offsetHeight > h1) {
374 offset = h1 - scroller[0].offsetHeight;
376 timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]);
380 .on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) {
382 timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
385 startY = pointerEventToXY(event).y;
386 startTopScroll = parseInt(scroller.css('margin-top'), 10);
387 h1 = scrollbar[0].offsetHeight;
389 if (event.type === 'mousedown') {
391 $(document.body).addClass('xdsoft_noselect');
393 $([document.body, window]).on('mouseup.xdsoft_scroller', function arguments_callee() {
394 $([document.body, window]).off('mouseup.xdsoft_scroller', arguments_callee)
395 .off('mousemove.xdsoft_scroller', calcOffset)
396 .removeClass('xdsoft_noselect');
398 $(document.body).on('mousemove.xdsoft_scroller', calcOffset);
401 event.stopPropagation();
402 event.preventDefault();
405 .on('touchmove', function (event) {
407 event.preventDefault();
411 .on('touchend touchcancel', function (event) {
417 .on('scroll_element.xdsoft_scroller', function (event, percentage) {
419 timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]);
421 percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage;
423 scroller.css('margin-top', maximumOffset * percentage);
425 setTimeout(function () {
426 timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10));
429 .on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) {
431 parentHeight = timeboxparent[0].clientHeight;
432 height = timebox[0].offsetHeight;
433 percent = parentHeight / height;
434 sh = percent * scrollbar[0].offsetHeight;
439 scroller.css('height', parseInt(sh > 10 ? sh : 10, 10));
440 maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
441 if (noTriggerScroll !== true) {
442 timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]);
447 timeboxparent.on('mousewheel', function (event) {
448 var top = Math.abs(parseInt(timebox.css('marginTop'), 10));
450 top = top - (event.deltaY * 20);
455 timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]);
456 event.stopPropagation();
460 timeboxparent.on('touchstart', function (event) {
461 start = pointerEventToXY(event);
462 startTop = Math.abs(parseInt(timebox.css('marginTop'), 10));
465 timeboxparent.on('touchmove', function (event) {
467 event.preventDefault();
468 var coord = pointerEventToXY(event);
469 timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]);
473 timeboxparent.on('touchend touchcancel', function (event) {
478 timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
482 $.fn.datetimepicker = function (opt) {
504 options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options),
507 createDateTimePicker,
508 destroyDateTimePicker,
511 lazyInit = function (input) {
513 .on('open.xdsoft focusin.xdsoft mousedown.xdsoft', function initOnActionCallback(event) {
514 if (input.is(':disabled') || input.is(':hidden') || !input.is(':visible') || input.data('xdsoft_datetimepicker')) {
517 clearTimeout(lazyInitTimer);
518 lazyInitTimer = setTimeout(function () {
520 if (!input.data('xdsoft_datetimepicker')) {
521 createDateTimePicker(input);
524 .off('open.xdsoft focusin.xdsoft mousedown.xdsoft', initOnActionCallback)
525 .trigger('open.xdsoft');
530 createDateTimePicker = function (input) {
531 var datetimepicker = $('<div ' + (options.id ? 'id="' + options.id + '"' : '') + ' ' + (options.style ? 'style="' + options.style + '"' : '') + ' class="xdsoft_datetimepicker xdsoft_' + options.theme + ' xdsoft_noselect ' + (options.weeks ? ' xdsoft_showweeks' : '') + options.className + '"></div>'),
532 xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
533 datepicker = $('<div class="xdsoft_datepicker active"></div>'),
534 mounth_picker = $('<div class="xdsoft_mounthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
535 '<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
536 '<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
537 '<button type="button" class="xdsoft_next"></button></div>'),
538 calendar = $('<div class="xdsoft_calendar"></div>'),
539 timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),
540 timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
541 timebox = $('<div class="xdsoft_time_variant"></div>'),
542 /*scrollbar = $('<div class="xdsoft_scrollbar"></div>'),
543 scroller = $('<div class="xdsoft_scroller"></div>'),*/
544 monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
545 yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
546 triggerAfterOpen = false,
557 .find('.xdsoft_month span')
560 .find('.xdsoft_year span')
564 .find('.xdsoft_month,.xdsoft_year')
565 .on('mousedown.xdsoft', function (event) {
566 var select = $(this).find('.xdsoft_select').eq(0),
569 visible = select.is(':visible'),
574 .find('.xdsoft_select')
576 if (_xdsoft_datetime.currentTime) {
577 val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear']();
580 select[visible ? 'hide' : 'show']();
581 for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) {
582 if (items.eq(i).data('value') === val) {
585 top += items[0].offsetHeight;
589 select.xdsoftScroller(top / (select.children()[0].offsetHeight - (select[0].clientHeight)));
590 event.stopPropagation();
595 .find('.xdsoft_select')
597 .on('mousedown.xdsoft', function (event) {
598 event.stopPropagation();
599 event.preventDefault();
601 .on('mousedown.xdsoft', '.xdsoft_option', function (event) {
602 var year = _xdsoft_datetime.currentTime.getFullYear();
603 if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
604 _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value'));
607 $(this).parent().parent().hide();
609 datetimepicker.trigger('xchange.xdsoft');
610 if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
611 options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
614 if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
615 options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
619 datetimepicker.setOptions = function (_options) {
620 options = $.extend(true, {}, options, _options);
622 if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
623 options.allowTimes = $.extend(true, [], _options.allowTimes);
626 if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) {
627 options.weekends = $.extend(true, [], _options.weekends);
630 if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) {
631 options.disabledDates = $.extend(true, [], _options.disabledDates);
634 if ((options.open || options.opened) && (!options.inline)) {
635 input.trigger('open.xdsoft');
638 if (options.inline) {
639 triggerAfterOpen = true;
640 datetimepicker.addClass('xdsoft_inline');
641 input.after(datetimepicker).hide();
644 if (options.inverseButton) {
645 options.next = 'xdsoft_prev';
646 options.prev = 'xdsoft_next';
649 if (options.datepicker) {
650 datepicker.addClass('active');
652 datepicker.removeClass('active');
655 if (options.timepicker) {
656 timepicker.addClass('active');
658 timepicker.removeClass('active');
662 if (input && input.val) {
663 input.val(options.value);
665 _xdsoft_datetime.setCurrentTime(options.value);
668 if (isNaN(options.dayOfWeekStart)) {
669 options.dayOfWeekStart = 0;
671 options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7;
674 if (!options.timepickerScrollbar) {
675 timeboxparent.xdsoftScroller('hide');
678 if (options.minDate && /^-(.*)$/.test(options.minDate)) {
679 options.minDate = _xdsoft_datetime.strToDateTime(options.minDate).dateFormat(options.formatDate);
682 if (options.maxDate && /^\+(.*)$/.test(options.maxDate)) {
683 options.maxDate = _xdsoft_datetime.strToDateTime(options.maxDate).dateFormat(options.formatDate);
687 .find('.xdsoft_today_button')
688 .css('visibility', !options.todayButton ? 'hidden' : 'visible');
692 getCaretPos = function (input) {
694 if (document.selection && document.selection.createRange) {
695 var range = document.selection.createRange();
696 return range.getBookmark().charCodeAt(2) - 2;
698 if (input.setSelectionRange) {
699 return input.selectionStart;
705 setCaretPos = function (node, pos) {
706 node = (typeof node === "string" || node instanceof String) ? document.getElementById(node) : node;
710 if (node.createTextRange) {
711 var textRange = node.createTextRange();
712 textRange.collapse(true);
713 textRange.moveEnd('character', pos);
714 textRange.moveStart('character', pos);
718 if (node.setSelectionRange) {
719 node.setSelectionRange(pos, pos);
724 isValidValue = function (mask, value) {
726 .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
727 .replace(/_/g, '{digit+}')
728 .replace(/([0-9]{1})/g, '{digit$1}')
729 .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
730 .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
731 return (new RegExp(reg)).test(value);
733 input.off('keydown.xdsoft');
735 if (options.mask === true) {
736 options.mask = options.format
737 .replace(/Y/g, '9999')
738 .replace(/F/g, '9999')
743 .replace(/s/g, '59');
746 if ($.type(options.mask) === 'string') {
747 if (!isValidValue(options.mask, input.val())) {
748 input.val(options.mask.replace(/[0-9]/g, '_'));
751 input.on('keydown.xdsoft', function (event) {
752 var val = this.value,
757 if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) {
758 pos = getCaretPos(this);
759 digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_';
761 if ((key === BACKSPACE || key === DEL) && pos) {
766 while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
767 pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
770 val = val.substr(0, pos) + digit + val.substr(pos + 1);
771 if ($.trim(val) === '') {
772 val = options.mask.replace(/[0-9]/g, '_');
774 if (pos === options.mask.length) {
775 event.preventDefault();
780 pos += (key === BACKSPACE || key === DEL) ? 0 : 1;
781 while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
782 pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
785 if (isValidValue(options.mask, val)) {
787 setCaretPos(this, pos);
788 } else if ($.trim(val) === '') {
789 this.value = options.mask.replace(/[0-9]/g, '_');
791 input.trigger('error_input.xdsoft');
794 if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
799 event.preventDefault();
804 if (options.validateOnBlur) {
807 .on('blur.xdsoft', function () {
808 if (options.allowBlank && !$.trim($(this).val()).length) {
810 datetimepicker.data('xdsoft_datetime').empty();
811 } else if (!Date.parseDate($(this).val(), options.format)) {
812 $(this).val((_xdsoft_datetime.now()).dateFormat(options.format));
813 datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
815 datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
817 datetimepicker.trigger('changedatetime.xdsoft');
820 options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
823 .trigger('xchange.xdsoft')
824 .trigger('afterOpen.xdsoft');
828 .data('options', options)
829 .on('mousedown.xdsoft', function (event) {
830 event.stopPropagation();
831 event.preventDefault();
837 //scroll_element = timepicker.find('.xdsoft_time_box');
838 timeboxparent.append(timebox);
839 timeboxparent.xdsoftScroller();
841 datetimepicker.on('afterOpen.xdsoft', function () {
842 timeboxparent.xdsoftScroller();
849 if (options.withoutCopyright !== true) {
851 .append(xdsoft_copyright);
855 .append(mounth_picker)
859 .append(datetimepicker);
861 XDSoft_datetime = function () {
863 _this.now = function (norecursion) {
868 if (!norecursion && options.defaultDate) {
869 date = _this.strToDate(options.defaultDate);
870 d.setFullYear(date.getFullYear());
871 d.setMonth(date.getMonth());
872 d.setDate(date.getDate());
875 if (options.yearOffset) {
876 d.setFullYear(d.getFullYear() + options.yearOffset);
879 if (!norecursion && options.defaultTime) {
880 time = _this.strtotime(options.defaultTime);
881 d.setHours(time.getHours());
882 d.setMinutes(time.getMinutes());
888 _this.isValidDate = function (d) {
889 if (Object.prototype.toString.call(d) !== "[object Date]") {
892 return !isNaN(d.getTime());
895 _this.setCurrentTime = function (dTime) {
896 _this.currentTime = (typeof dTime === 'string') ? _this.strToDateTime(dTime) : _this.isValidDate(dTime) ? dTime : _this.now();
897 datetimepicker.trigger('xchange.xdsoft');
900 _this.empty = function () {
901 _this.currentTime = null;
904 _this.getCurrentTime = function (dTime) {
905 return _this.currentTime;
908 _this.nextMonth = function () {
909 var month = _this.currentTime.getMonth() + 1,
912 _this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1);
916 year = _this.currentTime.getFullYear();
918 _this.currentTime.setDate(
920 new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
921 _this.currentTime.getDate()
924 _this.currentTime.setMonth(month);
926 if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
927 options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
930 if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
931 options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
934 datetimepicker.trigger('xchange.xdsoft');
938 _this.prevMonth = function () {
939 var month = _this.currentTime.getMonth() - 1;
941 _this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1);
944 _this.currentTime.setDate(
946 new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
947 _this.currentTime.getDate()
950 _this.currentTime.setMonth(month);
951 if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
952 options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
954 datetimepicker.trigger('xchange.xdsoft');
958 _this.getWeekOfYear = function (datetime) {
959 var onejan = new Date(datetime.getFullYear(), 0, 1);
960 return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7);
963 _this.strToDateTime = function (sDateTime) {
964 var tmpDate = [], timeOffset, currentTime;
966 if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) {
970 tmpDate = /^(\+|\-)(.*)$/.exec(sDateTime);
972 tmpDate[2] = Date.parseDate(tmpDate[2], options.formatDate);
974 if (tmpDate && tmpDate[2]) {
975 timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
976 currentTime = new Date((_xdsoft_datetime.now()).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset);
978 currentTime = sDateTime ? Date.parseDate(sDateTime, options.format) : _this.now();
981 if (!_this.isValidDate(currentTime)) {
982 currentTime = _this.now();
988 _this.strToDate = function (sDate) {
989 if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) {
993 var currentTime = sDate ? Date.parseDate(sDate, options.formatDate) : _this.now(true);
994 if (!_this.isValidDate(currentTime)) {
995 currentTime = _this.now(true);
1000 _this.strtotime = function (sTime) {
1001 if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) {
1004 var currentTime = sTime ? Date.parseDate(sTime, options.formatTime) : _this.now(true);
1005 if (!_this.isValidDate(currentTime)) {
1006 currentTime = _this.now(true);
1011 _this.str = function () {
1012 return _this.currentTime.dateFormat(options.format);
1014 _this.currentTime = this.now();
1017 _xdsoft_datetime = new XDSoft_datetime();
1020 .find('.xdsoft_today_button')
1021 .on('mousedown.xdsoft', function () {
1022 datetimepicker.data('changed', true);
1023 _xdsoft_datetime.setCurrentTime(0);
1024 datetimepicker.trigger('afterOpen.xdsoft');
1025 }).on('dblclick.xdsoft', function () {
1026 input.val(_xdsoft_datetime.str());
1027 datetimepicker.trigger('close.xdsoft');
1030 .find('.xdsoft_prev,.xdsoft_next')
1031 .on('mousedown.xdsoft', function () {
1032 var $this = $(this),
1036 (function arguments_callee1(v) {
1037 var month = _xdsoft_datetime.currentTime.getMonth();
1038 if ($this.hasClass(options.next)) {
1039 _xdsoft_datetime.nextMonth();
1040 } else if ($this.hasClass(options.prev)) {
1041 _xdsoft_datetime.prevMonth();
1043 if (options.monthChangeSpinner) {
1045 timer = setTimeout(arguments_callee1, v || 100);
1050 $([document.body, window]).on('mouseup.xdsoft', function arguments_callee2() {
1051 clearTimeout(timer);
1053 $([document.body, window]).off('mouseup.xdsoft', arguments_callee2);
1058 .find('.xdsoft_prev,.xdsoft_next')
1059 .on('mousedown.xdsoft', function () {
1060 var $this = $(this),
1064 (function arguments_callee4(v) {
1065 var pheight = timeboxparent[0].clientHeight,
1066 height = timebox[0].offsetHeight,
1067 top = Math.abs(parseInt(timebox.css('marginTop'), 10));
1068 if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) {
1069 timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px');
1070 } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
1071 timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
1073 timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox.css('marginTop'), 10) / (height - pheight))]);
1074 period = (period > 10) ? 10 : period - 10;
1076 timer = setTimeout(arguments_callee4, v || period);
1079 $([document.body, window]).on('mouseup.xdsoft', function arguments_callee5() {
1080 clearTimeout(timer);
1082 $([document.body, window])
1083 .off('mouseup.xdsoft', arguments_callee5);
1088 // base handler - generating a calendar and timepicker
1090 .on('xchange.xdsoft', function (event) {
1091 clearTimeout(xchangeTimer);
1092 xchangeTimer = setTimeout(function () {
1094 start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0),
1097 today = _xdsoft_datetime.now(),
1111 while (start.getDay() !== options.dayOfWeekStart) {
1112 start.setDate(start.getDate() - 1);
1115 table += '<table><thead><tr>';
1117 if (options.weeks) {
1118 table += '<th></th>';
1121 for (j = 0; j < 7; j += 1) {
1122 table += '<th>' + options.i18n[options.lang].dayOfWeek[(j + options.dayOfWeekStart) % 7] + '</th>';
1125 table += '</tr></thead>';
1128 if (options.maxDate !== false) {
1129 maxDate = _xdsoft_datetime.strToDate(options.maxDate);
1130 maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
1133 if (options.minDate !== false) {
1134 minDate = _xdsoft_datetime.strToDate(options.minDate);
1135 minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
1138 while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
1142 d = start.getDate();
1143 y = start.getFullYear();
1144 m = start.getMonth();
1145 w = _xdsoft_datetime.getWeekOfYear(start);
1147 classes.push('xdsoft_date');
1149 if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) {
1150 customDateSettings = options.beforeShowDay.call(datetimepicker, start);
1152 customDateSettings = null;
1155 if ((maxDate !== false && start > maxDate) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) {
1156 classes.push('xdsoft_disabled');
1157 } else if (options.disabledDates.indexOf(start.dateFormat(options.formatDate)) !== -1) {
1158 classes.push('xdsoft_disabled');
1161 if (customDateSettings && customDateSettings[1] !== "") {
1162 classes.push(customDateSettings[1]);
1165 if (_xdsoft_datetime.currentTime.getMonth() !== m) {
1166 classes.push('xdsoft_other_month');
1169 if ((options.defaultSelect || datetimepicker.data('changed')) && _xdsoft_datetime.currentTime.dateFormat(options.formatDate) === start.dateFormat(options.formatDate)) {
1170 classes.push('xdsoft_current');
1173 if (today.dateFormat(options.formatDate) === start.dateFormat(options.formatDate)) {
1174 classes.push('xdsoft_today');
1177 if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(start.dateFormat(options.formatDate)) === -1) {
1178 classes.push('xdsoft_weekend');
1181 if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) {
1182 classes.push(options.beforeShowDay(start));
1188 if (options.weeks) {
1189 table += '<th>' + w + '</th>';
1193 table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '">' +
1194 '<div>' + d + '</div>' +
1197 if (start.getDay() === options.dayOfWeekStartPrev) {
1202 start.setDate(d + 1);
1204 table += '</tbody></table>';
1206 calendar.html(table);
1208 mounth_picker.find('.xdsoft_label span').eq(0).text(options.i18n[options.lang].months[_xdsoft_datetime.currentTime.getMonth()]);
1209 mounth_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear());
1215 line_time = function line_time(h, m) {
1216 var now = _xdsoft_datetime.now();
1218 h = parseInt(now.getHours(), 10);
1220 m = parseInt(now.getMinutes(), 10);
1223 if ((options.maxTime !== false && _xdsoft_datetime.strtotime(options.maxTime).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime(options.minTime).getTime() > now.getTime())) {
1224 classes.push('xdsoft_disabled');
1226 if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && parseInt(_xdsoft_datetime.currentTime.getHours(), 10) === parseInt(h, 10) && (options.step > 59 || Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step === parseInt(m, 10))) {
1227 if (options.defaultSelect || datetimepicker.data('changed')) {
1228 classes.push('xdsoft_current');
1229 } else if (options.initTime) {
1230 classes.push('xdsoft_init_time');
1233 if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) {
1234 classes.push('xdsoft_today');
1236 time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + now.dateFormat(options.formatTime) + '</div>';
1239 if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) {
1240 for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
1241 for (j = 0; j < 60; j += options.step) {
1242 h = (i < 10 ? '0' : '') + i;
1243 m = (j < 10 ? '0' : '') + j;
1248 for (i = 0; i < options.allowTimes.length; i += 1) {
1249 h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
1250 m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
1260 for (i = parseInt(options.yearStart, 10) + options.yearOffset; i <= parseInt(options.yearEnd, 10) + options.yearOffset; i += 1) {
1261 opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + i + '</div>';
1263 yearselect.children().eq(0)
1266 for (i = 0, opt = ''; i <= 11; i += 1) {
1267 opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[options.lang].months[i] + '</div>';
1269 monthselect.children().eq(0).html(opt);
1271 .trigger('generate.xdsoft');
1273 event.stopPropagation();
1275 .on('afterOpen.xdsoft', function () {
1276 if (options.timepicker) {
1277 var classType, pheight, height, top;
1278 if (timebox.find('.xdsoft_current').length) {
1279 classType = '.xdsoft_current';
1280 } else if (timebox.find('.xdsoft_init_time').length) {
1281 classType = '.xdsoft_init_time';
1284 pheight = timeboxparent[0].clientHeight;
1285 height = timebox[0].offsetHeight;
1286 top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1;
1287 if ((height - pheight) < top) {
1288 top = height - pheight;
1290 timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]);
1292 timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]);
1299 .on('click.xdsoft', 'td', function (xdevent) {
1300 xdevent.stopPropagation(); // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
1302 var $this = $(this),
1303 currentTime = _xdsoft_datetime.currentTime;
1305 if (currentTime === undefined || currentTime === null) {
1306 _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1307 currentTime = _xdsoft_datetime.currentTime;
1310 if ($this.hasClass('xdsoft_disabled')) {
1314 currentTime.setDate(1);
1315 currentTime.setFullYear($this.data('year'));
1316 currentTime.setMonth($this.data('month'));
1317 currentTime.setDate($this.data('date'));
1319 datetimepicker.trigger('select.xdsoft', [currentTime]);
1321 input.val(_xdsoft_datetime.str());
1322 if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === 0 && !options.timepicker))) && !options.inline) {
1323 datetimepicker.trigger('close.xdsoft');
1326 if (options.onSelectDate && $.isFunction(options.onSelectDate)) {
1327 options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
1330 datetimepicker.data('changed', true);
1331 datetimepicker.trigger('xchange.xdsoft');
1332 datetimepicker.trigger('changedatetime.xdsoft');
1333 setTimeout(function () {
1339 .on('click.xdsoft', 'div', function (xdevent) {
1340 xdevent.stopPropagation();
1341 var $this = $(this),
1342 currentTime = _xdsoft_datetime.currentTime;
1344 if (currentTime === undefined || currentTime === null) {
1345 _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1346 currentTime = _xdsoft_datetime.currentTime;
1349 if ($this.hasClass('xdsoft_disabled')) {
1352 currentTime.setHours($this.data('hour'));
1353 currentTime.setMinutes($this.data('minute'));
1354 datetimepicker.trigger('select.xdsoft', [currentTime]);
1356 datetimepicker.data('input').val(_xdsoft_datetime.str());
1357 if (!options.inline) {
1358 datetimepicker.trigger('close.xdsoft');
1361 if (options.onSelectTime && $.isFunction(options.onSelectTime)) {
1362 options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
1364 datetimepicker.data('changed', true);
1365 datetimepicker.trigger('xchange.xdsoft');
1366 datetimepicker.trigger('changedatetime.xdsoft');
1371 .on('mousewheel.xdsoft', function (event) {
1372 if (!options.scrollMonth) {
1375 if (event.deltaY < 0) {
1376 _xdsoft_datetime.nextMonth();
1378 _xdsoft_datetime.prevMonth();
1384 .on('mousewheel.xdsoft', function (event) {
1385 if (!options.scrollInput) {
1388 if (!options.datepicker && options.timepicker) {
1389 current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0;
1390 if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
1391 current_time_index += event.deltaY;
1393 if (timebox.children().eq(current_time_index).length) {
1394 timebox.children().eq(current_time_index).trigger('mousedown');
1398 if (options.datepicker && !options.timepicker) {
1399 datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]);
1401 input.val(_xdsoft_datetime.str());
1403 datetimepicker.trigger('changedatetime.xdsoft');
1409 .on('changedatetime.xdsoft', function (event) {
1410 if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) {
1411 var $input = datetimepicker.data('input');
1412 options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event);
1413 delete options.value;
1414 $input.trigger('change');
1417 .on('generate.xdsoft', function () {
1418 if (options.onGenerate && $.isFunction(options.onGenerate)) {
1419 options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1421 if (triggerAfterOpen) {
1422 datetimepicker.trigger('afterOpen.xdsoft');
1423 triggerAfterOpen = false;
1426 .on('click.xdsoft', function (xdevent) {
1427 xdevent.stopPropagation();
1430 current_time_index = 0;
1432 setPos = function () {
1433 var offset = datetimepicker.data('input').offset(), top = offset.top + datetimepicker.data('input')[0].offsetHeight - 1, left = offset.left, position = "absolute";
1434 if (options.fixed) {
1435 top -= $(window).scrollTop();
1436 left -= $(window).scrollLeft();
1439 if (top + datetimepicker[0].offsetHeight > $(window).height() + $(window).scrollTop()) {
1440 top = offset.top - datetimepicker[0].offsetHeight + 1;
1445 if (left + datetimepicker[0].offsetWidth > $(window).width()) {
1446 left = $(window).width() - datetimepicker[0].offsetWidth;
1449 datetimepicker.css({
1456 .on('open.xdsoft', function (event) {
1458 if (options.onShow && $.isFunction(options.onShow)) {
1459 onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
1461 if (onShow !== false) {
1462 datetimepicker.show();
1465 .off('resize.xdsoft', setPos)
1466 .on('resize.xdsoft', setPos);
1468 if (options.closeOnWithoutClick) {
1469 $([document.body, window]).on('mousedown.xdsoft', function arguments_callee6() {
1470 datetimepicker.trigger('close.xdsoft');
1471 $([document.body, window]).off('mousedown.xdsoft', arguments_callee6);
1476 .on('close.xdsoft', function (event) {
1479 .find('.xdsoft_month,.xdsoft_year')
1480 .find('.xdsoft_select')
1482 if (options.onClose && $.isFunction(options.onClose)) {
1483 onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
1485 if (onClose !== false && !options.opened && !options.inline) {
1486 datetimepicker.hide();
1488 event.stopPropagation();
1490 .on('toggle.xdsoft', function (event) {
1491 datetimepicker.is(':visible') ? datetimepicker.trigger('close.xdsoft') : datetimepicker.trigger('open.xdsoft');
1493 .data('input', input);
1498 datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
1499 datetimepicker.setOptions(options);
1501 function getCurrentValue() {
1503 var ct = false, time;
1505 if (options.startDate) {
1506 ct = _xdsoft_datetime.strToDate(options.startDate);
1508 ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
1510 ct = _xdsoft_datetime.strToDateTime(ct);
1511 } else if (options.defaultDate) {
1512 ct = _xdsoft_datetime.strToDate(options.defaultDate);
1513 if (options.defaultTime) {
1514 time = _xdsoft_datetime.strtotime(options.defaultTime);
1515 ct.setHours(time.getHours());
1516 ct.setMinutes(time.getMinutes());
1521 if (ct && _xdsoft_datetime.isValidDate(ct)) {
1522 datetimepicker.data('changed', true);
1530 _xdsoft_datetime.setCurrentTime(getCurrentValue());
1533 .data('xdsoft_datetimepicker', datetimepicker)
1534 .on('open.xdsoft focusin.xdsoft mousedown.xdsoft', function (event) {
1535 if (input.is(':disabled') || input.is(':hidden') || !input.is(':visible') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
1538 clearTimeout(timer);
1539 timer = setTimeout(function () {
1540 if (input.is(':disabled') || input.is(':hidden') || !input.is(':visible')) {
1544 triggerAfterOpen = true;
1545 _xdsoft_datetime.setCurrentTime(getCurrentValue());
1547 datetimepicker.trigger('open.xdsoft');
1550 .on('keydown.xdsoft', function (event) {
1551 var val = this.value, elementSelector,
1553 if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
1554 elementSelector = $("input:visible,textarea:visible");
1555 datetimepicker.trigger('close.xdsoft');
1556 elementSelector.eq(elementSelector.index(this) + 1).focus();
1559 if ([TAB].indexOf(key) !== -1) {
1560 datetimepicker.trigger('close.xdsoft');
1565 destroyDateTimePicker = function (input) {
1566 var datetimepicker = input.data('xdsoft_datetimepicker');
1567 if (datetimepicker) {
1568 datetimepicker.data('xdsoft_datetime', null);
1569 datetimepicker.remove();
1571 .data('xdsoft_datetimepicker', null)
1573 $(window).off('resize.xdsoft');
1574 $([window, document.body]).off('mousedown.xdsoft');
1575 if (input.unmousewheel) {
1576 input.unmousewheel();
1581 .off('keydown.xdsoftctrl keyup.xdsoftctrl')
1582 .on('keydown.xdsoftctrl', function (e) {
1583 if (e.keyCode === CTRLKEY) {
1587 .on('keyup.xdsoftctrl', function (e) {
1588 if (e.keyCode === CTRLKEY) {
1592 return this.each(function () {
1593 var datetimepicker = $(this).data('xdsoft_datetimepicker');
1594 if (datetimepicker) {
1595 if ($.type(opt) === 'string') {
1598 $(this).select().focus();
1599 datetimepicker.trigger('open.xdsoft');
1602 datetimepicker.trigger('close.xdsoft');
1605 datetimepicker.trigger('toggle.xdsoft');
1608 destroyDateTimePicker($(this));
1611 this.value = this.defaultValue;
1612 if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(Date.parseDate(this.value, options.format))) {
1613 datetimepicker.data('changed', false);
1615 datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
1624 if ($.type(opt) !== 'string') {
1625 if (!options.lazyInit || options.open || options.inline) {
1626 createDateTimePicker($(this));
1633 $.fn.datetimepicker.defaults = default_options;
1637 /*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
1638 * Licensed under the MIT License (LICENSE.txt).
1642 * Requires: jQuery 1.2.2+
1644 !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});
1646 // Parse and Format Library
1647 //http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/
1649 * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
1651 * This program is free software; you can redistribute it and/or modify it
1652 * under the terms of the GNU Lesser General Public License as published by the
1653 * Free Software Foundation, version 2.1.
1655 * This program is distributed in the hope that it will be useful, but WITHOUT
1656 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1657 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
1660 Date.parseFunctions={count:0};Date.parseRegexes=[];Date.formatFunctions={count:0};Date.prototype.dateFormat=function(b){if(b=="unixtime"){return parseInt(this.getTime()/1000);}if(Date.formatFunctions[b]==null){Date.createNewFormat(b);}var a=Date.formatFunctions[b];return this[a]();};Date.createNewFormat=function(format){var funcName="format"+Date.formatFunctions.count++;Date.formatFunctions[format]=funcName;var code="Date.prototype."+funcName+" = function() {return ";var special=false;var ch="";for(var i=0;i<format.length;++i){ch=format.charAt(i);if(!special&&ch=="\\"){special=true;}else{if(special){special=false;code+="'"+String.escape(ch)+"' + ";}else{code+=Date.getFormatCode(ch);}}}eval(code.substring(0,code.length-3)+";}");};Date.getFormatCode=function(a){switch(a){case"d":return"String.leftPad(this.getDate(), 2, '0') + ";case"D":return"Date.dayNames[this.getDay()].substring(0, 3) + ";case"j":return"this.getDate() + ";case"l":return"Date.dayNames[this.getDay()] + ";case"S":return"this.getSuffix() + ";case"w":return"this.getDay() + ";case"z":return"this.getDayOfYear() + ";case"W":return"this.getWeekOfYear() + ";case"F":return"Date.monthNames[this.getMonth()] + ";case"m":return"String.leftPad(this.getMonth() + 1, 2, '0') + ";case"M":return"Date.monthNames[this.getMonth()].substring(0, 3) + ";case"n":return"(this.getMonth() + 1) + ";case"t":return"this.getDaysInMonth() + ";case"L":return"(this.isLeapYear() ? 1 : 0) + ";case"Y":return"this.getFullYear() + ";case"y":return"('' + this.getFullYear()).substring(2, 4) + ";case"a":return"(this.getHours() < 12 ? 'am' : 'pm') + ";case"A":return"(this.getHours() < 12 ? 'AM' : 'PM') + ";case"g":return"((this.getHours() %12) ? this.getHours() % 12 : 12) + ";case"G":return"this.getHours() + ";case"h":return"String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";case"H":return"String.leftPad(this.getHours(), 2, '0') + ";case"i":return"String.leftPad(this.getMinutes(), 2, '0') + ";case"s":return"String.leftPad(this.getSeconds(), 2, '0') + ";case"O":return"this.getGMTOffset() + ";case"T":return"this.getTimezone() + ";case"Z":return"(this.getTimezoneOffset() * -60) + ";default:return"'"+String.escape(a)+"' + ";}};Date.parseDate=function(a,c){if(c=="unixtime"){return new Date(!isNaN(parseInt(a))?parseInt(a)*1000:0);}if(Date.parseFunctions[c]==null){Date.createParser(c);}var b=Date.parseFunctions[c];return Date[b](a);};Date.createParser=function(format){var funcName="parse"+Date.parseFunctions.count++;var regexNum=Date.parseRegexes.length;var currentGroup=1;Date.parseFunctions[format]=funcName;var code="Date."+funcName+" = function(input) {\nvar y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, z = -1;\nvar d = new Date();\ny = d.getFullYear();\nm = d.getMonth();\nd = d.getDate();\nvar results = input.match(Date.parseRegexes["+regexNum+"]);\nif (results && results.length > 0) {";var regex="";var special=false;var ch="";for(var i=0;i<format.length;++i){ch=format.charAt(i);if(!special&&ch=="\\"){special=true;}else{if(special){special=false;regex+=String.escape(ch);}else{obj=Date.formatCodeToRegex(ch,currentGroup);currentGroup+=obj.g;regex+=obj.s;if(obj.g&&obj.c){code+=obj.c;}}}}code+="if (y > 0 && z > 0){\nvar doyDate = new Date(y,0);\ndoyDate.setDate(z);\nm = doyDate.getMonth();\nd = doyDate.getDate();\n}";code+="if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n{return new Date(y, m, d, h, i, s);}\nelse if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n{return new Date(y, m, d, h, i);}\nelse if (y > 0 && m >= 0 && d > 0 && h >= 0)\n{return new Date(y, m, d, h);}\nelse if (y > 0 && m >= 0 && d > 0)\n{return new Date(y, m, d);}\nelse if (y > 0 && m >= 0)\n{return new Date(y, m);}\nelse if (y > 0)\n{return new Date(y);}\n}return null;}";Date.parseRegexes[regexNum]=new RegExp("^"+regex+"$");eval(code);};Date.formatCodeToRegex=function(b,a){switch(b){case"D":return{g:0,c:null,s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};case"j":case"d":return{g:1,c:"d = parseInt(results["+a+"], 10);\n",s:"(\\d{1,2})"};case"l":return{g:0,c:null,s:"(?:"+Date.dayNames.join("|")+")"};case"S":return{g:0,c:null,s:"(?:st|nd|rd|th)"};case"w":return{g:0,c:null,s:"\\d"};case"z":return{g:1,c:"z = parseInt(results["+a+"], 10);\n",s:"(\\d{1,3})"};case"W":return{g:0,c:null,s:"(?:\\d{2})"};case"F":return{g:1,c:"m = parseInt(Date.monthNumbers[results["+a+"].substring(0, 3)], 10);\n",s:"("+Date.monthNames.join("|")+")"};case"M":return{g:1,c:"m = parseInt(Date.monthNumbers[results["+a+"]], 10);\n",s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};case"n":case"m":return{g:1,c:"m = parseInt(results["+a+"], 10) - 1;\n",s:"(\\d{1,2})"};case"t":return{g:0,c:null,s:"\\d{1,2}"};case"L":return{g:0,c:null,s:"(?:1|0)"};case"Y":return{g:1,c:"y = parseInt(results["+a+"], 10);\n",s:"(\\d{4})"};case"y":return{g:1,c:"var ty = parseInt(results["+a+"], 10);\ny = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"};case"a":return{g:1,c:"if (results["+a+"] == 'am') {\nif (h == 12) { h = 0; }\n} else { if (h < 12) { h += 12; }}",s:"(am|pm)"};case"A":return{g:1,c:"if (results["+a+"] == 'AM') {\nif (h == 12) { h = 0; }\n} else { if (h < 12) { h += 12; }}",s:"(AM|PM)"};case"g":case"G":case"h":case"H":return{g:1,c:"h = parseInt(results["+a+"], 10);\n",s:"(\\d{1,2})"};case"i":return{g:1,c:"i = parseInt(results["+a+"], 10);\n",s:"(\\d{2})"};case"s":return{g:1,c:"s = parseInt(results["+a+"], 10);\n",s:"(\\d{2})"};case"O":return{g:0,c:null,s:"[+-]\\d{4}"};case"T":return{g:0,c:null,s:"[A-Z]{3}"};case"Z":return{g:0,c:null,s:"[+-]\\d{1,5}"};default:return{g:0,c:null,s:String.escape(b)};}};Date.prototype.getTimezone=function(){return this.toString().replace(/^.*? ([A-Z]{3}) [0-9]{4}.*$/,"$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/,"$1$2$3");};Date.prototype.getGMTOffset=function(){return(this.getTimezoneOffset()>0?"-":"+")+String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset())/60),2,"0")+String.leftPad(Math.abs(this.getTimezoneOffset())%60,2,"0");};Date.prototype.getDayOfYear=function(){var a=0;Date.daysInMonth[1]=this.isLeapYear()?29:28;for(var b=0;b<this.getMonth();++b){a+=Date.daysInMonth[b];}return a+this.getDate();};Date.prototype.getWeekOfYear=function(){var b=this.getDayOfYear()+(4-this.getDay());var a=new Date(this.getFullYear(),0,1);var c=(7-a.getDay()+4);return String.leftPad(Math.ceil((b-c)/7)+1,2,"0");};Date.prototype.isLeapYear=function(){var a=this.getFullYear();return((a&3)==0&&(a%100||(a%400==0&&a)));};Date.prototype.getFirstDayOfMonth=function(){var a=(this.getDay()-(this.getDate()-1))%7;return(a<0)?(a+7):a;};Date.prototype.getLastDayOfMonth=function(){var a=(this.getDay()+(Date.daysInMonth[this.getMonth()]-this.getDate()))%7;return(a<0)?(a+7):a;};Date.prototype.getDaysInMonth=function(){Date.daysInMonth[1]=this.isLeapYear()?29:28;return Date.daysInMonth[this.getMonth()];};Date.prototype.getSuffix=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};String.escape=function(a){return a.replace(/('|\\)/g,"\\$1");};String.leftPad=function(d,b,c){var a=new String(d);if(c==null){c=" ";}while(a.length<b){a=c+a;}return a;};Date.daysInMonth=[31,28,31,30,31,30,31,31,30,31,30,31];Date.monthNames=["January","February","March","April","May","June","July","August","September","October","November","December"];Date.dayNames=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];Date.y2kYear=50;Date.monthNumbers={Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11};Date.patterns={ISO8601LongPattern:"Y-m-d H:i:s",ISO8601ShortPattern:"Y-m-d",ShortDatePattern:"n/j/Y",LongDatePattern:"l, F d, Y",FullDateTimePattern:"l, F d, Y g:i:s A",MonthDayPattern:"F d",ShortTimePattern:"g:i A",LongTimePattern:"g:i:s A",SortableDateTimePattern:"Y-m-d\\TH:i:s",UniversalSortableDateTimePattern:"Y-m-d H:i:sO",YearMonthPattern:"F, Y"};