kadmin 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aaddff71053969c92febee026a1d06d73baaef7c359997a982412f9a4675d383
4
- data.tar.gz: 1e5439fc82c78d2296c50a04d3e0c6440901e46dd43dc6bf91dccbbeff930784
3
+ metadata.gz: 8c6153d0dc1a36c9b7066b1fa6a030a9891047f57a89d759e9016d08dcfdc416
4
+ data.tar.gz: 705b7ea2a3955b239c5cbeda6b220767644df8c1c7dd12453ca890eafa54f314
5
5
  SHA512:
6
- metadata.gz: ece854403c51a63b594e33dbace25cf6f173ed859db515b5bbbd375b06c6f0dd568ca243981e3618654497fd1b53febcd5a98e41b8f3bd6a548962814b420f59
7
- data.tar.gz: 1997775cd1c4a39d7d61a0fbcfdd82799812bb91ae2544386456e8de882efb0597b85f6ac650e34e7592fb40b567787002760cabab45adc374f9d20040df1a4e
6
+ metadata.gz: ebf43f06633696960d75bc86f3ab3a5536125b00d8b3e4164c8fd94100dc04f424faa6701ebcb9c8d6efa294f8ef701bde701abbdface9e462e488bdcee7ca26
7
+ data.tar.gz: c3a1f72368a014697ce3d83f0babe9a942aae39a1956d0ff9a9fcb92c52c9a742924352d3580189db2a709b473e070040a5ea0510a4734dff31659c84b367cb1
@@ -1,6 +1,7 @@
1
1
  //= require modular
2
2
  //= require jquery_ujs
3
3
  //= require_tree .
4
+ //= require jquery.datetimepicker.full
4
5
 
5
6
  // sortable tables
6
7
 
@@ -1,10 +1,12 @@
1
1
  //*= require modular
2
2
  //*= require_self
3
+ //*= require jquery.datetimepicker
3
4
 
4
5
  // sass-lint:disable no-color-literals
5
6
 
6
7
  // Wrap everything in a .kadmin class to ensure our styling always overrides everyone else
7
8
  .kadmin {
9
+
8
10
  a.titlelink { // sass-lint:disable-line no-qualifying-elements force-element-nesting
9
11
  color: #fff;
10
12
  font-weight: bold;
@@ -106,8 +108,25 @@
106
108
  top: 0;
107
109
  }
108
110
  }
111
+
109
112
  pre {
110
113
  background-color: #f0f3f6;
111
114
  padding: 10px;
112
115
  }
116
+
117
+ // custom css
118
+ .required-field::before {
119
+ content: " * ";
120
+ color: red;
121
+ }
122
+
123
+ .wrap {
124
+ white-space: pre-wrap; /* CSS3 */
125
+ white-space: -moz-pre-wrap; /* Firefox */
126
+ white-space: -pre-wrap; /* Opera <7 */
127
+ white-space: -o-pre-wrap; /* Opera 7 */
128
+ word-wrap: break-word; /* IE */
129
+ }
130
+
113
131
  }
132
+
@@ -34,5 +34,35 @@ module Kadmin
34
34
 
35
35
  return content_tag(:div, button + list, class: 'dropdown', style: 'display: inline-block;')
36
36
  end
37
+
38
+ # Generates help assitance using bootstrap i.e. * for mendatory feilds, help icon and popover for help
39
+ # @param [String] label text for the view
40
+ # @param [String] label_for is ID of the html element for which we are displaying label.
41
+ # @param [Boolean] Display the red asteric to indicate mendatory field.
42
+ # @param [Boolean] to decide weither we need to display the help iocn or not
43
+ # @param [String] Title of the popover
44
+ # @param [String] Body text of popover
45
+ # @param [String] classname for the label.
46
+ def help_assistance(label, label_for = "", required = false, display_help = true, title = "", message = "", label_class = 'control-label')
47
+ label = t(label)
48
+ label = label.html_safe
49
+
50
+ require_html = required ? '<span class="required-field"><span>':''
51
+ icon_html = "<i class='fa fa-question-circle' style='color:green'></i>"
52
+
53
+ display_message = ""
54
+ if display_help
55
+ message = t(message)
56
+ message = message.gsub('"', '\"')
57
+ message = message.gsub("'", "\'")
58
+ html_message = message.html_safe
59
+
60
+ title = t(title)
61
+ title = title.html_safe
62
+ display_message = "<span data-toggle='popover' title='#{title}' data-placement='top' data-trigger='hover' data-content='#{html_message}'>#{icon_html}</span>"
63
+ end
64
+
65
+ return "<label for='#{label_for}' class='#{label_class}'' >#{require_html}#{label} #{display_message}</label>".html_safe
66
+ end
37
67
  end
38
68
  end
@@ -98,6 +98,11 @@
98
98
  <script type='text/javascript'>
99
99
  jQuery(document).ready(function () {
100
100
  jQuery('#sidebar-menu').metisMenu({ activeClass: 'open' });
101
+ jQuery('[data-toggle="tooltip"]').tooltip(
102
+ {html:true, container:'body', trigger: 'hover', placement:"bottom"}
103
+ );
104
+ jQuery('[data-toggle="popover"]').popover({html:true});
105
+ jQuery('#scheduled_at').datetimepicker({ mask:'9999/19/39 29:59', minDate: 0});
101
106
  });
102
107
  </script>
103
108
  <%= yield :javascripts %>
@@ -1,3 +1,3 @@
1
1
  module Kadmin
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.2.0'.freeze
3
3
  end
@@ -0,0 +1,2911 @@
1
+ /*!
2
+ * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014 - 2016
3
+ * @version 1.3.4
4
+ *
5
+ * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format.
6
+ * @see http://php.net/manual/en/function.date.php
7
+ *
8
+ * For more JQuery plugins visit http://plugins.krajee.com
9
+ * For more Yii related demos visit http://demos.krajee.com
10
+ */var DateFormatter;!function(){"use strict";var t,e,r,n,a,u,i;u=864e5,i=3600,t=function(t,e){return"string"==typeof t&&"string"==typeof e&&t.toLowerCase()===e.toLowerCase()},e=function(t,r,n){var a=n||"0",u=t.toString();return u.length<r?e(a+u,r):u},r=function(t){var e,n;for(t=t||{},e=1;e<arguments.length;e++)if(n=arguments[e])for(var a in n)n.hasOwnProperty(a)&&("object"==typeof n[a]?r(t[a],n[a]):t[a]=n[a]);return t},n=function(t,e){for(var r=0;r<e.length;r++)if(e[r].toLowerCase()===t.toLowerCase())return r;return-1},a={dateSettings:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["AM","PM"],ordinal:function(t){var e=t%10,r={1:"st",2:"nd",3:"rd"};return 1!==Math.floor(t%100/10)&&r[e]?r[e]:"th"}},separators:/[ \-+\/\.T:@]/g,validParts:/[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g,intParts:/[djwNzmnyYhHgGis]/g,tzParts:/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,tzClip:/[^-+\dA-Z]/g},DateFormatter=function(t){var e=this,n=r(a,t);e.dateSettings=n.dateSettings,e.separators=n.separators,e.validParts=n.validParts,e.intParts=n.intParts,e.tzParts=n.tzParts,e.tzClip=n.tzClip},DateFormatter.prototype={constructor:DateFormatter,getMonth:function(t){var e,r=this;return e=n(t,r.dateSettings.monthsShort)+1,0===e&&(e=n(t,r.dateSettings.months)+1),e},parseDate:function(e,r){var n,a,u,i,s,o,c,f,l,h,d=this,g=!1,m=!1,p=d.dateSettings,y={date:null,year:null,month:null,day:null,hour:0,min:0,sec:0};if(!e)return null;if(e instanceof Date)return e;if("U"===r)return u=parseInt(e),u?new Date(1e3*u):e;switch(typeof e){case"number":return new Date(e);case"string":break;default:return null}if(n=r.match(d.validParts),!n||0===n.length)throw new Error("Invalid date format definition.");for(a=e.replace(d.separators,"\x00").split("\x00"),u=0;u<a.length;u++)switch(i=a[u],s=parseInt(i),n[u]){case"y":case"Y":if(!s)return null;l=i.length,y.year=2===l?parseInt((70>s?"20":"19")+i):s,g=!0;break;case"m":case"n":case"M":case"F":if(isNaN(s)){if(o=d.getMonth(i),!(o>0))return null;y.month=o}else{if(!(s>=1&&12>=s))return null;y.month=s}g=!0;break;case"d":case"j":if(!(s>=1&&31>=s))return null;y.day=s,g=!0;break;case"g":case"h":if(c=n.indexOf("a")>-1?n.indexOf("a"):n.indexOf("A")>-1?n.indexOf("A"):-1,h=a[c],c>-1)f=t(h,p.meridiem[0])?0:t(h,p.meridiem[1])?12:-1,s>=1&&12>=s&&f>-1?y.hour=s+f-1:s>=0&&23>=s&&(y.hour=s);else{if(!(s>=0&&23>=s))return null;y.hour=s}m=!0;break;case"G":case"H":if(!(s>=0&&23>=s))return null;y.hour=s,m=!0;break;case"i":if(!(s>=0&&59>=s))return null;y.min=s,m=!0;break;case"s":if(!(s>=0&&59>=s))return null;y.sec=s,m=!0}if(g===!0&&y.year&&y.month&&y.day)y.date=new Date(y.year,y.month-1,y.day,y.hour,y.min,y.sec,0);else{if(m!==!0)return null;y.date=new Date(0,0,0,y.hour,y.min,y.sec,0)}return y.date},guessDate:function(t,e){if("string"!=typeof t)return t;var r,n,a,u,i,s,o=this,c=t.replace(o.separators,"\x00").split("\x00"),f=/^[djmn]/g,l=e.match(o.validParts),h=new Date,d=0;if(!f.test(l[0]))return t;for(a=0;a<c.length;a++){if(d=2,i=c[a],s=parseInt(i.substr(0,2)),isNaN(s))return null;switch(a){case 0:"m"===l[0]||"n"===l[0]?h.setMonth(s-1):h.setDate(s);break;case 1:"m"===l[0]||"n"===l[0]?h.setDate(s):h.setMonth(s-1);break;case 2:if(n=h.getFullYear(),r=i.length,d=4>r?r:4,n=parseInt(4>r?n.toString().substr(0,4-r)+i:i.substr(0,4)),!n)return null;h.setFullYear(n);break;case 3:h.setHours(s);break;case 4:h.setMinutes(s);break;case 5:h.setSeconds(s)}u=i.substr(d),u.length>0&&c.splice(a+1,0,u)}return h},parseFormat:function(t,r){var n,a=this,s=a.dateSettings,o=/\\?(.?)/gi,c=function(t,e){return n[t]?n[t]():e};return n={d:function(){return e(n.j(),2)},D:function(){return s.daysShort[n.w()]},j:function(){return r.getDate()},l:function(){return s.days[n.w()]},N:function(){return n.w()||7},w:function(){return r.getDay()},z:function(){var t=new Date(n.Y(),n.n()-1,n.j()),e=new Date(n.Y(),0,1);return Math.round((t-e)/u)},W:function(){var t=new Date(n.Y(),n.n()-1,n.j()-n.N()+3),r=new Date(t.getFullYear(),0,4);return e(1+Math.round((t-r)/u/7),2)},F:function(){return s.months[r.getMonth()]},m:function(){return e(n.n(),2)},M:function(){return s.monthsShort[r.getMonth()]},n:function(){return r.getMonth()+1},t:function(){return new Date(n.Y(),n.n(),0).getDate()},L:function(){var t=n.Y();return t%4===0&&t%100!==0||t%400===0?1:0},o:function(){var t=n.n(),e=n.W(),r=n.Y();return r+(12===t&&9>e?1:1===t&&e>9?-1:0)},Y:function(){return r.getFullYear()},y:function(){return n.Y().toString().slice(-2)},a:function(){return n.A().toLowerCase()},A:function(){var t=n.G()<12?0:1;return s.meridiem[t]},B:function(){var t=r.getUTCHours()*i,n=60*r.getUTCMinutes(),a=r.getUTCSeconds();return e(Math.floor((t+n+a+i)/86.4)%1e3,3)},g:function(){return n.G()%12||12},G:function(){return r.getHours()},h:function(){return e(n.g(),2)},H:function(){return e(n.G(),2)},i:function(){return e(r.getMinutes(),2)},s:function(){return e(r.getSeconds(),2)},u:function(){return e(1e3*r.getMilliseconds(),6)},e:function(){var t=/\((.*)\)/.exec(String(r))[1];return t||"Coordinated Universal Time"},I:function(){var t=new Date(n.Y(),0),e=Date.UTC(n.Y(),0),r=new Date(n.Y(),6),a=Date.UTC(n.Y(),6);return t-e!==r-a?1:0},O:function(){var t=r.getTimezoneOffset(),n=Math.abs(t);return(t>0?"-":"+")+e(100*Math.floor(n/60)+n%60,4)},P:function(){var t=n.O();return t.substr(0,3)+":"+t.substr(3,2)},T:function(){var t=(String(r).match(a.tzParts)||[""]).pop().replace(a.tzClip,"");return t||"UTC"},Z:function(){return 60*-r.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(o,c)},r:function(){return"D, d M Y H:i:s O".replace(o,c)},U:function(){return r.getTime()/1e3||0}},c(t,t)},formatDate:function(t,e){var r,n,a,u,i,s=this,o="",c="\\";if("string"==typeof t&&(t=s.parseDate(t,e),!t))return null;if(t instanceof Date){for(a=e.length,r=0;a>r;r++)i=e.charAt(r),"S"!==i&&i!==c&&(r>0&&e.charAt(r-1)===c?o+=i:(u=s.parseFormat(i,t),r!==a-1&&s.intParts.test(i)&&"S"===e.charAt(r+1)&&(n=parseInt(u)||0,u+=s.dateSettings.ordinal(n)),o+=u));return o}return""}}}();/**
11
+ * @preserve jQuery DateTimePicker
12
+ * @homepage http://xdsoft.net/jqplugins/datetimepicker/
13
+ * @author Chupurnov Valeriy (<chupurnov@gmail.com>)
14
+ */
15
+
16
+ /**
17
+ * @param {jQuery} $
18
+ */
19
+ var datetimepickerFactory = function ($) {
20
+ 'use strict';
21
+
22
+ var default_options = {
23
+ i18n: {
24
+ ar: { // Arabic
25
+ months: [
26
+ "كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
27
+ ],
28
+ dayOfWeekShort: [
29
+ "ن", "ث", "ع", "خ", "ج", "س", "ح"
30
+ ],
31
+ dayOfWeek: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"]
32
+ },
33
+ ro: { // Romanian
34
+ months: [
35
+ "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"
36
+ ],
37
+ dayOfWeekShort: [
38
+ "Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ"
39
+ ],
40
+ dayOfWeek: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"]
41
+ },
42
+ id: { // Indonesian
43
+ months: [
44
+ "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"
45
+ ],
46
+ dayOfWeekShort: [
47
+ "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"
48
+ ],
49
+ dayOfWeek: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"]
50
+ },
51
+ is: { // Icelandic
52
+ months: [
53
+ "Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"
54
+ ],
55
+ dayOfWeekShort: [
56
+ "Sun", "Mán", "Þrið", "Mið", "Fim", "Fös", "Lau"
57
+ ],
58
+ dayOfWeek: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"]
59
+ },
60
+ bg: { // Bulgarian
61
+ months: [
62
+ "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
63
+ ],
64
+ dayOfWeekShort: [
65
+ "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
66
+ ],
67
+ dayOfWeek: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"]
68
+ },
69
+ fa: { // Persian/Farsi
70
+ months: [
71
+ 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
72
+ ],
73
+ dayOfWeekShort: [
74
+ 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
75
+ ],
76
+ dayOfWeek: ["یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", "شنبه", "یک‌شنبه"]
77
+ },
78
+ ru: { // Russian
79
+ months: [
80
+ 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
81
+ ],
82
+ dayOfWeekShort: [
83
+ "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
84
+ ],
85
+ dayOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]
86
+ },
87
+ uk: { // Ukrainian
88
+ months: [
89
+ 'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
90
+ ],
91
+ dayOfWeekShort: [
92
+ "Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
93
+ ],
94
+ dayOfWeek: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"]
95
+ },
96
+ en: { // English
97
+ months: [
98
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
99
+ ],
100
+ dayOfWeekShort: [
101
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
102
+ ],
103
+ dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
104
+ },
105
+ el: { // Ελληνικά
106
+ months: [
107
+ "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
108
+ ],
109
+ dayOfWeekShort: [
110
+ "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
111
+ ],
112
+ dayOfWeek: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"]
113
+ },
114
+ de: { // German
115
+ months: [
116
+ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
117
+ ],
118
+ dayOfWeekShort: [
119
+ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
120
+ ],
121
+ dayOfWeek: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
122
+ },
123
+ nl: { // Dutch
124
+ months: [
125
+ "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
126
+ ],
127
+ dayOfWeekShort: [
128
+ "zo", "ma", "di", "wo", "do", "vr", "za"
129
+ ],
130
+ dayOfWeek: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"]
131
+ },
132
+ tr: { // Turkish
133
+ months: [
134
+ "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
135
+ ],
136
+ dayOfWeekShort: [
137
+ "Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
138
+ ],
139
+ dayOfWeek: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"]
140
+ },
141
+ fr: { //French
142
+ months: [
143
+ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
144
+ ],
145
+ dayOfWeekShort: [
146
+ "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
147
+ ],
148
+ dayOfWeek: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
149
+ },
150
+ es: { // Spanish
151
+ months: [
152
+ "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
153
+ ],
154
+ dayOfWeekShort: [
155
+ "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
156
+ ],
157
+ dayOfWeek: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
158
+ },
159
+ th: { // Thai
160
+ months: [
161
+ 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
162
+ ],
163
+ dayOfWeekShort: [
164
+ 'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
165
+ ],
166
+ dayOfWeek: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"]
167
+ },
168
+ pl: { // Polish
169
+ months: [
170
+ "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
171
+ ],
172
+ dayOfWeekShort: [
173
+ "nd", "pn", "wt", "śr", "cz", "pt", "sb"
174
+ ],
175
+ dayOfWeek: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
176
+ },
177
+ pt: { // Portuguese
178
+ months: [
179
+ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
180
+ ],
181
+ dayOfWeekShort: [
182
+ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
183
+ ],
184
+ dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
185
+ },
186
+ ch: { // Simplified Chinese
187
+ months: [
188
+ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
189
+ ],
190
+ dayOfWeekShort: [
191
+ "日", "一", "二", "三", "四", "五", "六"
192
+ ]
193
+ },
194
+ se: { // Swedish
195
+ months: [
196
+ "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
197
+ ],
198
+ dayOfWeekShort: [
199
+ "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
200
+ ]
201
+ },
202
+ km: { // Khmer (ភាសាខ្មែរ)
203
+ months: [
204
+ "មករា​", "កុម្ភៈ", "មិនា​", "មេសា​", "ឧសភា​", "មិថុនា​", "កក្កដា​", "សីហា​", "កញ្ញា​", "តុលា​", "វិច្ឆិកា", "ធ្នូ​"
205
+ ],
206
+ dayOfWeekShort: ["អាទិ​", "ច័ន្ទ​", "អង្គារ​", "ពុធ​", "ព្រហ​​", "សុក្រ​", "សៅរ៍"],
207
+ dayOfWeek: ["អាទិត្យ​", "ច័ន្ទ​", "អង្គារ​", "ពុធ​", "ព្រហស្បតិ៍​", "សុក្រ​", "សៅរ៍"]
208
+ },
209
+ kr: { // Korean
210
+ months: [
211
+ "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
212
+ ],
213
+ dayOfWeekShort: [
214
+ "일", "월", "화", "수", "목", "금", "토"
215
+ ],
216
+ dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
217
+ },
218
+ it: { // Italian
219
+ months: [
220
+ "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
221
+ ],
222
+ dayOfWeekShort: [
223
+ "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
224
+ ],
225
+ dayOfWeek: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]
226
+ },
227
+ da: { // Dansk
228
+ months: [
229
+ "Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"
230
+ ],
231
+ dayOfWeekShort: [
232
+ "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
233
+ ],
234
+ dayOfWeek: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"]
235
+ },
236
+ no: { // Norwegian
237
+ months: [
238
+ "Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
239
+ ],
240
+ dayOfWeekShort: [
241
+ "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
242
+ ],
243
+ dayOfWeek: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag']
244
+ },
245
+ ja: { // Japanese
246
+ months: [
247
+ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
248
+ ],
249
+ dayOfWeekShort: [
250
+ "日", "月", "火", "水", "木", "金", "土"
251
+ ],
252
+ dayOfWeek: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"]
253
+ },
254
+ vi: { // Vietnamese
255
+ months: [
256
+ "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"
257
+ ],
258
+ dayOfWeekShort: [
259
+ "CN", "T2", "T3", "T4", "T5", "T6", "T7"
260
+ ],
261
+ dayOfWeek: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
262
+ },
263
+ sl: { // Slovenščina
264
+ months: [
265
+ "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"
266
+ ],
267
+ dayOfWeekShort: [
268
+ "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
269
+ ],
270
+ dayOfWeek: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"]
271
+ },
272
+ cs: { // Čeština
273
+ months: [
274
+ "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
275
+ ],
276
+ dayOfWeekShort: [
277
+ "Ne", "Po", "Út", "St", "Čt", "Pá", "So"
278
+ ]
279
+ },
280
+ hu: { // Hungarian
281
+ months: [
282
+ "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
283
+ ],
284
+ dayOfWeekShort: [
285
+ "Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
286
+ ],
287
+ dayOfWeek: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"]
288
+ },
289
+ az: { //Azerbaijanian (Azeri)
290
+ months: [
291
+ "Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"
292
+ ],
293
+ dayOfWeekShort: [
294
+ "B", "Be", "Ça", "Ç", "Ca", "C", "Ş"
295
+ ],
296
+ dayOfWeek: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"]
297
+ },
298
+ bs: { //Bosanski
299
+ months: [
300
+ "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
301
+ ],
302
+ dayOfWeekShort: [
303
+ "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
304
+ ],
305
+ dayOfWeek: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
306
+ },
307
+ ca: { //Català
308
+ months: [
309
+ "Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"
310
+ ],
311
+ dayOfWeekShort: [
312
+ "Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds"
313
+ ],
314
+ dayOfWeek: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"]
315
+ },
316
+ 'en-GB': { //English (British)
317
+ months: [
318
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
319
+ ],
320
+ dayOfWeekShort: [
321
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
322
+ ],
323
+ dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
324
+ },
325
+ et: { //"Eesti"
326
+ months: [
327
+ "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"
328
+ ],
329
+ dayOfWeekShort: [
330
+ "P", "E", "T", "K", "N", "R", "L"
331
+ ],
332
+ dayOfWeek: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"]
333
+ },
334
+ eu: { //Euskara
335
+ months: [
336
+ "Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua"
337
+ ],
338
+ dayOfWeekShort: [
339
+ "Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La."
340
+ ],
341
+ dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata']
342
+ },
343
+ fi: { //Finnish (Suomi)
344
+ months: [
345
+ "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"
346
+ ],
347
+ dayOfWeekShort: [
348
+ "Su", "Ma", "Ti", "Ke", "To", "Pe", "La"
349
+ ],
350
+ dayOfWeek: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"]
351
+ },
352
+ gl: { //Galego
353
+ months: [
354
+ "Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec"
355
+ ],
356
+ dayOfWeekShort: [
357
+ "Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab"
358
+ ],
359
+ dayOfWeek: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"]
360
+ },
361
+ hr: { //Hrvatski
362
+ months: [
363
+ "Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"
364
+ ],
365
+ dayOfWeekShort: [
366
+ "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
367
+ ],
368
+ dayOfWeek: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
369
+ },
370
+ ko: { //Korean (한국어)
371
+ months: [
372
+ "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
373
+ ],
374
+ dayOfWeekShort: [
375
+ "일", "월", "화", "수", "목", "금", "토"
376
+ ],
377
+ dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
378
+ },
379
+ lt: { //Lithuanian (lietuvių)
380
+ months: [
381
+ "Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio"
382
+ ],
383
+ dayOfWeekShort: [
384
+ "Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš"
385
+ ],
386
+ dayOfWeek: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"]
387
+ },
388
+ lv: { //Latvian (Latviešu)
389
+ months: [
390
+ "Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"
391
+ ],
392
+ dayOfWeekShort: [
393
+ "Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St"
394
+ ],
395
+ dayOfWeek: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"]
396
+ },
397
+ mk: { //Macedonian (Македонски)
398
+ months: [
399
+ "јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"
400
+ ],
401
+ dayOfWeekShort: [
402
+ "нед", "пон", "вто", "сре", "чет", "пет", "саб"
403
+ ],
404
+ dayOfWeek: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"]
405
+ },
406
+ mn: { //Mongolian (Монгол)
407
+ months: [
408
+ "1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар"
409
+ ],
410
+ dayOfWeekShort: [
411
+ "Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням"
412
+ ],
413
+ dayOfWeek: ["Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба", "Ням"]
414
+ },
415
+ 'pt-BR': { //Português(Brasil)
416
+ months: [
417
+ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
418
+ ],
419
+ dayOfWeekShort: [
420
+ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"
421
+ ],
422
+ dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
423
+ },
424
+ sk: { //Slovenčina
425
+ months: [
426
+ "Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"
427
+ ],
428
+ dayOfWeekShort: [
429
+ "Ne", "Po", "Ut", "St", "Št", "Pi", "So"
430
+ ],
431
+ dayOfWeek: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"]
432
+ },
433
+ sq: { //Albanian (Shqip)
434
+ months: [
435
+ "Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"
436
+ ],
437
+ dayOfWeekShort: [
438
+ "Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu"
439
+ ],
440
+ dayOfWeek: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"]
441
+ },
442
+ 'sr-YU': { //Serbian (Srpski)
443
+ months: [
444
+ "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
445
+ ],
446
+ dayOfWeekShort: [
447
+ "Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub"
448
+ ],
449
+ dayOfWeek: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"]
450
+ },
451
+ sr: { //Serbian Cyrillic (Српски)
452
+ months: [
453
+ "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар"
454
+ ],
455
+ dayOfWeekShort: [
456
+ "нед", "пон", "уто", "сре", "чет", "пет", "суб"
457
+ ],
458
+ dayOfWeek: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"]
459
+ },
460
+ sv: { //Svenska
461
+ months: [
462
+ "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
463
+ ],
464
+ dayOfWeekShort: [
465
+ "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
466
+ ],
467
+ dayOfWeek: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"]
468
+ },
469
+ 'zh-TW': { //Traditional Chinese (繁體中文)
470
+ months: [
471
+ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
472
+ ],
473
+ dayOfWeekShort: [
474
+ "日", "一", "二", "三", "四", "五", "六"
475
+ ],
476
+ dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
477
+ },
478
+ zh: { //Simplified Chinese (简体中文)
479
+ months: [
480
+ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
481
+ ],
482
+ dayOfWeekShort: [
483
+ "日", "一", "二", "三", "四", "五", "六"
484
+ ],
485
+ dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
486
+ },
487
+ ug:{ // Uyghur(ئۇيغۇرچە)
488
+ months: [
489
+ "1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي"
490
+ ],
491
+ dayOfWeek: [
492
+ "يەكشەنبە", "دۈشەنبە","سەيشەنبە","چارشەنبە","پەيشەنبە","جۈمە","شەنبە"
493
+ ]
494
+ },
495
+ he: { //Hebrew (עברית)
496
+ months: [
497
+ 'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
498
+ ],
499
+ dayOfWeekShort: [
500
+ 'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
501
+ ],
502
+ dayOfWeek: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"]
503
+ },
504
+ hy: { // Armenian
505
+ months: [
506
+ "Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"
507
+ ],
508
+ dayOfWeekShort: [
509
+ "Կի", "Երկ", "Երք", "Չոր", "Հնգ", "Ուրբ", "Շբթ"
510
+ ],
511
+ dayOfWeek: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"]
512
+ },
513
+ kg: { // Kyrgyz
514
+ months: [
515
+ 'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'
516
+ ],
517
+ dayOfWeekShort: [
518
+ "Жек", "Дүй", "Шей", "Шар", "Бей", "Жум", "Ише"
519
+ ],
520
+ dayOfWeek: [
521
+ "Жекшемб", "Дүйшөмб", "Шейшемб", "Шаршемб", "Бейшемби", "Жума", "Ишенб"
522
+ ]
523
+ },
524
+ rm: { // Romansh
525
+ months: [
526
+ "Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December"
527
+ ],
528
+ dayOfWeekShort: [
529
+ "Du", "Gli", "Ma", "Me", "Gie", "Ve", "So"
530
+ ],
531
+ dayOfWeek: [
532
+ "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda"
533
+ ]
534
+ },
535
+ ka: { // Georgian
536
+ months: [
537
+ 'იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'
538
+ ],
539
+ dayOfWeekShort: [
540
+ "კვ", "ორშ", "სამშ", "ოთხ", "ხუთ", "პარ", "შაბ"
541
+ ],
542
+ dayOfWeek: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი"]
543
+ }
544
+ },
545
+
546
+ ownerDocument: document,
547
+ contentWindow: window,
548
+
549
+ value: '',
550
+ rtl: false,
551
+
552
+ format: 'Y/m/d H:i',
553
+ formatTime: 'H:i',
554
+ formatDate: 'Y/m/d',
555
+
556
+ startDate: false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
557
+ step: 60,
558
+ monthChangeSpinner: true,
559
+
560
+ closeOnDateSelect: false,
561
+ closeOnTimeSelect: true,
562
+ closeOnWithoutClick: true,
563
+ closeOnInputClick: true,
564
+ openOnFocus: true,
565
+
566
+ timepicker: true,
567
+ datepicker: true,
568
+ weeks: false,
569
+
570
+ defaultTime: false, // use formatTime format (ex. '10:00' for formatTime: 'H:i')
571
+ defaultDate: false, // use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
572
+
573
+ minDate: false,
574
+ maxDate: false,
575
+ minTime: false,
576
+ maxTime: false,
577
+ minDateTime: false,
578
+ maxDateTime: false,
579
+
580
+ allowTimes: [],
581
+ opened: false,
582
+ initTime: true,
583
+ inline: false,
584
+ theme: '',
585
+ touchMovedThreshold: 5,
586
+
587
+ onSelectDate: function () {},
588
+ onSelectTime: function () {},
589
+ onChangeMonth: function () {},
590
+ onGetWeekOfYear: function () {},
591
+ onChangeYear: function () {},
592
+ onChangeDateTime: function () {},
593
+ onShow: function () {},
594
+ onClose: function () {},
595
+ onGenerate: function () {},
596
+
597
+ withoutCopyright: true,
598
+ inverseButton: false,
599
+ hours12: false,
600
+ next: 'xdsoft_next',
601
+ prev : 'xdsoft_prev',
602
+ dayOfWeekStart: 0,
603
+ parentID: 'body',
604
+ timeHeightInTimePicker: 25,
605
+ timepickerScrollbar: true,
606
+ todayButton: true,
607
+ prevButton: true,
608
+ nextButton: true,
609
+ defaultSelect: true,
610
+
611
+ scrollMonth: true,
612
+ scrollTime: true,
613
+ scrollInput: true,
614
+
615
+ lazyInit: false,
616
+ mask: false,
617
+ validateOnBlur: true,
618
+ allowBlank: true,
619
+ yearStart: 1950,
620
+ yearEnd: 2050,
621
+ monthStart: 0,
622
+ monthEnd: 11,
623
+ style: '',
624
+ id: '',
625
+ fixed: false,
626
+ roundTime: 'round', // ceil, floor
627
+ className: '',
628
+ weekends: [],
629
+ highlightedDates: [],
630
+ highlightedPeriods: [],
631
+ allowDates : [],
632
+ allowDateRe : null,
633
+ disabledDates : [],
634
+ disabledWeekDays: [],
635
+ yearOffset: 0,
636
+ beforeShowDay: null,
637
+
638
+ enterLikeTab: true,
639
+ showApplyButton: false,
640
+ insideParent: false,
641
+ };
642
+
643
+ var dateHelper = null,
644
+ defaultDateHelper = null,
645
+ globalLocaleDefault = 'en',
646
+ globalLocale = 'en';
647
+
648
+ var dateFormatterOptionsDefault = {
649
+ meridiem: ['AM', 'PM']
650
+ };
651
+
652
+ var initDateFormatter = function(){
653
+ var locale = default_options.i18n[globalLocale],
654
+ opts = {
655
+ days: locale.dayOfWeek,
656
+ daysShort: locale.dayOfWeekShort,
657
+ months: locale.months,
658
+ monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) })
659
+ };
660
+
661
+ if (typeof DateFormatter === 'function') {
662
+ dateHelper = defaultDateHelper = new DateFormatter({
663
+ dateSettings: $.extend({}, dateFormatterOptionsDefault, opts)
664
+ });
665
+ }
666
+ };
667
+
668
+ var dateFormatters = {
669
+ moment: {
670
+ default_options:{
671
+ format: 'YYYY/MM/DD HH:mm',
672
+ formatDate: 'YYYY/MM/DD',
673
+ formatTime: 'HH:mm',
674
+ },
675
+ formatter: {
676
+ parseDate: function (date, format) {
677
+ if(isFormatStandard(format)){
678
+ return defaultDateHelper.parseDate(date, format);
679
+ }
680
+ var d = moment(date, format);
681
+ return d.isValid() ? d.toDate() : false;
682
+ },
683
+
684
+ formatDate: function (date, format) {
685
+ if(isFormatStandard(format)){
686
+ return defaultDateHelper.formatDate(date, format);
687
+ }
688
+ return moment(date).format(format);
689
+ },
690
+
691
+ formatMask: function(format){
692
+ return format
693
+ .replace(/Y{4}/g, '9999')
694
+ .replace(/Y{2}/g, '99')
695
+ .replace(/M{2}/g, '19')
696
+ .replace(/D{2}/g, '39')
697
+ .replace(/H{2}/g, '29')
698
+ .replace(/m{2}/g, '59')
699
+ .replace(/s{2}/g, '59');
700
+ },
701
+ }
702
+ }
703
+ }
704
+
705
+ // for locale settings
706
+ $.datetimepicker = {
707
+ setLocale: function(locale){
708
+ var newLocale = default_options.i18n[locale] ? locale : globalLocaleDefault;
709
+ if (globalLocale !== newLocale) {
710
+ globalLocale = newLocale;
711
+ // reinit date formatter
712
+ initDateFormatter();
713
+ }
714
+ },
715
+
716
+ setDateFormatter: function(dateFormatter) {
717
+ if(typeof dateFormatter === 'string' && dateFormatters.hasOwnProperty(dateFormatter)){
718
+ var df = dateFormatters[dateFormatter];
719
+ $.extend(default_options, df.default_options);
720
+ dateHelper = df.formatter;
721
+ }
722
+ else {
723
+ dateHelper = dateFormatter;
724
+ }
725
+ },
726
+ };
727
+
728
+ var standardFormats = {
729
+ RFC_2822: 'D, d M Y H:i:s O',
730
+ ATOM: 'Y-m-d\TH:i:sP',
731
+ ISO_8601: 'Y-m-d\TH:i:sO',
732
+ RFC_822: 'D, d M y H:i:s O',
733
+ RFC_850: 'l, d-M-y H:i:s T',
734
+ RFC_1036: 'D, d M y H:i:s O',
735
+ RFC_1123: 'D, d M Y H:i:s O',
736
+ RSS: 'D, d M Y H:i:s O',
737
+ W3C: 'Y-m-d\TH:i:sP'
738
+ }
739
+
740
+ var isFormatStandard = function(format){
741
+ return Object.values(standardFormats).indexOf(format) === -1 ? false : true;
742
+ }
743
+
744
+ $.extend($.datetimepicker, standardFormats);
745
+
746
+ // first init date formatter
747
+ initDateFormatter();
748
+
749
+ // fix for ie8
750
+ if (!window.getComputedStyle) {
751
+ window.getComputedStyle = function (el) {
752
+ this.el = el;
753
+ this.getPropertyValue = function (prop) {
754
+ var re = /(-([a-z]))/g;
755
+ if (prop === 'float') {
756
+ prop = 'styleFloat';
757
+ }
758
+ if (re.test(prop)) {
759
+ prop = prop.replace(re, function (a, b, c) {
760
+ return c.toUpperCase();
761
+ });
762
+ }
763
+ return el.currentStyle[prop] || null;
764
+ };
765
+ return this;
766
+ };
767
+ }
768
+ if (!Array.prototype.indexOf) {
769
+ Array.prototype.indexOf = function (obj, start) {
770
+ var i, j;
771
+ for (i = (start || 0), j = this.length; i < j; i += 1) {
772
+ if (this[i] === obj) { return i; }
773
+ }
774
+ return -1;
775
+ };
776
+ }
777
+
778
+ Date.prototype.countDaysInMonth = function () {
779
+ return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
780
+ };
781
+
782
+ $.fn.xdsoftScroller = function (options, percent) {
783
+ return this.each(function () {
784
+ var timeboxparent = $(this),
785
+ pointerEventToXY = function (e) {
786
+ var out = {x: 0, y: 0},
787
+ touch;
788
+ if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
789
+ touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
790
+ out.x = touch.clientX;
791
+ out.y = touch.clientY;
792
+ } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
793
+ out.x = e.clientX;
794
+ out.y = e.clientY;
795
+ }
796
+ return out;
797
+ },
798
+ timebox,
799
+ parentHeight,
800
+ height,
801
+ scrollbar,
802
+ scroller,
803
+ maximumOffset = 100,
804
+ start = false,
805
+ startY = 0,
806
+ startTop = 0,
807
+ h1 = 0,
808
+ touchStart = false,
809
+ startTopScroll = 0,
810
+ calcOffset = function () {};
811
+
812
+ if (percent === 'hide') {
813
+ timeboxparent.find('.xdsoft_scrollbar').hide();
814
+ return;
815
+ }
816
+
817
+ if (!$(this).hasClass('xdsoft_scroller_box')) {
818
+ timebox = timeboxparent.children().eq(0);
819
+ parentHeight = timeboxparent[0].clientHeight;
820
+ height = timebox[0].offsetHeight;
821
+ scrollbar = $('<div class="xdsoft_scrollbar"></div>');
822
+ scroller = $('<div class="xdsoft_scroller"></div>');
823
+ scrollbar.append(scroller);
824
+
825
+ timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
826
+ calcOffset = function calcOffset(event) {
827
+ var offset = pointerEventToXY(event).y - startY + startTopScroll;
828
+ if (offset < 0) {
829
+ offset = 0;
830
+ }
831
+ if (offset + scroller[0].offsetHeight > h1) {
832
+ offset = h1 - scroller[0].offsetHeight;
833
+ }
834
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]);
835
+ };
836
+
837
+ scroller
838
+ .on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) {
839
+ if (!parentHeight) {
840
+ timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
841
+ }
842
+
843
+ startY = pointerEventToXY(event).y;
844
+ startTopScroll = parseInt(scroller.css('margin-top'), 10);
845
+ h1 = scrollbar[0].offsetHeight;
846
+
847
+ if (event.type === 'mousedown' || event.type === 'touchstart') {
848
+ if (options.ownerDocument) {
849
+ $(options.ownerDocument.body).addClass('xdsoft_noselect');
850
+ }
851
+ $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft_scroller', function arguments_callee() {
852
+ $([options.ownerDocument.body, options.contentWindow]).off('touchend mouseup.xdsoft_scroller', arguments_callee)
853
+ .off('mousemove.xdsoft_scroller', calcOffset)
854
+ .removeClass('xdsoft_noselect');
855
+ });
856
+ $(options.ownerDocument.body).on('mousemove.xdsoft_scroller', calcOffset);
857
+ } else {
858
+ touchStart = true;
859
+ event.stopPropagation();
860
+ event.preventDefault();
861
+ }
862
+ })
863
+ .on('touchmove', function (event) {
864
+ if (touchStart) {
865
+ event.preventDefault();
866
+ calcOffset(event);
867
+ }
868
+ })
869
+ .on('touchend touchcancel', function () {
870
+ touchStart = false;
871
+ startTopScroll = 0;
872
+ });
873
+
874
+ timeboxparent
875
+ .on('scroll_element.xdsoft_scroller', function (event, percentage) {
876
+ if (!parentHeight) {
877
+ timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]);
878
+ }
879
+ percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage;
880
+
881
+ scroller.css('margin-top', maximumOffset * percentage);
882
+
883
+ setTimeout(function () {
884
+ timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10));
885
+ }, 10);
886
+ })
887
+ .on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) {
888
+ var percent, sh;
889
+ parentHeight = timeboxparent[0].clientHeight;
890
+ height = timebox[0].offsetHeight;
891
+ percent = parentHeight / height;
892
+ sh = percent * scrollbar[0].offsetHeight;
893
+ if (percent > 1) {
894
+ scroller.hide();
895
+ } else {
896
+ scroller.show();
897
+ scroller.css('height', parseInt(sh > 10 ? sh : 10, 10));
898
+ maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
899
+ if (noTriggerScroll !== true) {
900
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]);
901
+ }
902
+ }
903
+ });
904
+
905
+ timeboxparent.on('mousewheel', function (event) {
906
+ var top = Math.abs(parseInt(timebox.css('marginTop'), 10));
907
+
908
+ top = top - (event.deltaY * 20);
909
+ if (top < 0) {
910
+ top = 0;
911
+ }
912
+
913
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]);
914
+ event.stopPropagation();
915
+ return false;
916
+ });
917
+
918
+ timeboxparent.on('touchstart', function (event) {
919
+ start = pointerEventToXY(event);
920
+ startTop = Math.abs(parseInt(timebox.css('marginTop'), 10));
921
+ });
922
+
923
+ timeboxparent.on('touchmove', function (event) {
924
+ if (start) {
925
+ event.preventDefault();
926
+ var coord = pointerEventToXY(event);
927
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]);
928
+ }
929
+ });
930
+
931
+ timeboxparent.on('touchend touchcancel', function () {
932
+ start = false;
933
+ startTop = 0;
934
+ });
935
+ }
936
+ timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
937
+ });
938
+ };
939
+
940
+ $.fn.datetimepicker = function (opt, opt2) {
941
+ var result = this,
942
+ KEY0 = 48,
943
+ KEY9 = 57,
944
+ _KEY0 = 96,
945
+ _KEY9 = 105,
946
+ CTRLKEY = 17,
947
+ CMDKEY = 91,
948
+ DEL = 46,
949
+ ENTER = 13,
950
+ ESC = 27,
951
+ BACKSPACE = 8,
952
+ ARROWLEFT = 37,
953
+ ARROWUP = 38,
954
+ ARROWRIGHT = 39,
955
+ ARROWDOWN = 40,
956
+ TAB = 9,
957
+ F5 = 116,
958
+ AKEY = 65,
959
+ CKEY = 67,
960
+ VKEY = 86,
961
+ ZKEY = 90,
962
+ YKEY = 89,
963
+ ctrlDown = false,
964
+ cmdDown = false,
965
+ options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options),
966
+
967
+ lazyInitTimer = 0,
968
+ createDateTimePicker,
969
+ destroyDateTimePicker,
970
+
971
+ lazyInit = function (input) {
972
+ input
973
+ .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback() {
974
+ if (input.is(':disabled') || input.data('xdsoft_datetimepicker')) {
975
+ return;
976
+ }
977
+ clearTimeout(lazyInitTimer);
978
+ lazyInitTimer = setTimeout(function () {
979
+
980
+ if (!input.data('xdsoft_datetimepicker')) {
981
+ createDateTimePicker(input);
982
+ }
983
+ input
984
+ .off('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', initOnActionCallback)
985
+ .trigger('open.xdsoft');
986
+ }, 100);
987
+ });
988
+ };
989
+
990
+ createDateTimePicker = function (input) {
991
+ var datetimepicker = $('<div class="xdsoft_datetimepicker xdsoft_noselect"></div>'),
992
+ xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
993
+ datepicker = $('<div class="xdsoft_datepicker active"></div>'),
994
+ month_picker = $('<div class="xdsoft_monthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
995
+ '<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
996
+ '<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
997
+ '<button type="button" class="xdsoft_next"></button></div>'),
998
+ calendar = $('<div class="xdsoft_calendar"></div>'),
999
+ 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>'),
1000
+ timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
1001
+ timebox = $('<div class="xdsoft_time_variant"></div>'),
1002
+ applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),
1003
+
1004
+ monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
1005
+ yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
1006
+ triggerAfterOpen = false,
1007
+ XDSoft_datetime,
1008
+
1009
+ xchangeTimer,
1010
+ timerclick,
1011
+ current_time_index,
1012
+ setPos,
1013
+ timer = 0,
1014
+ _xdsoft_datetime,
1015
+ forEachAncestorOf;
1016
+
1017
+ if (options.id) {
1018
+ datetimepicker.attr('id', options.id);
1019
+ }
1020
+ if (options.style) {
1021
+ datetimepicker.attr('style', options.style);
1022
+ }
1023
+ if (options.weeks) {
1024
+ datetimepicker.addClass('xdsoft_showweeks');
1025
+ }
1026
+ if (options.rtl) {
1027
+ datetimepicker.addClass('xdsoft_rtl');
1028
+ }
1029
+
1030
+ datetimepicker.addClass('xdsoft_' + options.theme);
1031
+ datetimepicker.addClass(options.className);
1032
+
1033
+ month_picker
1034
+ .find('.xdsoft_month span')
1035
+ .after(monthselect);
1036
+ month_picker
1037
+ .find('.xdsoft_year span')
1038
+ .after(yearselect);
1039
+
1040
+ month_picker
1041
+ .find('.xdsoft_month,.xdsoft_year')
1042
+ .on('touchstart mousedown.xdsoft', function (event) {
1043
+ var select = $(this).find('.xdsoft_select').eq(0),
1044
+ val = 0,
1045
+ top = 0,
1046
+ visible = select.is(':visible'),
1047
+ items,
1048
+ i;
1049
+
1050
+ month_picker
1051
+ .find('.xdsoft_select')
1052
+ .hide();
1053
+ if (_xdsoft_datetime.currentTime) {
1054
+ val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear']();
1055
+ }
1056
+
1057
+ select[visible ? 'hide' : 'show']();
1058
+ for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) {
1059
+ if (items.eq(i).data('value') === val) {
1060
+ break;
1061
+ } else {
1062
+ top += items[0].offsetHeight;
1063
+ }
1064
+ }
1065
+
1066
+ select.xdsoftScroller(options, top / (select.children()[0].offsetHeight - (select[0].clientHeight)));
1067
+ event.stopPropagation();
1068
+ return false;
1069
+ });
1070
+
1071
+ var handleTouchMoved = function (event) {
1072
+ var evt = event.originalEvent;
1073
+ var touchPosition = evt.touches ? evt.touches[0] : evt;
1074
+ this.touchStartPosition = this.touchStartPosition || touchPosition;
1075
+ var xMovement = Math.abs(this.touchStartPosition.clientX - touchPosition.clientX);
1076
+ var yMovement = Math.abs(this.touchStartPosition.clientY - touchPosition.clientY);
1077
+ var distance = Math.sqrt(xMovement * xMovement + yMovement * yMovement);
1078
+ if(distance > options.touchMovedThreshold) {
1079
+ this.touchMoved = true;
1080
+ }
1081
+ }
1082
+
1083
+ month_picker
1084
+ .find('.xdsoft_select')
1085
+ .xdsoftScroller(options)
1086
+ .on('touchstart mousedown.xdsoft', function (event) {
1087
+ var evt = event.originalEvent;
1088
+ this.touchMoved = false;
1089
+ this.touchStartPosition = evt.touches ? evt.touches[0] : evt;
1090
+ event.stopPropagation();
1091
+ event.preventDefault();
1092
+ })
1093
+ .on('touchmove', '.xdsoft_option', handleTouchMoved)
1094
+ .on('touchend mousedown.xdsoft', '.xdsoft_option', function () {
1095
+ if (!this.touchMoved) {
1096
+ if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1097
+ _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1098
+ }
1099
+
1100
+ var year = _xdsoft_datetime.currentTime.getFullYear();
1101
+ if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
1102
+ _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value'));
1103
+ }
1104
+
1105
+ $(this).parent().parent().hide();
1106
+
1107
+ datetimepicker.trigger('xchange.xdsoft');
1108
+ if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
1109
+ options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1110
+ }
1111
+
1112
+ if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
1113
+ options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1114
+ }
1115
+ }
1116
+ });
1117
+
1118
+ datetimepicker.getValue = function () {
1119
+ return _xdsoft_datetime.getCurrentTime();
1120
+ };
1121
+
1122
+ datetimepicker.setOptions = function (_options) {
1123
+ var highlightedDates = {};
1124
+
1125
+ options = $.extend(true, {}, options, _options);
1126
+
1127
+ if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
1128
+ options.allowTimes = $.extend(true, [], _options.allowTimes);
1129
+ }
1130
+
1131
+ if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) {
1132
+ options.weekends = $.extend(true, [], _options.weekends);
1133
+ }
1134
+
1135
+ if (_options.allowDates && $.isArray(_options.allowDates) && _options.allowDates.length) {
1136
+ options.allowDates = $.extend(true, [], _options.allowDates);
1137
+ }
1138
+
1139
+ if (_options.allowDateRe && Object.prototype.toString.call(_options.allowDateRe)==="[object String]") {
1140
+ options.allowDateRe = new RegExp(_options.allowDateRe);
1141
+ }
1142
+
1143
+ if (_options.highlightedDates && $.isArray(_options.highlightedDates) && _options.highlightedDates.length) {
1144
+ $.each(_options.highlightedDates, function (index, value) {
1145
+ var splitData = $.map(value.split(','), $.trim),
1146
+ exDesc,
1147
+ hDate = new HighlightedDate(dateHelper.parseDate(splitData[0], options.formatDate), splitData[1], splitData[2]), // date, desc, style
1148
+ keyDate = dateHelper.formatDate(hDate.date, options.formatDate);
1149
+ if (highlightedDates[keyDate] !== undefined) {
1150
+ exDesc = highlightedDates[keyDate].desc;
1151
+ if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
1152
+ highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
1153
+ }
1154
+ } else {
1155
+ highlightedDates[keyDate] = hDate;
1156
+ }
1157
+ });
1158
+
1159
+ options.highlightedDates = $.extend(true, [], highlightedDates);
1160
+ }
1161
+
1162
+ if (_options.highlightedPeriods && $.isArray(_options.highlightedPeriods) && _options.highlightedPeriods.length) {
1163
+ highlightedDates = $.extend(true, [], options.highlightedDates);
1164
+ $.each(_options.highlightedPeriods, function (index, value) {
1165
+ var dateTest, // start date
1166
+ dateEnd,
1167
+ desc,
1168
+ hDate,
1169
+ keyDate,
1170
+ exDesc,
1171
+ style;
1172
+ if ($.isArray(value)) {
1173
+ dateTest = value[0];
1174
+ dateEnd = value[1];
1175
+ desc = value[2];
1176
+ style = value[3];
1177
+ }
1178
+ else {
1179
+ var splitData = $.map(value.split(','), $.trim);
1180
+ dateTest = dateHelper.parseDate(splitData[0], options.formatDate);
1181
+ dateEnd = dateHelper.parseDate(splitData[1], options.formatDate);
1182
+ desc = splitData[2];
1183
+ style = splitData[3];
1184
+ }
1185
+
1186
+ while (dateTest <= dateEnd) {
1187
+ hDate = new HighlightedDate(dateTest, desc, style);
1188
+ keyDate = dateHelper.formatDate(dateTest, options.formatDate);
1189
+ dateTest.setDate(dateTest.getDate() + 1);
1190
+ if (highlightedDates[keyDate] !== undefined) {
1191
+ exDesc = highlightedDates[keyDate].desc;
1192
+ if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
1193
+ highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
1194
+ }
1195
+ } else {
1196
+ highlightedDates[keyDate] = hDate;
1197
+ }
1198
+ }
1199
+ });
1200
+
1201
+ options.highlightedDates = $.extend(true, [], highlightedDates);
1202
+ }
1203
+
1204
+ if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) {
1205
+ options.disabledDates = $.extend(true, [], _options.disabledDates);
1206
+ }
1207
+
1208
+ if (_options.disabledWeekDays && $.isArray(_options.disabledWeekDays) && _options.disabledWeekDays.length) {
1209
+ options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays);
1210
+ }
1211
+
1212
+ if ((options.open || options.opened) && (!options.inline)) {
1213
+ input.trigger('open.xdsoft');
1214
+ }
1215
+
1216
+ if (options.inline) {
1217
+ triggerAfterOpen = true;
1218
+ datetimepicker.addClass('xdsoft_inline');
1219
+ input.after(datetimepicker).hide();
1220
+ }
1221
+
1222
+ if (options.inverseButton) {
1223
+ options.next = 'xdsoft_prev';
1224
+ options.prev = 'xdsoft_next';
1225
+ }
1226
+
1227
+ if (options.datepicker) {
1228
+ datepicker.addClass('active');
1229
+ } else {
1230
+ datepicker.removeClass('active');
1231
+ }
1232
+
1233
+ if (options.timepicker) {
1234
+ timepicker.addClass('active');
1235
+ } else {
1236
+ timepicker.removeClass('active');
1237
+ }
1238
+
1239
+ if (options.value) {
1240
+ _xdsoft_datetime.setCurrentTime(options.value);
1241
+ if (input && input.val) {
1242
+ input.val(_xdsoft_datetime.str);
1243
+ }
1244
+ }
1245
+
1246
+ if (isNaN(options.dayOfWeekStart)) {
1247
+ options.dayOfWeekStart = 0;
1248
+ } else {
1249
+ options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7;
1250
+ }
1251
+
1252
+ if (!options.timepickerScrollbar) {
1253
+ timeboxparent.xdsoftScroller(options, 'hide');
1254
+ }
1255
+
1256
+ if (options.minDate && /^[\+\-](.*)$/.test(options.minDate)) {
1257
+ options.minDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.minDate), options.formatDate);
1258
+ }
1259
+
1260
+ if (options.maxDate && /^[\+\-](.*)$/.test(options.maxDate)) {
1261
+ options.maxDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.maxDate), options.formatDate);
1262
+ }
1263
+
1264
+ if (options.minDateTime && /^\+(.*)$/.test(options.minDateTime)) {
1265
+ options.minDateTime = _xdsoft_datetime.strToDateTime(options.minDateTime).dateFormat(options.formatDate);
1266
+ }
1267
+
1268
+ if (options.maxDateTime && /^\+(.*)$/.test(options.maxDateTime)) {
1269
+ options.maxDateTime = _xdsoft_datetime.strToDateTime(options.maxDateTime).dateFormat(options.formatDate);
1270
+ }
1271
+
1272
+ applyButton.toggle(options.showApplyButton);
1273
+
1274
+ month_picker
1275
+ .find('.xdsoft_today_button')
1276
+ .css('visibility', !options.todayButton ? 'hidden' : 'visible');
1277
+
1278
+ month_picker
1279
+ .find('.' + options.prev)
1280
+ .css('visibility', !options.prevButton ? 'hidden' : 'visible');
1281
+
1282
+ month_picker
1283
+ .find('.' + options.next)
1284
+ .css('visibility', !options.nextButton ? 'hidden' : 'visible');
1285
+
1286
+ setMask(options);
1287
+
1288
+ if (options.validateOnBlur) {
1289
+ input
1290
+ .off('blur.xdsoft')
1291
+ .on('blur.xdsoft', function () {
1292
+ if (options.allowBlank && (!$.trim($(this).val()).length ||
1293
+ (typeof options.mask === "string" && $.trim($(this).val()) === options.mask.replace(/[0-9]/g, '_')))) {
1294
+ $(this).val(null);
1295
+ datetimepicker.data('xdsoft_datetime').empty();
1296
+ } else {
1297
+ var d = dateHelper.parseDate($(this).val(), options.format);
1298
+ if (d) { // parseDate() may skip some invalid parts like date or time, so make it clear for user: show parsed date/time
1299
+ $(this).val(dateHelper.formatDate(d, options.format));
1300
+ } else {
1301
+ var splittedHours = +([$(this).val()[0], $(this).val()[1]].join('')),
1302
+ splittedMinutes = +([$(this).val()[2], $(this).val()[3]].join(''));
1303
+
1304
+ // parse the numbers as 0312 => 03:12
1305
+ if (!options.datepicker && options.timepicker && splittedHours >= 0 && splittedHours < 24 && splittedMinutes >= 0 && splittedMinutes < 60) {
1306
+ $(this).val([splittedHours, splittedMinutes].map(function (item) {
1307
+ return item > 9 ? item : '0' + item;
1308
+ }).join(':'));
1309
+ } else {
1310
+ $(this).val(dateHelper.formatDate(_xdsoft_datetime.now(), options.format));
1311
+ }
1312
+ }
1313
+ datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
1314
+ }
1315
+
1316
+ datetimepicker.trigger('changedatetime.xdsoft');
1317
+ datetimepicker.trigger('close.xdsoft');
1318
+ });
1319
+ }
1320
+ options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
1321
+
1322
+ datetimepicker
1323
+ .trigger('xchange.xdsoft')
1324
+ .trigger('afterOpen.xdsoft');
1325
+ };
1326
+
1327
+ datetimepicker
1328
+ .data('options', options)
1329
+ .on('touchstart mousedown.xdsoft', function (event) {
1330
+ event.stopPropagation();
1331
+ event.preventDefault();
1332
+ yearselect.hide();
1333
+ monthselect.hide();
1334
+ return false;
1335
+ });
1336
+
1337
+ //scroll_element = timepicker.find('.xdsoft_time_box');
1338
+ timeboxparent.append(timebox);
1339
+ timeboxparent.xdsoftScroller(options);
1340
+
1341
+ datetimepicker.on('afterOpen.xdsoft', function () {
1342
+ timeboxparent.xdsoftScroller(options);
1343
+ });
1344
+
1345
+ datetimepicker
1346
+ .append(datepicker)
1347
+ .append(timepicker);
1348
+
1349
+ if (options.withoutCopyright !== true) {
1350
+ datetimepicker
1351
+ .append(xdsoft_copyright);
1352
+ }
1353
+
1354
+ datepicker
1355
+ .append(month_picker)
1356
+ .append(calendar)
1357
+ .append(applyButton);
1358
+
1359
+ if (options.insideParent) {
1360
+ $(input).parent().append(datetimepicker);
1361
+ } else {
1362
+ $(options.parentID).append(datetimepicker);
1363
+ }
1364
+
1365
+ XDSoft_datetime = function () {
1366
+ var _this = this;
1367
+ _this.now = function (norecursion) {
1368
+ var d = new Date(),
1369
+ date,
1370
+ time;
1371
+
1372
+ if (!norecursion && options.defaultDate) {
1373
+ date = _this.strToDateTime(options.defaultDate);
1374
+ d.setFullYear(date.getFullYear());
1375
+ d.setMonth(date.getMonth());
1376
+ d.setDate(date.getDate());
1377
+ }
1378
+
1379
+ d.setFullYear(d.getFullYear());
1380
+
1381
+ if (!norecursion && options.defaultTime) {
1382
+ time = _this.strtotime(options.defaultTime);
1383
+ d.setHours(time.getHours());
1384
+ d.setMinutes(time.getMinutes());
1385
+ d.setSeconds(time.getSeconds());
1386
+ d.setMilliseconds(time.getMilliseconds());
1387
+ }
1388
+ return d;
1389
+ };
1390
+
1391
+ _this.isValidDate = function (d) {
1392
+ if (Object.prototype.toString.call(d) !== "[object Date]") {
1393
+ return false;
1394
+ }
1395
+ return !isNaN(d.getTime());
1396
+ };
1397
+
1398
+ _this.setCurrentTime = function (dTime, requireValidDate) {
1399
+ if (typeof dTime === 'string') {
1400
+ _this.currentTime = _this.strToDateTime(dTime);
1401
+ }
1402
+ else if (_this.isValidDate(dTime)) {
1403
+ _this.currentTime = dTime;
1404
+ }
1405
+ else if (!dTime && !requireValidDate && options.allowBlank && !options.inline) {
1406
+ _this.currentTime = null;
1407
+ }
1408
+ else {
1409
+ _this.currentTime = _this.now();
1410
+ }
1411
+
1412
+ datetimepicker.trigger('xchange.xdsoft');
1413
+ };
1414
+
1415
+ _this.empty = function () {
1416
+ _this.currentTime = null;
1417
+ };
1418
+
1419
+ _this.getCurrentTime = function () {
1420
+ return _this.currentTime;
1421
+ };
1422
+
1423
+ _this.nextMonth = function () {
1424
+
1425
+ if (_this.currentTime === undefined || _this.currentTime === null) {
1426
+ _this.currentTime = _this.now();
1427
+ }
1428
+
1429
+ var month = _this.currentTime.getMonth() + 1,
1430
+ year;
1431
+ if (month === 12) {
1432
+ _this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1);
1433
+ month = 0;
1434
+ }
1435
+
1436
+ year = _this.currentTime.getFullYear();
1437
+
1438
+ _this.currentTime.setDate(
1439
+ Math.min(
1440
+ new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
1441
+ _this.currentTime.getDate()
1442
+ )
1443
+ );
1444
+ _this.currentTime.setMonth(month);
1445
+
1446
+ if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
1447
+ options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1448
+ }
1449
+
1450
+ if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
1451
+ options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1452
+ }
1453
+
1454
+ datetimepicker.trigger('xchange.xdsoft');
1455
+ return month;
1456
+ };
1457
+
1458
+ _this.prevMonth = function () {
1459
+
1460
+ if (_this.currentTime === undefined || _this.currentTime === null) {
1461
+ _this.currentTime = _this.now();
1462
+ }
1463
+
1464
+ var month = _this.currentTime.getMonth() - 1;
1465
+ if (month === -1) {
1466
+ _this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1);
1467
+ month = 11;
1468
+ }
1469
+ _this.currentTime.setDate(
1470
+ Math.min(
1471
+ new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
1472
+ _this.currentTime.getDate()
1473
+ )
1474
+ );
1475
+ _this.currentTime.setMonth(month);
1476
+ if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
1477
+ options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1478
+ }
1479
+ datetimepicker.trigger('xchange.xdsoft');
1480
+ return month;
1481
+ };
1482
+
1483
+ _this.getWeekOfYear = function (datetime) {
1484
+ if (options.onGetWeekOfYear && $.isFunction(options.onGetWeekOfYear)) {
1485
+ var week = options.onGetWeekOfYear.call(datetimepicker, datetime);
1486
+ if (typeof week !== 'undefined') {
1487
+ return week;
1488
+ }
1489
+ }
1490
+ var onejan = new Date(datetime.getFullYear(), 0, 1);
1491
+
1492
+ //First week of the year is th one with the first Thursday according to ISO8601
1493
+ if (onejan.getDay() !== 4) {
1494
+ onejan.setMonth(0, 1 + ((4 - onejan.getDay()+ 7) % 7));
1495
+ }
1496
+
1497
+ return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7);
1498
+ };
1499
+
1500
+ _this.strToDateTime = function (sDateTime) {
1501
+ var tmpDate = [], timeOffset, currentTime;
1502
+
1503
+ if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) {
1504
+ return sDateTime;
1505
+ }
1506
+
1507
+ tmpDate = /^([+-]{1})(.*)$/.exec(sDateTime);
1508
+
1509
+ if (tmpDate) {
1510
+ tmpDate[2] = dateHelper.parseDate(tmpDate[2], options.formatDate);
1511
+ }
1512
+
1513
+ if (tmpDate && tmpDate[2]) {
1514
+ timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
1515
+ currentTime = new Date((_this.now(true)).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset);
1516
+ } else {
1517
+ currentTime = sDateTime ? dateHelper.parseDate(sDateTime, options.format) : _this.now();
1518
+ }
1519
+
1520
+ if (!_this.isValidDate(currentTime)) {
1521
+ currentTime = _this.now();
1522
+ }
1523
+
1524
+ return currentTime;
1525
+ };
1526
+
1527
+ _this.strToDate = function (sDate) {
1528
+ if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) {
1529
+ return sDate;
1530
+ }
1531
+
1532
+ var currentTime = sDate ? dateHelper.parseDate(sDate, options.formatDate) : _this.now(true);
1533
+ if (!_this.isValidDate(currentTime)) {
1534
+ currentTime = _this.now(true);
1535
+ }
1536
+ return currentTime;
1537
+ };
1538
+
1539
+ _this.strtotime = function (sTime) {
1540
+ if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) {
1541
+ return sTime;
1542
+ }
1543
+ var currentTime = sTime ? dateHelper.parseDate(sTime, options.formatTime) : _this.now(true);
1544
+ if (!_this.isValidDate(currentTime)) {
1545
+ currentTime = _this.now(true);
1546
+ }
1547
+ return currentTime;
1548
+ };
1549
+
1550
+ _this.str = function () {
1551
+ var format = options.format;
1552
+ if (options.yearOffset) {
1553
+ format = format.replace('Y', _this.currentTime.getFullYear() + options.yearOffset);
1554
+ format = format.replace('y', String(_this.currentTime.getFullYear() + options.yearOffset).substring(2, 4));
1555
+ }
1556
+ return dateHelper.formatDate(_this.currentTime, format);
1557
+ };
1558
+ _this.currentTime = this.now();
1559
+ };
1560
+
1561
+ _xdsoft_datetime = new XDSoft_datetime();
1562
+
1563
+ applyButton.on('touchend click', function (e) {//pathbrite
1564
+ e.preventDefault();
1565
+ datetimepicker.data('changed', true);
1566
+ _xdsoft_datetime.setCurrentTime(getCurrentValue());
1567
+ input.val(_xdsoft_datetime.str());
1568
+ datetimepicker.trigger('close.xdsoft');
1569
+ });
1570
+ month_picker
1571
+ .find('.xdsoft_today_button')
1572
+ .on('touchend mousedown.xdsoft', function () {
1573
+ datetimepicker.data('changed', true);
1574
+ _xdsoft_datetime.setCurrentTime(0, true);
1575
+ datetimepicker.trigger('afterOpen.xdsoft');
1576
+ }).on('dblclick.xdsoft', function () {
1577
+ var currentDate = _xdsoft_datetime.getCurrentTime(), minDate, maxDate;
1578
+ currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
1579
+ minDate = _xdsoft_datetime.strToDate(options.minDate);
1580
+ minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
1581
+ if (currentDate < minDate) {
1582
+ return;
1583
+ }
1584
+ maxDate = _xdsoft_datetime.strToDate(options.maxDate);
1585
+ maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate());
1586
+ if (currentDate > maxDate) {
1587
+ return;
1588
+ }
1589
+ input.val(_xdsoft_datetime.str());
1590
+ input.trigger('change');
1591
+ datetimepicker.trigger('close.xdsoft');
1592
+ });
1593
+ month_picker
1594
+ .find('.xdsoft_prev,.xdsoft_next')
1595
+ .on('touchend mousedown.xdsoft', function () {
1596
+ var $this = $(this),
1597
+ timer = 0,
1598
+ stop = false;
1599
+
1600
+ (function arguments_callee1(v) {
1601
+ if ($this.hasClass(options.next)) {
1602
+ _xdsoft_datetime.nextMonth();
1603
+ } else if ($this.hasClass(options.prev)) {
1604
+ _xdsoft_datetime.prevMonth();
1605
+ }
1606
+ if (options.monthChangeSpinner) {
1607
+ if (!stop) {
1608
+ timer = setTimeout(arguments_callee1, v || 100);
1609
+ }
1610
+ }
1611
+ }(500));
1612
+
1613
+ $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft', function arguments_callee2() {
1614
+ clearTimeout(timer);
1615
+ stop = true;
1616
+ $([options.ownerDocument.body, options.contentWindow]).off('touchend mouseup.xdsoft', arguments_callee2);
1617
+ });
1618
+ });
1619
+
1620
+ timepicker
1621
+ .find('.xdsoft_prev,.xdsoft_next')
1622
+ .on('touchend mousedown.xdsoft', function () {
1623
+ var $this = $(this),
1624
+ timer = 0,
1625
+ stop = false,
1626
+ period = 110;
1627
+ (function arguments_callee4(v) {
1628
+ var pheight = timeboxparent[0].clientHeight,
1629
+ height = timebox[0].offsetHeight,
1630
+ top = Math.abs(parseInt(timebox.css('marginTop'), 10));
1631
+ if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) {
1632
+ timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px');
1633
+ } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
1634
+ timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
1635
+ }
1636
+ /**
1637
+ * Fixed bug:
1638
+ * When using css3 transition, it will cause a bug that you cannot scroll the timepicker list.
1639
+ * The reason is that the transition-duration time, if you set it to 0, all things fine, otherwise, this
1640
+ * would cause a bug when you use jquery.css method.
1641
+ * Let's say: * { transition: all .5s ease; }
1642
+ * jquery timebox.css('marginTop') will return the original value which is before you clicking the next/prev button,
1643
+ * meanwhile the timebox[0].style.marginTop will return the right value which is after you clicking the
1644
+ * next/prev button.
1645
+ *
1646
+ * What we should do:
1647
+ * Replace timebox.css('marginTop') with timebox[0].style.marginTop.
1648
+ */
1649
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox[0].style.marginTop, 10) / (height - pheight))]);
1650
+ period = (period > 10) ? 10 : period - 10;
1651
+ if (!stop) {
1652
+ timer = setTimeout(arguments_callee4, v || period);
1653
+ }
1654
+ }(500));
1655
+ $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft', function arguments_callee5() {
1656
+ clearTimeout(timer);
1657
+ stop = true;
1658
+ $([options.ownerDocument.body, options.contentWindow])
1659
+ .off('touchend mouseup.xdsoft', arguments_callee5);
1660
+ });
1661
+ });
1662
+
1663
+ xchangeTimer = 0;
1664
+ // base handler - generating a calendar and timepicker
1665
+ datetimepicker
1666
+ .on('xchange.xdsoft', function (event) {
1667
+ clearTimeout(xchangeTimer);
1668
+ xchangeTimer = setTimeout(function () {
1669
+
1670
+ if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1671
+ _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1672
+ }
1673
+
1674
+ var table = '',
1675
+ start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0),
1676
+ i = 0,
1677
+ j,
1678
+ today = _xdsoft_datetime.now(),
1679
+ maxDate = false,
1680
+ minDate = false,
1681
+ minDateTime = false,
1682
+ maxDateTime = false,
1683
+ hDate,
1684
+ day,
1685
+ d,
1686
+ y,
1687
+ m,
1688
+ w,
1689
+ classes = [],
1690
+ customDateSettings,
1691
+ newRow = true,
1692
+ time = '',
1693
+ h,
1694
+ line_time,
1695
+ description;
1696
+
1697
+ while (start.getDay() !== options.dayOfWeekStart) {
1698
+ start.setDate(start.getDate() - 1);
1699
+ }
1700
+
1701
+ table += '<table><thead><tr>';
1702
+
1703
+ if (options.weeks) {
1704
+ table += '<th></th>';
1705
+ }
1706
+
1707
+ for (j = 0; j < 7; j += 1) {
1708
+ table += '<th>' + options.i18n[globalLocale].dayOfWeekShort[(j + options.dayOfWeekStart) % 7] + '</th>';
1709
+ }
1710
+
1711
+ table += '</tr></thead>';
1712
+ table += '<tbody>';
1713
+
1714
+ if (options.maxDate !== false) {
1715
+ maxDate = _xdsoft_datetime.strToDate(options.maxDate);
1716
+ maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
1717
+ }
1718
+
1719
+ if (options.minDate !== false) {
1720
+ minDate = _xdsoft_datetime.strToDate(options.minDate);
1721
+ minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
1722
+ }
1723
+
1724
+ if (options.minDateTime !== false) {
1725
+ minDateTime = _xdsoft_datetime.strToDate(options.minDateTime);
1726
+ minDateTime = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), minDateTime.getHours(), minDateTime.getMinutes(), minDateTime.getSeconds());
1727
+ }
1728
+
1729
+ if (options.maxDateTime !== false) {
1730
+ maxDateTime = _xdsoft_datetime.strToDate(options.maxDateTime);
1731
+ maxDateTime = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), maxDateTime.getHours(), maxDateTime.getMinutes(), maxDateTime.getSeconds());
1732
+ }
1733
+
1734
+ var maxDateTimeDay;
1735
+ if (maxDateTime !== false) {
1736
+ maxDateTimeDay = ((maxDateTime.getFullYear() * 12) + maxDateTime.getMonth()) * 31 + maxDateTime.getDate();
1737
+ }
1738
+
1739
+ while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
1740
+ classes = [];
1741
+ i += 1;
1742
+
1743
+ day = start.getDay();
1744
+ d = start.getDate();
1745
+ y = start.getFullYear();
1746
+ m = start.getMonth();
1747
+ w = _xdsoft_datetime.getWeekOfYear(start);
1748
+ description = '';
1749
+
1750
+ classes.push('xdsoft_date');
1751
+
1752
+ if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) {
1753
+ customDateSettings = options.beforeShowDay.call(datetimepicker, start);
1754
+ } else {
1755
+ customDateSettings = null;
1756
+ }
1757
+
1758
+ if(options.allowDateRe && Object.prototype.toString.call(options.allowDateRe) === "[object RegExp]"){
1759
+ if(!options.allowDateRe.test(dateHelper.formatDate(start, options.formatDate))){
1760
+ classes.push('xdsoft_disabled');
1761
+ }
1762
+ }
1763
+
1764
+ if(options.allowDates && options.allowDates.length>0){
1765
+ if(options.allowDates.indexOf(dateHelper.formatDate(start, options.formatDate)) === -1){
1766
+ classes.push('xdsoft_disabled');
1767
+ }
1768
+ }
1769
+
1770
+ var currentDay = ((start.getFullYear() * 12) + start.getMonth()) * 31 + start.getDate();
1771
+ if ((maxDate !== false && start > maxDate) || (minDateTime !== false && start < minDateTime) || (minDate !== false && start < minDate) || (maxDateTime !== false && currentDay > maxDateTimeDay) || (customDateSettings && customDateSettings[0] === false)) {
1772
+ classes.push('xdsoft_disabled');
1773
+ }
1774
+
1775
+ if (options.disabledDates.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
1776
+ classes.push('xdsoft_disabled');
1777
+ }
1778
+
1779
+ if (options.disabledWeekDays.indexOf(day) !== -1) {
1780
+ classes.push('xdsoft_disabled');
1781
+ }
1782
+
1783
+ if (input.is('[disabled]')) {
1784
+ classes.push('xdsoft_disabled');
1785
+ }
1786
+
1787
+ if (customDateSettings && customDateSettings[1] !== "") {
1788
+ classes.push(customDateSettings[1]);
1789
+ }
1790
+
1791
+ if (_xdsoft_datetime.currentTime.getMonth() !== m) {
1792
+ classes.push('xdsoft_other_month');
1793
+ }
1794
+
1795
+ if ((options.defaultSelect || datetimepicker.data('changed')) && dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
1796
+ classes.push('xdsoft_current');
1797
+ }
1798
+
1799
+ if (dateHelper.formatDate(today, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
1800
+ classes.push('xdsoft_today');
1801
+ }
1802
+
1803
+ if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
1804
+ classes.push('xdsoft_weekend');
1805
+ }
1806
+
1807
+ if (options.highlightedDates[dateHelper.formatDate(start, options.formatDate)] !== undefined) {
1808
+ hDate = options.highlightedDates[dateHelper.formatDate(start, options.formatDate)];
1809
+ classes.push(hDate.style === undefined ? 'xdsoft_highlighted_default' : hDate.style);
1810
+ description = hDate.desc === undefined ? '' : hDate.desc;
1811
+ }
1812
+
1813
+ if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) {
1814
+ classes.push(options.beforeShowDay(start));
1815
+ }
1816
+
1817
+ if (newRow) {
1818
+ table += '<tr>';
1819
+ newRow = false;
1820
+ if (options.weeks) {
1821
+ table += '<th>' + w + '</th>';
1822
+ }
1823
+ }
1824
+
1825
+ table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '" title="' + description + '">' +
1826
+ '<div>' + d + '</div>' +
1827
+ '</td>';
1828
+
1829
+ if (start.getDay() === options.dayOfWeekStartPrev) {
1830
+ table += '</tr>';
1831
+ newRow = true;
1832
+ }
1833
+
1834
+ start.setDate(d + 1);
1835
+ }
1836
+ table += '</tbody></table>';
1837
+
1838
+ calendar.html(table);
1839
+
1840
+ month_picker.find('.xdsoft_label span').eq(0).text(options.i18n[globalLocale].months[_xdsoft_datetime.currentTime.getMonth()]);
1841
+ month_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear() + options.yearOffset);
1842
+
1843
+ // generate timebox
1844
+ time = '';
1845
+ h = '';
1846
+ m = '';
1847
+
1848
+ var minTimeMinutesOfDay = 0;
1849
+ if (options.minTime !== false) {
1850
+ var t = _xdsoft_datetime.strtotime(options.minTime);
1851
+ minTimeMinutesOfDay = 60 * t.getHours() + t.getMinutes();
1852
+ }
1853
+ var maxTimeMinutesOfDay = 24 * 60;
1854
+ if (options.maxTime !== false) {
1855
+ var t = _xdsoft_datetime.strtotime(options.maxTime);
1856
+ maxTimeMinutesOfDay = 60 * t.getHours() + t.getMinutes();
1857
+ }
1858
+
1859
+ if (options.minDateTime !== false) {
1860
+ var t = _xdsoft_datetime.strToDateTime(options.minDateTime);
1861
+ var currentDayIsMinDateTimeDay = dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(t, options.formatDate);
1862
+ if (currentDayIsMinDateTimeDay) {
1863
+ var m = 60 * t.getHours() + t.getMinutes();
1864
+ if (m > minTimeMinutesOfDay) minTimeMinutesOfDay = m;
1865
+ }
1866
+ }
1867
+
1868
+ if (options.maxDateTime !== false) {
1869
+ var t = _xdsoft_datetime.strToDateTime(options.maxDateTime);
1870
+ var currentDayIsMaxDateTimeDay = dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(t, options.formatDate);
1871
+ if (currentDayIsMaxDateTimeDay) {
1872
+ var m = 60 * t.getHours() + t.getMinutes();
1873
+ if (m < maxTimeMinutesOfDay) maxTimeMinutesOfDay = m;
1874
+ }
1875
+ }
1876
+
1877
+ line_time = function line_time(h, m) {
1878
+ var now = _xdsoft_datetime.now(), current_time,
1879
+ isALlowTimesInit = options.allowTimes && $.isArray(options.allowTimes) && options.allowTimes.length;
1880
+ now.setHours(h);
1881
+ h = parseInt(now.getHours(), 10);
1882
+ now.setMinutes(m);
1883
+ m = parseInt(now.getMinutes(), 10);
1884
+ classes = [];
1885
+ var currentMinutesOfDay = 60 * h + m;
1886
+ if (input.is('[disabled]') || (currentMinutesOfDay >= maxTimeMinutesOfDay) || (currentMinutesOfDay < minTimeMinutesOfDay)) {
1887
+ classes.push('xdsoft_disabled');
1888
+ }
1889
+
1890
+ current_time = new Date(_xdsoft_datetime.currentTime);
1891
+ current_time.setHours(parseInt(_xdsoft_datetime.currentTime.getHours(), 10));
1892
+
1893
+ if (!isALlowTimesInit) {
1894
+ current_time.setMinutes(Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step);
1895
+ }
1896
+
1897
+ if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && current_time.getHours() === parseInt(h, 10) && ((!isALlowTimesInit && options.step > 59) || current_time.getMinutes() === parseInt(m, 10))) {
1898
+ if (options.defaultSelect || datetimepicker.data('changed')) {
1899
+ classes.push('xdsoft_current');
1900
+ } else if (options.initTime) {
1901
+ classes.push('xdsoft_init_time');
1902
+ }
1903
+ }
1904
+ if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) {
1905
+ classes.push('xdsoft_today');
1906
+ }
1907
+ time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + dateHelper.formatDate(now, options.formatTime) + '</div>';
1908
+ };
1909
+
1910
+ if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) {
1911
+ for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
1912
+ for (j = 0; j < 60; j += options.step) {
1913
+ var currentMinutesOfDay = i * 60 + j;
1914
+ if (currentMinutesOfDay < minTimeMinutesOfDay) continue;
1915
+ if (currentMinutesOfDay >= maxTimeMinutesOfDay) continue;
1916
+ h = (i < 10 ? '0' : '') + i;
1917
+ m = (j < 10 ? '0' : '') + j;
1918
+ line_time(h, m);
1919
+ }
1920
+ }
1921
+ } else {
1922
+ for (i = 0; i < options.allowTimes.length; i += 1) {
1923
+ h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
1924
+ m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
1925
+ line_time(h, m);
1926
+ }
1927
+ }
1928
+
1929
+ timebox.html(time);
1930
+
1931
+ opt = '';
1932
+
1933
+ for (i = parseInt(options.yearStart, 10); i <= parseInt(options.yearEnd, 10); i += 1) {
1934
+ opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + (i + options.yearOffset) + '</div>';
1935
+ }
1936
+ yearselect.children().eq(0)
1937
+ .html(opt);
1938
+
1939
+ for (i = parseInt(options.monthStart, 10), opt = ''; i <= parseInt(options.monthEnd, 10); i += 1) {
1940
+ opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[globalLocale].months[i] + '</div>';
1941
+ }
1942
+ monthselect.children().eq(0).html(opt);
1943
+ $(datetimepicker)
1944
+ .trigger('generate.xdsoft');
1945
+ }, 10);
1946
+ event.stopPropagation();
1947
+ })
1948
+ .on('afterOpen.xdsoft', function () {
1949
+ if (options.timepicker) {
1950
+ var classType, pheight, height, top;
1951
+ if (timebox.find('.xdsoft_current').length) {
1952
+ classType = '.xdsoft_current';
1953
+ } else if (timebox.find('.xdsoft_init_time').length) {
1954
+ classType = '.xdsoft_init_time';
1955
+ }
1956
+ if (classType) {
1957
+ pheight = timeboxparent[0].clientHeight;
1958
+ height = timebox[0].offsetHeight;
1959
+ top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1;
1960
+ if ((height - pheight) < top) {
1961
+ top = height - pheight;
1962
+ }
1963
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]);
1964
+ } else {
1965
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]);
1966
+ }
1967
+ }
1968
+ });
1969
+
1970
+ timerclick = 0;
1971
+ calendar
1972
+ .on('touchend click.xdsoft', 'td', function (xdevent) {
1973
+ xdevent.stopPropagation(); // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
1974
+ timerclick += 1;
1975
+ var $this = $(this),
1976
+ currentTime = _xdsoft_datetime.currentTime;
1977
+
1978
+ if (currentTime === undefined || currentTime === null) {
1979
+ _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1980
+ currentTime = _xdsoft_datetime.currentTime;
1981
+ }
1982
+
1983
+ if ($this.hasClass('xdsoft_disabled')) {
1984
+ return false;
1985
+ }
1986
+
1987
+ currentTime.setDate(1);
1988
+ currentTime.setFullYear($this.data('year'));
1989
+ currentTime.setMonth($this.data('month'));
1990
+ currentTime.setDate($this.data('date'));
1991
+
1992
+ datetimepicker.trigger('select.xdsoft', [currentTime]);
1993
+
1994
+ input.val(_xdsoft_datetime.str());
1995
+
1996
+ if (options.onSelectDate && $.isFunction(options.onSelectDate)) {
1997
+ options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
1998
+ }
1999
+
2000
+ datetimepicker.data('changed', true);
2001
+ datetimepicker.trigger('xchange.xdsoft');
2002
+ datetimepicker.trigger('changedatetime.xdsoft');
2003
+ if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === false && !options.timepicker))) && !options.inline) {
2004
+ datetimepicker.trigger('close.xdsoft');
2005
+ }
2006
+ setTimeout(function () {
2007
+ timerclick = 0;
2008
+ }, 200);
2009
+ });
2010
+
2011
+ timebox
2012
+ .on('touchstart', 'div', function (xdevent) {
2013
+ this.touchMoved = false;
2014
+ })
2015
+ .on('touchmove', 'div', handleTouchMoved)
2016
+ .on('touchend click.xdsoft', 'div', function (xdevent) {
2017
+ if (!this.touchMoved) {
2018
+ xdevent.stopPropagation();
2019
+ var $this = $(this),
2020
+ currentTime = _xdsoft_datetime.currentTime;
2021
+
2022
+ if (currentTime === undefined || currentTime === null) {
2023
+ _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
2024
+ currentTime = _xdsoft_datetime.currentTime;
2025
+ }
2026
+
2027
+ if ($this.hasClass('xdsoft_disabled')) {
2028
+ return false;
2029
+ }
2030
+ currentTime.setHours($this.data('hour'));
2031
+ currentTime.setMinutes($this.data('minute'));
2032
+ datetimepicker.trigger('select.xdsoft', [currentTime]);
2033
+
2034
+ datetimepicker.data('input').val(_xdsoft_datetime.str());
2035
+
2036
+ if (options.onSelectTime && $.isFunction(options.onSelectTime)) {
2037
+ options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
2038
+ }
2039
+ datetimepicker.data('changed', true);
2040
+ datetimepicker.trigger('xchange.xdsoft');
2041
+ datetimepicker.trigger('changedatetime.xdsoft');
2042
+ if (options.inline !== true && options.closeOnTimeSelect === true) {
2043
+ datetimepicker.trigger('close.xdsoft');
2044
+ }
2045
+ }
2046
+ });
2047
+
2048
+ datepicker
2049
+ .on('mousewheel.xdsoft', function (event) {
2050
+ if (!options.scrollMonth) {
2051
+ return true;
2052
+ }
2053
+ if (event.deltaY < 0) {
2054
+ _xdsoft_datetime.nextMonth();
2055
+ } else {
2056
+ _xdsoft_datetime.prevMonth();
2057
+ }
2058
+ return false;
2059
+ });
2060
+
2061
+ input
2062
+ .on('mousewheel.xdsoft', function (event) {
2063
+ if (!options.scrollInput) {
2064
+ return true;
2065
+ }
2066
+ if (!options.datepicker && options.timepicker) {
2067
+ current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0;
2068
+ if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
2069
+ current_time_index += event.deltaY;
2070
+ }
2071
+ if (timebox.children().eq(current_time_index).length) {
2072
+ timebox.children().eq(current_time_index).trigger('mousedown');
2073
+ }
2074
+ return false;
2075
+ }
2076
+ if (options.datepicker && !options.timepicker) {
2077
+ datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]);
2078
+ if (input.val) {
2079
+ input.val(_xdsoft_datetime.str());
2080
+ }
2081
+ datetimepicker.trigger('changedatetime.xdsoft');
2082
+ return false;
2083
+ }
2084
+ });
2085
+
2086
+ datetimepicker
2087
+ .on('changedatetime.xdsoft', function (event) {
2088
+ if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) {
2089
+ var $input = datetimepicker.data('input');
2090
+ options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event);
2091
+ delete options.value;
2092
+ $input.trigger('change');
2093
+ }
2094
+ })
2095
+ .on('generate.xdsoft', function () {
2096
+ if (options.onGenerate && $.isFunction(options.onGenerate)) {
2097
+ options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
2098
+ }
2099
+ if (triggerAfterOpen) {
2100
+ datetimepicker.trigger('afterOpen.xdsoft');
2101
+ triggerAfterOpen = false;
2102
+ }
2103
+ })
2104
+ .on('click.xdsoft', function (xdevent) {
2105
+ xdevent.stopPropagation();
2106
+ });
2107
+
2108
+ current_time_index = 0;
2109
+
2110
+ /**
2111
+ * Runs the callback for each of the specified node's ancestors.
2112
+ *
2113
+ * Return FALSE from the callback to stop ascending.
2114
+ *
2115
+ * @param {DOMNode} node
2116
+ * @param {Function} callback
2117
+ * @returns {undefined}
2118
+ */
2119
+ forEachAncestorOf = function (node, callback) {
2120
+ do {
2121
+ node = node.parentNode;
2122
+
2123
+ if (!node || callback(node) === false) {
2124
+ break;
2125
+ }
2126
+ } while (node.nodeName !== 'HTML');
2127
+ };
2128
+
2129
+ /**
2130
+ * Sets the position of the picker.
2131
+ *
2132
+ * @returns {undefined}
2133
+ */
2134
+ setPos = function () {
2135
+ var dateInputOffset,
2136
+ dateInputElem,
2137
+ verticalPosition,
2138
+ left,
2139
+ position,
2140
+ datetimepickerElem,
2141
+ dateInputHasFixedAncestor,
2142
+ $dateInput,
2143
+ windowWidth,
2144
+ verticalAnchorEdge,
2145
+ datetimepickerCss,
2146
+ windowHeight,
2147
+ windowScrollTop;
2148
+
2149
+ $dateInput = datetimepicker.data('input');
2150
+ dateInputOffset = $dateInput.offset();
2151
+ dateInputElem = $dateInput[0];
2152
+
2153
+ verticalAnchorEdge = 'top';
2154
+ verticalPosition = (dateInputOffset.top + dateInputElem.offsetHeight) - 1;
2155
+ left = dateInputOffset.left;
2156
+ position = "absolute";
2157
+
2158
+ windowWidth = $(options.contentWindow).width();
2159
+ windowHeight = $(options.contentWindow).height();
2160
+ windowScrollTop = $(options.contentWindow).scrollTop();
2161
+
2162
+ if ((options.ownerDocument.documentElement.clientWidth - dateInputOffset.left) < datepicker.parent().outerWidth(true)) {
2163
+ var diff = datepicker.parent().outerWidth(true) - dateInputElem.offsetWidth;
2164
+ left = left - diff;
2165
+ }
2166
+
2167
+ if ($dateInput.parent().css('direction') === 'rtl') {
2168
+ left -= (datetimepicker.outerWidth() - $dateInput.outerWidth());
2169
+ }
2170
+
2171
+ if (options.fixed) {
2172
+ verticalPosition -= windowScrollTop;
2173
+ left -= $(options.contentWindow).scrollLeft();
2174
+ position = "fixed";
2175
+ } else {
2176
+ dateInputHasFixedAncestor = false;
2177
+
2178
+ forEachAncestorOf(dateInputElem, function (ancestorNode) {
2179
+ if (ancestorNode === null) {
2180
+ return false;
2181
+ }
2182
+
2183
+ if (options.contentWindow.getComputedStyle(ancestorNode).getPropertyValue('position') === 'fixed') {
2184
+ dateInputHasFixedAncestor = true;
2185
+ return false;
2186
+ }
2187
+ });
2188
+
2189
+ if (dateInputHasFixedAncestor && !options.insideParent) {
2190
+ position = 'fixed';
2191
+
2192
+ //If the picker won't fit entirely within the viewport then display it above the date input.
2193
+ if (verticalPosition + datetimepicker.outerHeight() > windowHeight + windowScrollTop) {
2194
+ verticalAnchorEdge = 'bottom';
2195
+ verticalPosition = (windowHeight + windowScrollTop) - dateInputOffset.top;
2196
+ } else {
2197
+ verticalPosition -= windowScrollTop;
2198
+ }
2199
+ } else {
2200
+ if (verticalPosition + datetimepicker[0].offsetHeight > windowHeight + windowScrollTop) {
2201
+ verticalPosition = dateInputOffset.top - datetimepicker[0].offsetHeight + 1;
2202
+ }
2203
+ }
2204
+
2205
+ if (verticalPosition < 0) {
2206
+ verticalPosition = 0;
2207
+ }
2208
+
2209
+ if (left + dateInputElem.offsetWidth > windowWidth) {
2210
+ left = windowWidth - dateInputElem.offsetWidth;
2211
+ }
2212
+ }
2213
+
2214
+ datetimepickerElem = datetimepicker[0];
2215
+
2216
+ forEachAncestorOf(datetimepickerElem, function (ancestorNode) {
2217
+ var ancestorNodePosition;
2218
+
2219
+ ancestorNodePosition = options.contentWindow.getComputedStyle(ancestorNode).getPropertyValue('position');
2220
+
2221
+ if (ancestorNodePosition === 'relative' && windowWidth >= ancestorNode.offsetWidth) {
2222
+ left = left - ((windowWidth - ancestorNode.offsetWidth) / 2);
2223
+ return false;
2224
+ }
2225
+ });
2226
+
2227
+ datetimepickerCss = {
2228
+ position: position,
2229
+ left: options.insideParent ? dateInputElem.offsetLeft : left,
2230
+ top: '', //Initialize to prevent previous values interfering with new ones.
2231
+ bottom: '' //Initialize to prevent previous values interfering with new ones.
2232
+ };
2233
+
2234
+ if (options.insideParent) {
2235
+ datetimepickerCss[verticalAnchorEdge] = dateInputElem.offsetTop + dateInputElem.offsetHeight;
2236
+ } else {
2237
+ datetimepickerCss[verticalAnchorEdge] = verticalPosition;
2238
+ }
2239
+
2240
+ datetimepicker.css(datetimepickerCss);
2241
+ };
2242
+
2243
+ datetimepicker
2244
+ .on('open.xdsoft', function (event) {
2245
+ var onShow = true;
2246
+ if (options.onShow && $.isFunction(options.onShow)) {
2247
+ onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
2248
+ }
2249
+ if (onShow !== false) {
2250
+ datetimepicker.show();
2251
+ setPos();
2252
+ $(options.contentWindow)
2253
+ .off('resize.xdsoft', setPos)
2254
+ .on('resize.xdsoft', setPos);
2255
+
2256
+ if (options.closeOnWithoutClick) {
2257
+ $([options.ownerDocument.body, options.contentWindow]).on('touchstart mousedown.xdsoft', function arguments_callee6() {
2258
+ datetimepicker.trigger('close.xdsoft');
2259
+ $([options.ownerDocument.body, options.contentWindow]).off('touchstart mousedown.xdsoft', arguments_callee6);
2260
+ });
2261
+ }
2262
+ }
2263
+ })
2264
+ .on('close.xdsoft', function (event) {
2265
+ var onClose = true;
2266
+ month_picker
2267
+ .find('.xdsoft_month,.xdsoft_year')
2268
+ .find('.xdsoft_select')
2269
+ .hide();
2270
+ if (options.onClose && $.isFunction(options.onClose)) {
2271
+ onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
2272
+ }
2273
+ if (onClose !== false && !options.opened && !options.inline) {
2274
+ datetimepicker.hide();
2275
+ }
2276
+ event.stopPropagation();
2277
+ })
2278
+ .on('toggle.xdsoft', function () {
2279
+ if (datetimepicker.is(':visible')) {
2280
+ datetimepicker.trigger('close.xdsoft');
2281
+ } else {
2282
+ datetimepicker.trigger('open.xdsoft');
2283
+ }
2284
+ })
2285
+ .data('input', input);
2286
+
2287
+ timer = 0;
2288
+
2289
+ datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
2290
+ datetimepicker.setOptions(options);
2291
+
2292
+ function getCurrentValue() {
2293
+ var ct = false, time;
2294
+
2295
+ if (options.startDate) {
2296
+ ct = _xdsoft_datetime.strToDate(options.startDate);
2297
+ } else {
2298
+ ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
2299
+ if (ct) {
2300
+ ct = _xdsoft_datetime.strToDateTime(ct);
2301
+ if (options.yearOffset) {
2302
+ ct = new Date(ct.getFullYear() - options.yearOffset, ct.getMonth(), ct.getDate(), ct.getHours(), ct.getMinutes(), ct.getSeconds(), ct.getMilliseconds());
2303
+ }
2304
+ } else if (options.defaultDate) {
2305
+ ct = _xdsoft_datetime.strToDateTime(options.defaultDate);
2306
+ if (options.defaultTime) {
2307
+ time = _xdsoft_datetime.strtotime(options.defaultTime);
2308
+ ct.setHours(time.getHours());
2309
+ ct.setMinutes(time.getMinutes());
2310
+ }
2311
+ }
2312
+ }
2313
+
2314
+ if (ct && _xdsoft_datetime.isValidDate(ct)) {
2315
+ datetimepicker.data('changed', true);
2316
+ } else {
2317
+ ct = '';
2318
+ }
2319
+
2320
+ return ct || 0;
2321
+ }
2322
+
2323
+ function setMask(options) {
2324
+
2325
+ var isValidValue = function (mask, value) {
2326
+ var reg = mask
2327
+ .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
2328
+ .replace(/_/g, '{digit+}')
2329
+ .replace(/([0-9]{1})/g, '{digit$1}')
2330
+ .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
2331
+ .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
2332
+ return (new RegExp(reg)).test(value);
2333
+ },
2334
+ getCaretPos = function (input) {
2335
+ try {
2336
+ if (options.ownerDocument.selection && options.ownerDocument.selection.createRange) {
2337
+ var range = options.ownerDocument.selection.createRange();
2338
+ return range.getBookmark().charCodeAt(2) - 2;
2339
+ }
2340
+ if (input.setSelectionRange) {
2341
+ return input.selectionStart;
2342
+ }
2343
+ } catch (e) {
2344
+ return 0;
2345
+ }
2346
+ },
2347
+ setCaretPos = function (node, pos) {
2348
+ node = (typeof node === "string" || node instanceof String) ? options.ownerDocument.getElementById(node) : node;
2349
+ if (!node) {
2350
+ return false;
2351
+ }
2352
+ if (node.createTextRange) {
2353
+ var textRange = node.createTextRange();
2354
+ textRange.collapse(true);
2355
+ textRange.moveEnd('character', pos);
2356
+ textRange.moveStart('character', pos);
2357
+ textRange.select();
2358
+ return true;
2359
+ }
2360
+ if (node.setSelectionRange) {
2361
+ node.setSelectionRange(pos, pos);
2362
+ return true;
2363
+ }
2364
+ return false;
2365
+ };
2366
+
2367
+ if(options.mask) {
2368
+ input.off('keydown.xdsoft');
2369
+ }
2370
+
2371
+ if (options.mask === true) {
2372
+ if (dateHelper.formatMask) {
2373
+ options.mask = dateHelper.formatMask(options.format)
2374
+ } else {
2375
+ options.mask = options.format
2376
+ .replace(/Y/g, '9999')
2377
+ .replace(/F/g, '9999')
2378
+ .replace(/m/g, '19')
2379
+ .replace(/d/g, '39')
2380
+ .replace(/H/g, '29')
2381
+ .replace(/i/g, '59')
2382
+ .replace(/s/g, '59');
2383
+ }
2384
+ }
2385
+
2386
+ if ($.type(options.mask) === 'string') {
2387
+ if (!isValidValue(options.mask, input.val())) {
2388
+ input.val(options.mask.replace(/[0-9]/g, '_'));
2389
+ setCaretPos(input[0], 0);
2390
+ }
2391
+
2392
+ input.on('paste.xdsoft', function (event) {
2393
+ // couple options here
2394
+ // 1. return false - tell them they can't paste
2395
+ // 2. insert over current characters - minimal validation
2396
+ // 3. full fledged parsing and validation
2397
+ // let's go option 2 for now
2398
+
2399
+ // fires multiple times for some reason
2400
+
2401
+ // https://stackoverflow.com/a/30496488/1366033
2402
+ var clipboardData = event.clipboardData || event.originalEvent.clipboardData || window.clipboardData,
2403
+ pastedData = clipboardData.getData('text'),
2404
+ val = this.value,
2405
+ pos = this.selectionStart
2406
+
2407
+ var valueBeforeCursor = val.substr(0, pos);
2408
+ var valueAfterPaste = val.substr(pos + pastedData.length);
2409
+
2410
+ val = valueBeforeCursor + pastedData + valueAfterPaste;
2411
+ pos += pastedData.length;
2412
+
2413
+ if (isValidValue(options.mask, val)) {
2414
+ this.value = val;
2415
+ setCaretPos(this, pos);
2416
+ } else if ($.trim(val) === '') {
2417
+ this.value = options.mask.replace(/[0-9]/g, '_');
2418
+ } else {
2419
+ input.trigger('error_input.xdsoft');
2420
+ }
2421
+
2422
+ event.preventDefault();
2423
+ return false;
2424
+ });
2425
+
2426
+ input.on('keydown.xdsoft', function (event) {
2427
+ var val = this.value,
2428
+ key = event.which,
2429
+ pos = this.selectionStart,
2430
+ selEnd = this.selectionEnd,
2431
+ hasSel = pos !== selEnd,
2432
+ digit;
2433
+
2434
+ // only alow these characters
2435
+ if (((key >= KEY0 && key <= KEY9) ||
2436
+ (key >= _KEY0 && key <= _KEY9)) ||
2437
+ (key === BACKSPACE || key === DEL)) {
2438
+
2439
+ // get char to insert which is new character or placeholder ('_')
2440
+ digit = (key === BACKSPACE || key === DEL) ? '_' :
2441
+ String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key);
2442
+
2443
+ // we're deleting something, we're not at the start, and have normal cursor, move back one
2444
+ // if we have a selection length, cursor actually sits behind deletable char, not in front
2445
+ if (key === BACKSPACE && pos && !hasSel) {
2446
+ pos -= 1;
2447
+ }
2448
+
2449
+ // don't stop on a separator, continue whatever direction you were going
2450
+ // value char - keep incrementing position while on separator char and we still have room
2451
+ // del char - keep decrementing position while on separator char and we still have room
2452
+ while (true) {
2453
+ var maskValueAtCurPos = options.mask.substr(pos, 1);
2454
+ var posShorterThanMaskLength = pos < options.mask.length;
2455
+ var posGreaterThanZero = pos > 0;
2456
+ var notNumberOrPlaceholder = /[^0-9_]/;
2457
+ var curPosOnSep = notNumberOrPlaceholder.test(maskValueAtCurPos);
2458
+ var continueMovingPosition = curPosOnSep && posShorterThanMaskLength && posGreaterThanZero
2459
+
2460
+ // if we hit a real char, stay where we are
2461
+ if (!continueMovingPosition) break;
2462
+
2463
+ // hitting backspace in a selection, you can possibly go back any further - go forward
2464
+ pos += (key === BACKSPACE && !hasSel) ? -1 : 1;
2465
+
2466
+ }
2467
+
2468
+ if (event.metaKey) { // cmd has been pressed
2469
+ pos = 0;
2470
+ hasSel = true;
2471
+ }
2472
+
2473
+ if (hasSel) {
2474
+ // pos might have moved so re-calc length
2475
+ var selLength = selEnd - pos
2476
+
2477
+ // if we have a selection length we will wipe out entire selection and replace with default template for that range
2478
+ var defaultBlank = options.mask.replace(/[0-9]/g, '_');
2479
+ var defaultBlankSelectionReplacement = defaultBlank.substr(pos, selLength);
2480
+ var selReplacementRemainder = defaultBlankSelectionReplacement.substr(1) // might be empty
2481
+
2482
+ var valueBeforeSel = val.substr(0, pos);
2483
+ var insertChars = digit + selReplacementRemainder;
2484
+ var charsAfterSelection = val.substr(pos + selLength);
2485
+
2486
+ val = valueBeforeSel + insertChars + charsAfterSelection
2487
+
2488
+ } else {
2489
+ var valueBeforeCursor = val.substr(0, pos);
2490
+ var insertChar = digit;
2491
+ var valueAfterNextChar = val.substr(pos + 1);
2492
+
2493
+ val = valueBeforeCursor + insertChar + valueAfterNextChar
2494
+ }
2495
+
2496
+ if ($.trim(val) === '') {
2497
+ // if empty, set to default
2498
+ val = defaultBlank
2499
+ } else {
2500
+ // if at the last character don't need to do anything
2501
+ if (pos === options.mask.length) {
2502
+ event.preventDefault();
2503
+ return false;
2504
+ }
2505
+ }
2506
+
2507
+ // resume cursor location
2508
+ pos += (key === BACKSPACE) ? 0 : 1;
2509
+ // don't stop on a separator, continue whatever direction you were going
2510
+ while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
2511
+ pos += (key === BACKSPACE) ? 0 : 1;
2512
+ }
2513
+
2514
+ if (isValidValue(options.mask, val)) {
2515
+ this.value = val;
2516
+ setCaretPos(this, pos);
2517
+ } else if ($.trim(val) === '') {
2518
+ this.value = options.mask.replace(/[0-9]/g, '_');
2519
+ } else {
2520
+ input.trigger('error_input.xdsoft');
2521
+ }
2522
+ } else {
2523
+ if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
2524
+ return true;
2525
+ }
2526
+ }
2527
+
2528
+ event.preventDefault();
2529
+ return false;
2530
+ });
2531
+ }
2532
+ }
2533
+
2534
+ _xdsoft_datetime.setCurrentTime(getCurrentValue());
2535
+
2536
+ input
2537
+ .data('xdsoft_datetimepicker', datetimepicker)
2538
+ .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function () {
2539
+ if (input.is(':disabled') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
2540
+ return;
2541
+ }
2542
+ if (!options.openOnFocus) {
2543
+ return;
2544
+ }
2545
+ clearTimeout(timer);
2546
+ timer = setTimeout(function () {
2547
+ if (input.is(':disabled')) {
2548
+ return;
2549
+ }
2550
+
2551
+ triggerAfterOpen = true;
2552
+ _xdsoft_datetime.setCurrentTime(getCurrentValue(), true);
2553
+ if(options.mask) {
2554
+ setMask(options);
2555
+ }
2556
+ datetimepicker.trigger('open.xdsoft');
2557
+ }, 100);
2558
+ })
2559
+ .on('keydown.xdsoft', function (event) {
2560
+ var elementSelector,
2561
+ key = event.which;
2562
+ if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
2563
+ elementSelector = $("input:visible,textarea:visible,button:visible,a:visible");
2564
+ datetimepicker.trigger('close.xdsoft');
2565
+ elementSelector.eq(elementSelector.index(this) + 1).focus();
2566
+ return false;
2567
+ }
2568
+ if ([TAB].indexOf(key) !== -1) {
2569
+ datetimepicker.trigger('close.xdsoft');
2570
+ return true;
2571
+ }
2572
+ })
2573
+ .on('blur.xdsoft', function () {
2574
+ datetimepicker.trigger('close.xdsoft');
2575
+ });
2576
+ };
2577
+ destroyDateTimePicker = function (input) {
2578
+ var datetimepicker = input.data('xdsoft_datetimepicker');
2579
+ if (datetimepicker) {
2580
+ datetimepicker.data('xdsoft_datetime', null);
2581
+ datetimepicker.remove();
2582
+ input
2583
+ .data('xdsoft_datetimepicker', null)
2584
+ .off('.xdsoft');
2585
+ $(options.contentWindow).off('resize.xdsoft');
2586
+ $([options.contentWindow, options.ownerDocument.body]).off('mousedown.xdsoft touchstart');
2587
+ if (input.unmousewheel) {
2588
+ input.unmousewheel();
2589
+ }
2590
+ }
2591
+ };
2592
+ $(options.ownerDocument)
2593
+ .off('keydown.xdsoftctrl keyup.xdsoftctrl')
2594
+ .off('keydown.xdsoftcmd keyup.xdsoftcmd')
2595
+ .on('keydown.xdsoftctrl', function (e) {
2596
+ if (e.keyCode === CTRLKEY) {
2597
+ ctrlDown = true;
2598
+ }
2599
+ })
2600
+ .on('keyup.xdsoftctrl', function (e) {
2601
+ if (e.keyCode === CTRLKEY) {
2602
+ ctrlDown = false;
2603
+ }
2604
+ })
2605
+ .on('keydown.xdsoftcmd', function (e) {
2606
+ if (e.keyCode === CMDKEY) {
2607
+ cmdDown = true;
2608
+ }
2609
+ })
2610
+ .on('keyup.xdsoftcmd', function (e) {
2611
+ if (e.keyCode === CMDKEY) {
2612
+ cmdDown = false;
2613
+ }
2614
+ });
2615
+
2616
+ this.each(function () {
2617
+ var datetimepicker = $(this).data('xdsoft_datetimepicker'), $input;
2618
+ if (datetimepicker) {
2619
+ if ($.type(opt) === 'string') {
2620
+ switch (opt) {
2621
+ case 'show':
2622
+ $(this).select().focus();
2623
+ datetimepicker.trigger('open.xdsoft');
2624
+ break;
2625
+ case 'hide':
2626
+ datetimepicker.trigger('close.xdsoft');
2627
+ break;
2628
+ case 'toggle':
2629
+ datetimepicker.trigger('toggle.xdsoft');
2630
+ break;
2631
+ case 'destroy':
2632
+ destroyDateTimePicker($(this));
2633
+ break;
2634
+ case 'reset':
2635
+ this.value = this.defaultValue;
2636
+ if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(dateHelper.parseDate(this.value, options.format))) {
2637
+ datetimepicker.data('changed', false);
2638
+ }
2639
+ datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
2640
+ break;
2641
+ case 'validate':
2642
+ $input = datetimepicker.data('input');
2643
+ $input.trigger('blur.xdsoft');
2644
+ break;
2645
+ default:
2646
+ if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) {
2647
+ result = datetimepicker[opt](opt2);
2648
+ }
2649
+ }
2650
+ } else {
2651
+ datetimepicker
2652
+ .setOptions(opt);
2653
+ }
2654
+ return 0;
2655
+ }
2656
+ if ($.type(opt) !== 'string') {
2657
+ if (!options.lazyInit || options.open || options.inline) {
2658
+ createDateTimePicker($(this));
2659
+ } else {
2660
+ lazyInit($(this));
2661
+ }
2662
+ }
2663
+ });
2664
+
2665
+ return result;
2666
+ };
2667
+
2668
+ $.fn.datetimepicker.defaults = default_options;
2669
+
2670
+ function HighlightedDate(date, desc, style) {
2671
+ "use strict";
2672
+ this.date = date;
2673
+ this.desc = desc;
2674
+ this.style = style;
2675
+ }
2676
+ };
2677
+ ;(function (factory) {
2678
+ if ( typeof define === 'function' && define.amd ) {
2679
+ // AMD. Register as an anonymous module.
2680
+ define(['jquery', 'jquery-mousewheel'], factory);
2681
+ } else if (typeof exports === 'object') {
2682
+ // Node/CommonJS style for Browserify
2683
+ module.exports = factory(require('jquery'));;
2684
+ } else {
2685
+ // Browser globals
2686
+ factory(jQuery);
2687
+ }
2688
+ }(datetimepickerFactory));
2689
+
2690
+
2691
+ /*!
2692
+ * jQuery Mousewheel 3.1.13
2693
+ *
2694
+ * Copyright jQuery Foundation and other contributors
2695
+ * Released under the MIT license
2696
+ * http://jquery.org/license
2697
+ */
2698
+
2699
+ (function (factory) {
2700
+ if ( typeof define === 'function' && define.amd ) {
2701
+ // AMD. Register as an anonymous module.
2702
+ define(['jquery'], factory);
2703
+ } else if (typeof exports === 'object') {
2704
+ // Node/CommonJS style for Browserify
2705
+ module.exports = factory;
2706
+ } else {
2707
+ // Browser globals
2708
+ factory(jQuery);
2709
+ }
2710
+ }(function ($) {
2711
+
2712
+ var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
2713
+ toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
2714
+ ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
2715
+ slice = Array.prototype.slice,
2716
+ nullLowestDeltaTimeout, lowestDelta;
2717
+
2718
+ if ( $.event.fixHooks ) {
2719
+ for ( var i = toFix.length; i; ) {
2720
+ $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
2721
+ }
2722
+ }
2723
+
2724
+ var special = $.event.special.mousewheel = {
2725
+ version: '3.1.12',
2726
+
2727
+ setup: function() {
2728
+ if ( this.addEventListener ) {
2729
+ for ( var i = toBind.length; i; ) {
2730
+ this.addEventListener( toBind[--i], handler, false );
2731
+ }
2732
+ } else {
2733
+ this.onmousewheel = handler;
2734
+ }
2735
+ // Store the line height and page height for this particular element
2736
+ $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
2737
+ $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
2738
+ },
2739
+
2740
+ teardown: function() {
2741
+ if ( this.removeEventListener ) {
2742
+ for ( var i = toBind.length; i; ) {
2743
+ this.removeEventListener( toBind[--i], handler, false );
2744
+ }
2745
+ } else {
2746
+ this.onmousewheel = null;
2747
+ }
2748
+ // Clean up the data we added to the element
2749
+ $.removeData(this, 'mousewheel-line-height');
2750
+ $.removeData(this, 'mousewheel-page-height');
2751
+ },
2752
+
2753
+ getLineHeight: function(elem) {
2754
+ var $elem = $(elem),
2755
+ $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
2756
+ if (!$parent.length) {
2757
+ $parent = $('body');
2758
+ }
2759
+ return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
2760
+ },
2761
+
2762
+ getPageHeight: function(elem) {
2763
+ return $(elem).height();
2764
+ },
2765
+
2766
+ settings: {
2767
+ adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
2768
+ normalizeOffset: true // calls getBoundingClientRect for each event
2769
+ }
2770
+ };
2771
+
2772
+ $.fn.extend({
2773
+ mousewheel: function(fn) {
2774
+ return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
2775
+ },
2776
+
2777
+ unmousewheel: function(fn) {
2778
+ return this.unbind('mousewheel', fn);
2779
+ }
2780
+ });
2781
+
2782
+
2783
+ function handler(event) {
2784
+ var orgEvent = event || window.event,
2785
+ args = slice.call(arguments, 1),
2786
+ delta = 0,
2787
+ deltaX = 0,
2788
+ deltaY = 0,
2789
+ absDelta = 0,
2790
+ offsetX = 0,
2791
+ offsetY = 0;
2792
+ event = $.event.fix(orgEvent);
2793
+ event.type = 'mousewheel';
2794
+
2795
+ // Old school scrollwheel delta
2796
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
2797
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
2798
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
2799
+ if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
2800
+
2801
+ // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
2802
+ if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
2803
+ deltaX = deltaY * -1;
2804
+ deltaY = 0;
2805
+ }
2806
+
2807
+ // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
2808
+ delta = deltaY === 0 ? deltaX : deltaY;
2809
+
2810
+ // New school wheel delta (wheel event)
2811
+ if ( 'deltaY' in orgEvent ) {
2812
+ deltaY = orgEvent.deltaY * -1;
2813
+ delta = deltaY;
2814
+ }
2815
+ if ( 'deltaX' in orgEvent ) {
2816
+ deltaX = orgEvent.deltaX;
2817
+ if ( deltaY === 0 ) { delta = deltaX * -1; }
2818
+ }
2819
+
2820
+ // No change actually happened, no reason to go any further
2821
+ if ( deltaY === 0 && deltaX === 0 ) { return; }
2822
+
2823
+ // Need to convert lines and pages to pixels if we aren't already in pixels
2824
+ // There are three delta modes:
2825
+ // * deltaMode 0 is by pixels, nothing to do
2826
+ // * deltaMode 1 is by lines
2827
+ // * deltaMode 2 is by pages
2828
+ if ( orgEvent.deltaMode === 1 ) {
2829
+ var lineHeight = $.data(this, 'mousewheel-line-height');
2830
+ delta *= lineHeight;
2831
+ deltaY *= lineHeight;
2832
+ deltaX *= lineHeight;
2833
+ } else if ( orgEvent.deltaMode === 2 ) {
2834
+ var pageHeight = $.data(this, 'mousewheel-page-height');
2835
+ delta *= pageHeight;
2836
+ deltaY *= pageHeight;
2837
+ deltaX *= pageHeight;
2838
+ }
2839
+
2840
+ // Store lowest absolute delta to normalize the delta values
2841
+ absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
2842
+
2843
+ if ( !lowestDelta || absDelta < lowestDelta ) {
2844
+ lowestDelta = absDelta;
2845
+
2846
+ // Adjust older deltas if necessary
2847
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
2848
+ lowestDelta /= 40;
2849
+ }
2850
+ }
2851
+
2852
+ // Adjust older deltas if necessary
2853
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
2854
+ // Divide all the things by 40!
2855
+ delta /= 40;
2856
+ deltaX /= 40;
2857
+ deltaY /= 40;
2858
+ }
2859
+
2860
+ // Get a whole, normalized value for the deltas
2861
+ delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
2862
+ deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
2863
+ deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
2864
+
2865
+ // Normalise offsetX and offsetY properties
2866
+ if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
2867
+ var boundingRect = this.getBoundingClientRect();
2868
+ offsetX = event.clientX - boundingRect.left;
2869
+ offsetY = event.clientY - boundingRect.top;
2870
+ }
2871
+
2872
+ // Add information to the event object
2873
+ event.deltaX = deltaX;
2874
+ event.deltaY = deltaY;
2875
+ event.deltaFactor = lowestDelta;
2876
+ event.offsetX = offsetX;
2877
+ event.offsetY = offsetY;
2878
+ // Go ahead and set deltaMode to 0 since we converted to pixels
2879
+ // Although this is a little odd since we overwrite the deltaX/Y
2880
+ // properties with normalized deltas.
2881
+ event.deltaMode = 0;
2882
+
2883
+ // Add event and delta to the front of the arguments
2884
+ args.unshift(event, delta, deltaX, deltaY);
2885
+
2886
+ // Clearout lowestDelta after sometime to better
2887
+ // handle multiple device types that give different
2888
+ // a different lowestDelta
2889
+ // Ex: trackpad = 3 and mouse wheel = 120
2890
+ if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
2891
+ nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
2892
+
2893
+ return ($.event.dispatch || $.event.handle).apply(this, args);
2894
+ }
2895
+
2896
+ function nullLowestDelta() {
2897
+ lowestDelta = null;
2898
+ }
2899
+
2900
+ function shouldAdjustOldDeltas(orgEvent, absDelta) {
2901
+ // If this is an older event and the delta is divisable by 120,
2902
+ // then we are assuming that the browser is treating this as an
2903
+ // older mouse wheel event and that we should divide the deltas
2904
+ // by 40 to try and get a more usable deltaFactor.
2905
+ // Side note, this actually impacts the reported scroll distance
2906
+ // in older browsers and can cause scrolling to be slower than native.
2907
+ // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
2908
+ return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
2909
+ }
2910
+
2911
+ }));