jquery.datetimepicker.js 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393
  1. /**
  2. * @preserve jQuery DateTimePicker plugin v2.5.4
  3. * @homepage http://xdsoft.net/jqplugins/datetimepicker/
  4. * @author Chupurnov Valeriy (<chupurnov@gmail.com>)
  5. */
  6. /*global DateFormatter, document,window,jQuery,setTimeout,clearTimeout,HighlightedDate,getCurrentValue*/
  7. ;(function (factory) {
  8. if ( typeof define === 'function' && define.amd ) {
  9. // AMD. Register as an anonymous module.
  10. define(['jquery', 'jquery-mousewheel'], factory);
  11. } else if (typeof exports === 'object') {
  12. // Node/CommonJS style for Browserify
  13. module.exports = factory;
  14. } else {
  15. // Browser globals
  16. factory(jQuery);
  17. }
  18. }(function ($) {
  19. 'use strict';
  20. var default_options = {
  21. i18n: {
  22. ar: { // Arabic
  23. months: [
  24. "كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
  25. ],
  26. dayOfWeekShort: [
  27. "ن", "ث", "ع", "خ", "ج", "س", "ح"
  28. ],
  29. dayOfWeek: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"]
  30. },
  31. ro: { // Romanian
  32. months: [
  33. "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"
  34. ],
  35. dayOfWeekShort: [
  36. "Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ"
  37. ],
  38. dayOfWeek: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"]
  39. },
  40. id: { // Indonesian
  41. months: [
  42. "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"
  43. ],
  44. dayOfWeekShort: [
  45. "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"
  46. ],
  47. dayOfWeek: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"]
  48. },
  49. is: { // Icelandic
  50. months: [
  51. "Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"
  52. ],
  53. dayOfWeekShort: [
  54. "Sun", "Mán", "Þrið", "Mið", "Fim", "Fös", "Lau"
  55. ],
  56. dayOfWeek: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"]
  57. },
  58. bg: { // Bulgarian
  59. months: [
  60. "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
  61. ],
  62. dayOfWeekShort: [
  63. "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
  64. ],
  65. dayOfWeek: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"]
  66. },
  67. fa: { // Persian/Farsi
  68. months: [
  69. 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
  70. ],
  71. dayOfWeekShort: [
  72. 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
  73. ],
  74. dayOfWeek: ["یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", "شنبه", "یک‌شنبه"]
  75. },
  76. ru: { // Russian
  77. months: [
  78. 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
  79. ],
  80. dayOfWeekShort: [
  81. "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
  82. ],
  83. dayOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]
  84. },
  85. uk: { // Ukrainian
  86. months: [
  87. 'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
  88. ],
  89. dayOfWeekShort: [
  90. "Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
  91. ],
  92. dayOfWeek: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"]
  93. },
  94. en: { // English
  95. months: [
  96. "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
  97. ],
  98. dayOfWeekShort: [
  99. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  100. ],
  101. dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
  102. },
  103. el: { // Ελληνικά
  104. months: [
  105. "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
  106. ],
  107. dayOfWeekShort: [
  108. "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
  109. ],
  110. dayOfWeek: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"]
  111. },
  112. de: { // German
  113. months: [
  114. 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
  115. ],
  116. dayOfWeekShort: [
  117. "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
  118. ],
  119. dayOfWeek: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
  120. },
  121. nl: { // Dutch
  122. months: [
  123. "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
  124. ],
  125. dayOfWeekShort: [
  126. "zo", "ma", "di", "wo", "do", "vr", "za"
  127. ],
  128. dayOfWeek: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"]
  129. },
  130. tr: { // Turkish
  131. months: [
  132. "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
  133. ],
  134. dayOfWeekShort: [
  135. "Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
  136. ],
  137. dayOfWeek: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"]
  138. },
  139. fr: { //French
  140. months: [
  141. "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
  142. ],
  143. dayOfWeekShort: [
  144. "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
  145. ],
  146. dayOfWeek: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
  147. },
  148. es: { // Spanish
  149. months: [
  150. "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
  151. ],
  152. dayOfWeekShort: [
  153. "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
  154. ],
  155. dayOfWeek: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
  156. },
  157. th: { // Thai
  158. months: [
  159. 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
  160. ],
  161. dayOfWeekShort: [
  162. 'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
  163. ],
  164. dayOfWeek: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"]
  165. },
  166. pl: { // Polish
  167. months: [
  168. "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
  169. ],
  170. dayOfWeekShort: [
  171. "nd", "pn", "wt", "śr", "cz", "pt", "sb"
  172. ],
  173. dayOfWeek: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
  174. },
  175. pt: { // Portuguese
  176. months: [
  177. "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
  178. ],
  179. dayOfWeekShort: [
  180. "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
  181. ],
  182. dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
  183. },
  184. ch: { // Simplified Chinese
  185. months: [
  186. "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
  187. ],
  188. dayOfWeekShort: [
  189. "日", "一", "二", "三", "四", "五", "六"
  190. ]
  191. },
  192. se: { // Swedish
  193. months: [
  194. "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
  195. ],
  196. dayOfWeekShort: [
  197. "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
  198. ]
  199. },
  200. kr: { // Korean
  201. months: [
  202. "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
  203. ],
  204. dayOfWeekShort: [
  205. "일", "월", "화", "수", "목", "금", "토"
  206. ],
  207. dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
  208. },
  209. it: { // Italian
  210. months: [
  211. "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
  212. ],
  213. dayOfWeekShort: [
  214. "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
  215. ],
  216. dayOfWeek: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]
  217. },
  218. da: { // Dansk
  219. months: [
  220. "January", "Februar", "Marts", "April", "Maj", "Juni", "July", "August", "September", "Oktober", "November", "December"
  221. ],
  222. dayOfWeekShort: [
  223. "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
  224. ],
  225. dayOfWeek: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"]
  226. },
  227. no: { // Norwegian
  228. months: [
  229. "Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
  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. ja: { // Japanese
  237. months: [
  238. "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
  239. ],
  240. dayOfWeekShort: [
  241. "日", "月", "火", "水", "木", "金", "土"
  242. ],
  243. dayOfWeek: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"]
  244. },
  245. vi: { // Vietnamese
  246. months: [
  247. "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"
  248. ],
  249. dayOfWeekShort: [
  250. "CN", "T2", "T3", "T4", "T5", "T6", "T7"
  251. ],
  252. dayOfWeek: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
  253. },
  254. sl: { // Slovenščina
  255. months: [
  256. "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"
  257. ],
  258. dayOfWeekShort: [
  259. "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
  260. ],
  261. dayOfWeek: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"]
  262. },
  263. cs: { // Čeština
  264. months: [
  265. "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
  266. ],
  267. dayOfWeekShort: [
  268. "Ne", "Po", "Út", "St", "Čt", "Pá", "So"
  269. ]
  270. },
  271. hu: { // Hungarian
  272. months: [
  273. "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
  274. ],
  275. dayOfWeekShort: [
  276. "Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
  277. ],
  278. dayOfWeek: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"]
  279. },
  280. az: { //Azerbaijanian (Azeri)
  281. months: [
  282. "Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"
  283. ],
  284. dayOfWeekShort: [
  285. "B", "Be", "Ça", "Ç", "Ca", "C", "Ş"
  286. ],
  287. dayOfWeek: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"]
  288. },
  289. bs: { //Bosanski
  290. months: [
  291. "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
  292. ],
  293. dayOfWeekShort: [
  294. "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
  295. ],
  296. dayOfWeek: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
  297. },
  298. ca: { //Català
  299. months: [
  300. "Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"
  301. ],
  302. dayOfWeekShort: [
  303. "Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds"
  304. ],
  305. dayOfWeek: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"]
  306. },
  307. 'en-GB': { //English (British)
  308. months: [
  309. "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
  310. ],
  311. dayOfWeekShort: [
  312. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  313. ],
  314. dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
  315. },
  316. et: { //"Eesti"
  317. months: [
  318. "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"
  319. ],
  320. dayOfWeekShort: [
  321. "P", "E", "T", "K", "N", "R", "L"
  322. ],
  323. dayOfWeek: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"]
  324. },
  325. eu: { //Euskara
  326. months: [
  327. "Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua"
  328. ],
  329. dayOfWeekShort: [
  330. "Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La."
  331. ],
  332. dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata']
  333. },
  334. fi: { //Finnish (Suomi)
  335. months: [
  336. "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"
  337. ],
  338. dayOfWeekShort: [
  339. "Su", "Ma", "Ti", "Ke", "To", "Pe", "La"
  340. ],
  341. dayOfWeek: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"]
  342. },
  343. gl: { //Galego
  344. months: [
  345. "Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec"
  346. ],
  347. dayOfWeekShort: [
  348. "Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab"
  349. ],
  350. dayOfWeek: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"]
  351. },
  352. hr: { //Hrvatski
  353. months: [
  354. "Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"
  355. ],
  356. dayOfWeekShort: [
  357. "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
  358. ],
  359. dayOfWeek: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
  360. },
  361. ko: { //Korean (한국어)
  362. months: [
  363. "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
  364. ],
  365. dayOfWeekShort: [
  366. "일", "월", "화", "수", "목", "금", "토"
  367. ],
  368. dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
  369. },
  370. lt: { //Lithuanian (lietuvių)
  371. months: [
  372. "Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio"
  373. ],
  374. dayOfWeekShort: [
  375. "Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš"
  376. ],
  377. dayOfWeek: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"]
  378. },
  379. lv: { //Latvian (Latviešu)
  380. months: [
  381. "Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"
  382. ],
  383. dayOfWeekShort: [
  384. "Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St"
  385. ],
  386. dayOfWeek: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"]
  387. },
  388. mk: { //Macedonian (Македонски)
  389. months: [
  390. "јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"
  391. ],
  392. dayOfWeekShort: [
  393. "нед", "пон", "вто", "сре", "чет", "пет", "саб"
  394. ],
  395. dayOfWeek: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"]
  396. },
  397. mn: { //Mongolian (Монгол)
  398. months: [
  399. "1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар"
  400. ],
  401. dayOfWeekShort: [
  402. "Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням"
  403. ],
  404. dayOfWeek: ["Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба", "Ням"]
  405. },
  406. 'pt-BR': { //Português(Brasil)
  407. months: [
  408. "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
  409. ],
  410. dayOfWeekShort: [
  411. "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"
  412. ],
  413. dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
  414. },
  415. sk: { //Slovenčina
  416. months: [
  417. "Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"
  418. ],
  419. dayOfWeekShort: [
  420. "Ne", "Po", "Ut", "St", "Št", "Pi", "So"
  421. ],
  422. dayOfWeek: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"]
  423. },
  424. sq: { //Albanian (Shqip)
  425. months: [
  426. "Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"
  427. ],
  428. dayOfWeekShort: [
  429. "Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu"
  430. ],
  431. dayOfWeek: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"]
  432. },
  433. 'sr-YU': { //Serbian (Srpski)
  434. months: [
  435. "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
  436. ],
  437. dayOfWeekShort: [
  438. "Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub"
  439. ],
  440. dayOfWeek: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"]
  441. },
  442. sr: { //Serbian Cyrillic (Српски)
  443. months: [
  444. "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар"
  445. ],
  446. dayOfWeekShort: [
  447. "нед", "пон", "уто", "сре", "чет", "пет", "суб"
  448. ],
  449. dayOfWeek: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"]
  450. },
  451. sv: { //Svenska
  452. months: [
  453. "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
  454. ],
  455. dayOfWeekShort: [
  456. "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
  457. ],
  458. dayOfWeek: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"]
  459. },
  460. 'zh-TW': { //Traditional Chinese (繁體中文)
  461. months: [
  462. "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
  463. ],
  464. dayOfWeekShort: [
  465. "日", "一", "二", "三", "四", "五", "六"
  466. ],
  467. dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
  468. },
  469. zh: { //Simplified Chinese (简体中文)
  470. months: [
  471. "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
  472. ],
  473. dayOfWeekShort: [
  474. "日", "一", "二", "三", "四", "五", "六"
  475. ],
  476. dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
  477. },
  478. he: { //Hebrew (עברית)
  479. months: [
  480. 'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
  481. ],
  482. dayOfWeekShort: [
  483. 'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
  484. ],
  485. dayOfWeek: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"]
  486. },
  487. hy: { // Armenian
  488. months: [
  489. "Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"
  490. ],
  491. dayOfWeekShort: [
  492. "Կի", "Երկ", "Երք", "Չոր", "Հնգ", "Ուրբ", "Շբթ"
  493. ],
  494. dayOfWeek: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"]
  495. },
  496. kg: { // Kyrgyz
  497. months: [
  498. 'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'
  499. ],
  500. dayOfWeekShort: [
  501. "Жек", "Дүй", "Шей", "Шар", "Бей", "Жум", "Ише"
  502. ],
  503. dayOfWeek: [
  504. "Жекшемб", "Дүйшөмб", "Шейшемб", "Шаршемб", "Бейшемби", "Жума", "Ишенб"
  505. ]
  506. },
  507. rm: { // Romansh
  508. months: [
  509. "Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December"
  510. ],
  511. dayOfWeekShort: [
  512. "Du", "Gli", "Ma", "Me", "Gie", "Ve", "So"
  513. ],
  514. dayOfWeek: [
  515. "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda"
  516. ]
  517. },
  518. ka: { // Georgian
  519. months: [
  520. 'იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'
  521. ],
  522. dayOfWeekShort: [
  523. "კვ", "ორშ", "სამშ", "ოთხ", "ხუთ", "პარ", "შაბ"
  524. ],
  525. dayOfWeek: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი"]
  526. }
  527. },
  528. ownerDocument: document,
  529. contentWindow: window,
  530. value: '',
  531. rtl: false,
  532. format: 'Y/m/d H:i',
  533. formatTime: 'H:i',
  534. formatDate: 'Y/m/d',
  535. startDate: false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
  536. step: 60,
  537. monthChangeSpinner: true,
  538. closeOnDateSelect: false,
  539. closeOnTimeSelect: true,
  540. closeOnWithoutClick: true,
  541. closeOnInputClick: true,
  542. timepicker: true,
  543. datepicker: true,
  544. weeks: false,
  545. defaultTime: false, // use formatTime format (ex. '10:00' for formatTime: 'H:i')
  546. defaultDate: false, // use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
  547. minDate: false,
  548. maxDate: false,
  549. minTime: false,
  550. maxTime: false,
  551. disabledMinTime: false,
  552. disabledMaxTime: false,
  553. allowTimes: [],
  554. opened: false,
  555. initTime: true,
  556. inline: false,
  557. theme: '',
  558. onSelectDate: function () {},
  559. onSelectTime: function () {},
  560. onChangeMonth: function () {},
  561. onGetWeekOfYear: function () {},
  562. onChangeYear: function () {},
  563. onChangeDateTime: function () {},
  564. onShow: function () {},
  565. onClose: function () {},
  566. onGenerate: function () {},
  567. withoutCopyright: true,
  568. inverseButton: false,
  569. hours12: false,
  570. next: 'xdsoft_next',
  571. prev : 'xdsoft_prev',
  572. dayOfWeekStart: 0,
  573. parentID: 'body',
  574. timeHeightInTimePicker: 25,
  575. timepickerScrollbar: true,
  576. todayButton: true,
  577. prevButton: true,
  578. nextButton: true,
  579. defaultSelect: true,
  580. scrollMonth: true,
  581. scrollTime: true,
  582. scrollInput: true,
  583. lazyInit: false,
  584. mask: false,
  585. validateOnBlur: true,
  586. allowBlank: true,
  587. yearStart: 1950,
  588. yearEnd: 2050,
  589. monthStart: 0,
  590. monthEnd: 11,
  591. style: '',
  592. id: '',
  593. fixed: false,
  594. roundTime: 'round', // ceil, floor
  595. className: '',
  596. weekends: [],
  597. highlightedDates: [],
  598. highlightedPeriods: [],
  599. allowDates : [],
  600. allowDateRe : null,
  601. disabledDates : [],
  602. disabledWeekDays: [],
  603. yearOffset: 0,
  604. beforeShowDay: null,
  605. enterLikeTab: true,
  606. showApplyButton: false
  607. };
  608. var dateHelper = null,
  609. globalLocaleDefault = 'en',
  610. globalLocale = 'en';
  611. var dateFormatterOptionsDefault = {
  612. meridiem: ['AM', 'PM']
  613. };
  614. var initDateFormatter = function(){
  615. var locale = default_options.i18n[globalLocale],
  616. opts = {
  617. days: locale.dayOfWeek,
  618. daysShort: locale.dayOfWeekShort,
  619. months: locale.months,
  620. monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) })
  621. };
  622. if (typeof DateFormatter === 'function') {
  623. dateHelper = new DateFormatter({
  624. dateSettings: $.extend({}, dateFormatterOptionsDefault, opts)
  625. });
  626. }
  627. };
  628. // for locale settings
  629. $.datetimepicker = {
  630. setLocale: function(locale){
  631. var newLocale = default_options.i18n[locale]?locale:globalLocaleDefault;
  632. if(globalLocale != newLocale){
  633. globalLocale = newLocale;
  634. // reinit date formatter
  635. initDateFormatter();
  636. }
  637. },
  638. setDateFormatter: function(dateFormatter) {
  639. dateHelper = dateFormatter;
  640. },
  641. RFC_2822: 'D, d M Y H:i:s O',
  642. ATOM: 'Y-m-d\TH:i:sP',
  643. ISO_8601: 'Y-m-d\TH:i:sO',
  644. RFC_822: 'D, d M y H:i:s O',
  645. RFC_850: 'l, d-M-y H:i:s T',
  646. RFC_1036: 'D, d M y H:i:s O',
  647. RFC_1123: 'D, d M Y H:i:s O',
  648. RSS: 'D, d M Y H:i:s O',
  649. W3C: 'Y-m-d\TH:i:sP'
  650. };
  651. // first init date formatter
  652. initDateFormatter();
  653. // fix for ie8
  654. if (!window.getComputedStyle) {
  655. window.getComputedStyle = function (el, pseudo) {
  656. this.el = el;
  657. this.getPropertyValue = function (prop) {
  658. var re = /(\-([a-z]){1})/g;
  659. if (prop === 'float') {
  660. prop = 'styleFloat';
  661. }
  662. if (re.test(prop)) {
  663. prop = prop.replace(re, function (a, b, c) {
  664. return c.toUpperCase();
  665. });
  666. }
  667. return el.currentStyle[prop] || null;
  668. };
  669. return this;
  670. };
  671. }
  672. if (!Array.prototype.indexOf) {
  673. Array.prototype.indexOf = function (obj, start) {
  674. var i, j;
  675. for (i = (start || 0), j = this.length; i < j; i += 1) {
  676. if (this[i] === obj) { return i; }
  677. }
  678. return -1;
  679. };
  680. }
  681. Date.prototype.countDaysInMonth = function () {
  682. return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
  683. };
  684. $.fn.xdsoftScroller = function (options, percent) {
  685. return this.each(function () {
  686. var timeboxparent = $(this),
  687. pointerEventToXY = function (e) {
  688. var out = {x: 0, y: 0},
  689. touch;
  690. if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
  691. touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
  692. out.x = touch.clientX;
  693. out.y = touch.clientY;
  694. } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
  695. out.x = e.clientX;
  696. out.y = e.clientY;
  697. }
  698. return out;
  699. },
  700. timebox,
  701. parentHeight,
  702. height,
  703. scrollbar,
  704. scroller,
  705. maximumOffset = 100,
  706. start = false,
  707. startY = 0,
  708. startTop = 0,
  709. h1 = 0,
  710. touchStart = false,
  711. startTopScroll = 0,
  712. calcOffset = function () {};
  713. if (percent === 'hide') {
  714. timeboxparent.find('.xdsoft_scrollbar').hide();
  715. return;
  716. }
  717. if (!$(this).hasClass('xdsoft_scroller_box')) {
  718. timebox = timeboxparent.children().eq(0);
  719. parentHeight = timeboxparent[0].clientHeight;
  720. height = timebox[0].offsetHeight;
  721. scrollbar = $('<div class="xdsoft_scrollbar"></div>');
  722. scroller = $('<div class="xdsoft_scroller"></div>');
  723. scrollbar.append(scroller);
  724. timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
  725. calcOffset = function calcOffset(event) {
  726. var offset = pointerEventToXY(event).y - startY + startTopScroll;
  727. if (offset < 0) {
  728. offset = 0;
  729. }
  730. if (offset + scroller[0].offsetHeight > h1) {
  731. offset = h1 - scroller[0].offsetHeight;
  732. }
  733. timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]);
  734. };
  735. scroller
  736. .on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) {
  737. if (!parentHeight) {
  738. timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
  739. }
  740. startY = pointerEventToXY(event).y;
  741. startTopScroll = parseInt(scroller.css('margin-top'), 10);
  742. h1 = scrollbar[0].offsetHeight;
  743. if (event.type === 'mousedown' || event.type === 'touchstart') {
  744. if (options.ownerDocument) {
  745. $(options.ownerDocument.body).addClass('xdsoft_noselect');
  746. }
  747. $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft_scroller', function arguments_callee() {
  748. $([options.ownerDocument.body, options.contentWindow]).off('touchend mouseup.xdsoft_scroller', arguments_callee)
  749. .off('mousemove.xdsoft_scroller', calcOffset)
  750. .removeClass('xdsoft_noselect');
  751. });
  752. $(options.ownerDocument.body).on('mousemove.xdsoft_scroller', calcOffset);
  753. } else {
  754. touchStart = true;
  755. event.stopPropagation();
  756. event.preventDefault();
  757. }
  758. })
  759. .on('touchmove', function (event) {
  760. if (touchStart) {
  761. event.preventDefault();
  762. calcOffset(event);
  763. }
  764. })
  765. .on('touchend touchcancel', function () {
  766. touchStart = false;
  767. startTopScroll = 0;
  768. });
  769. timeboxparent
  770. .on('scroll_element.xdsoft_scroller', function (event, percentage) {
  771. if (!parentHeight) {
  772. timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]);
  773. }
  774. percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage;
  775. scroller.css('margin-top', maximumOffset * percentage);
  776. setTimeout(function () {
  777. timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10));
  778. }, 10);
  779. })
  780. .on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) {
  781. var percent, sh;
  782. parentHeight = timeboxparent[0].clientHeight;
  783. height = timebox[0].offsetHeight;
  784. percent = parentHeight / height;
  785. sh = percent * scrollbar[0].offsetHeight;
  786. if (percent > 1) {
  787. scroller.hide();
  788. } else {
  789. scroller.show();
  790. scroller.css('height', parseInt(sh > 10 ? sh : 10, 10));
  791. maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
  792. if (noTriggerScroll !== true) {
  793. timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]);
  794. }
  795. }
  796. });
  797. timeboxparent.on('mousewheel', function (event) {
  798. var top = Math.abs(parseInt(timebox.css('marginTop'), 10));
  799. top = top - (event.deltaY * 20);
  800. if (top < 0) {
  801. top = 0;
  802. }
  803. timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]);
  804. event.stopPropagation();
  805. return false;
  806. });
  807. timeboxparent.on('touchstart', function (event) {
  808. start = pointerEventToXY(event);
  809. startTop = Math.abs(parseInt(timebox.css('marginTop'), 10));
  810. });
  811. timeboxparent.on('touchmove', function (event) {
  812. if (start) {
  813. event.preventDefault();
  814. var coord = pointerEventToXY(event);
  815. timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]);
  816. }
  817. });
  818. timeboxparent.on('touchend touchcancel', function () {
  819. start = false;
  820. startTop = 0;
  821. });
  822. }
  823. timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
  824. });
  825. };
  826. $.fn.datetimepicker = function (opt, opt2) {
  827. var result = this,
  828. KEY0 = 48,
  829. KEY9 = 57,
  830. _KEY0 = 96,
  831. _KEY9 = 105,
  832. CTRLKEY = 17,
  833. DEL = 46,
  834. ENTER = 13,
  835. ESC = 27,
  836. BACKSPACE = 8,
  837. ARROWLEFT = 37,
  838. ARROWUP = 38,
  839. ARROWRIGHT = 39,
  840. ARROWDOWN = 40,
  841. TAB = 9,
  842. F5 = 116,
  843. AKEY = 65,
  844. CKEY = 67,
  845. VKEY = 86,
  846. ZKEY = 90,
  847. YKEY = 89,
  848. ctrlDown = false,
  849. options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options),
  850. lazyInitTimer = 0,
  851. createDateTimePicker,
  852. destroyDateTimePicker,
  853. lazyInit = function (input) {
  854. input
  855. .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback() {
  856. if (input.is(':disabled') || input.data('xdsoft_datetimepicker')) {
  857. return;
  858. }
  859. clearTimeout(lazyInitTimer);
  860. lazyInitTimer = setTimeout(function () {
  861. if (!input.data('xdsoft_datetimepicker')) {
  862. createDateTimePicker(input);
  863. }
  864. input
  865. .off('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', initOnActionCallback)
  866. .trigger('open.xdsoft');
  867. }, 100);
  868. });
  869. };
  870. createDateTimePicker = function (input) {
  871. var datetimepicker = $('<div class="xdsoft_datetimepicker xdsoft_noselect"></div>'),
  872. xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
  873. datepicker = $('<div class="xdsoft_datepicker active"></div>'),
  874. month_picker = $('<div class="xdsoft_monthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
  875. '<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
  876. '<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
  877. '<button type="button" class="xdsoft_next"></button></div>'),
  878. calendar = $('<div class="xdsoft_calendar"></div>'),
  879. 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>'),
  880. timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
  881. timebox = $('<div class="xdsoft_time_variant"></div>'),
  882. applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),
  883. monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
  884. yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
  885. triggerAfterOpen = false,
  886. XDSoft_datetime,
  887. xchangeTimer,
  888. timerclick,
  889. current_time_index,
  890. setPos,
  891. timer = 0,
  892. _xdsoft_datetime,
  893. forEachAncestorOf,
  894. throttle;
  895. if (options.id) {
  896. datetimepicker.attr('id', options.id);
  897. }
  898. if (options.style) {
  899. datetimepicker.attr('style', options.style);
  900. }
  901. if (options.weeks) {
  902. datetimepicker.addClass('xdsoft_showweeks');
  903. }
  904. if (options.rtl) {
  905. datetimepicker.addClass('xdsoft_rtl');
  906. }
  907. datetimepicker.addClass('xdsoft_' + options.theme);
  908. datetimepicker.addClass(options.className);
  909. month_picker
  910. .find('.xdsoft_month span')
  911. .after(monthselect);
  912. month_picker
  913. .find('.xdsoft_year span')
  914. .after(yearselect);
  915. month_picker
  916. .find('.xdsoft_month,.xdsoft_year')
  917. .on('touchstart mousedown.xdsoft', function (event) {
  918. var select = $(this).find('.xdsoft_select').eq(0),
  919. val = 0,
  920. top = 0,
  921. visible = select.is(':visible'),
  922. items,
  923. i;
  924. month_picker
  925. .find('.xdsoft_select')
  926. .hide();
  927. if (_xdsoft_datetime.currentTime) {
  928. val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear']();
  929. }
  930. select[visible ? 'hide' : 'show']();
  931. for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) {
  932. if (items.eq(i).data('value') === val) {
  933. break;
  934. } else {
  935. top += items[0].offsetHeight;
  936. }
  937. }
  938. select.xdsoftScroller(options, top / (select.children()[0].offsetHeight - (select[0].clientHeight)));
  939. event.stopPropagation();
  940. return false;
  941. });
  942. month_picker
  943. .find('.xdsoft_select')
  944. .xdsoftScroller(options)
  945. .on('touchstart mousedown.xdsoft', function (event) {
  946. event.stopPropagation();
  947. event.preventDefault();
  948. })
  949. .on('touchstart mousedown.xdsoft', '.xdsoft_option', function () {
  950. if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
  951. _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
  952. }
  953. var year = _xdsoft_datetime.currentTime.getFullYear();
  954. if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
  955. _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value'));
  956. }
  957. $(this).parent().parent().hide();
  958. datetimepicker.trigger('xchange.xdsoft');
  959. if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
  960. options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
  961. }
  962. if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
  963. options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
  964. }
  965. });
  966. datetimepicker.getValue = function () {
  967. return _xdsoft_datetime.getCurrentTime();
  968. };
  969. datetimepicker.setOptions = function (_options) {
  970. var highlightedDates = {};
  971. options = $.extend(true, {}, options, _options);
  972. if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
  973. options.allowTimes = $.extend(true, [], _options.allowTimes);
  974. }
  975. if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) {
  976. options.weekends = $.extend(true, [], _options.weekends);
  977. }
  978. if (_options.allowDates && $.isArray(_options.allowDates) && _options.allowDates.length) {
  979. options.allowDates = $.extend(true, [], _options.allowDates);
  980. }
  981. if (_options.allowDateRe && Object.prototype.toString.call(_options.allowDateRe)==="[object String]") {
  982. options.allowDateRe = new RegExp(_options.allowDateRe);
  983. }
  984. if (_options.highlightedDates && $.isArray(_options.highlightedDates) && _options.highlightedDates.length) {
  985. $.each(_options.highlightedDates, function (index, value) {
  986. var splitData = $.map(value.split(','), $.trim),
  987. exDesc,
  988. hDate = new HighlightedDate(dateHelper.parseDate(splitData[0], options.formatDate), splitData[1], splitData[2]), // date, desc, style
  989. keyDate = dateHelper.formatDate(hDate.date, options.formatDate);
  990. if (highlightedDates[keyDate] !== undefined) {
  991. exDesc = highlightedDates[keyDate].desc;
  992. if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
  993. highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
  994. }
  995. } else {
  996. highlightedDates[keyDate] = hDate;
  997. }
  998. });
  999. options.highlightedDates = $.extend(true, [], highlightedDates);
  1000. }
  1001. if (_options.highlightedPeriods && $.isArray(_options.highlightedPeriods) && _options.highlightedPeriods.length) {
  1002. highlightedDates = $.extend(true, [], options.highlightedDates);
  1003. $.each(_options.highlightedPeriods, function (index, value) {
  1004. var dateTest, // start date
  1005. dateEnd,
  1006. desc,
  1007. hDate,
  1008. keyDate,
  1009. exDesc,
  1010. style;
  1011. if ($.isArray(value)) {
  1012. dateTest = value[0];
  1013. dateEnd = value[1];
  1014. desc = value[2];
  1015. style = value[3];
  1016. }
  1017. else {
  1018. var splitData = $.map(value.split(','), $.trim);
  1019. dateTest = dateHelper.parseDate(splitData[0], options.formatDate);
  1020. dateEnd = dateHelper.parseDate(splitData[1], options.formatDate);
  1021. desc = splitData[2];
  1022. style = splitData[3];
  1023. }
  1024. while (dateTest <= dateEnd) {
  1025. hDate = new HighlightedDate(dateTest, desc, style);
  1026. keyDate = dateHelper.formatDate(dateTest, options.formatDate);
  1027. dateTest.setDate(dateTest.getDate() + 1);
  1028. if (highlightedDates[keyDate] !== undefined) {
  1029. exDesc = highlightedDates[keyDate].desc;
  1030. if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
  1031. highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
  1032. }
  1033. } else {
  1034. highlightedDates[keyDate] = hDate;
  1035. }
  1036. }
  1037. });
  1038. options.highlightedDates = $.extend(true, [], highlightedDates);
  1039. }
  1040. if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) {
  1041. options.disabledDates = $.extend(true, [], _options.disabledDates);
  1042. }
  1043. if (_options.disabledWeekDays && $.isArray(_options.disabledWeekDays) && _options.disabledWeekDays.length) {
  1044. options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays);
  1045. }
  1046. if ((options.open || options.opened) && (!options.inline)) {
  1047. input.trigger('open.xdsoft');
  1048. }
  1049. if (options.inline) {
  1050. triggerAfterOpen = true;
  1051. datetimepicker.addClass('xdsoft_inline');
  1052. input.after(datetimepicker).hide();
  1053. }
  1054. if (options.inverseButton) {
  1055. options.next = 'xdsoft_prev';
  1056. options.prev = 'xdsoft_next';
  1057. }
  1058. if (options.datepicker) {
  1059. datepicker.addClass('active');
  1060. } else {
  1061. datepicker.removeClass('active');
  1062. }
  1063. if (options.timepicker) {
  1064. timepicker.addClass('active');
  1065. } else {
  1066. timepicker.removeClass('active');
  1067. }
  1068. if (options.value) {
  1069. _xdsoft_datetime.setCurrentTime(options.value);
  1070. if (input && input.val) {
  1071. input.val(_xdsoft_datetime.str);
  1072. }
  1073. }
  1074. if (isNaN(options.dayOfWeekStart)) {
  1075. options.dayOfWeekStart = 0;
  1076. } else {
  1077. options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7;
  1078. }
  1079. if (!options.timepickerScrollbar) {
  1080. timeboxparent.xdsoftScroller(options, 'hide');
  1081. }
  1082. if (options.minDate && /^[\+\-](.*)$/.test(options.minDate)) {
  1083. options.minDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.minDate), options.formatDate);
  1084. }
  1085. if (options.maxDate && /^[\+\-](.*)$/.test(options.maxDate)) {
  1086. options.maxDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.maxDate), options.formatDate);
  1087. }
  1088. applyButton.toggle(options.showApplyButton);
  1089. month_picker
  1090. .find('.xdsoft_today_button')
  1091. .css('visibility', !options.todayButton ? 'hidden' : 'visible');
  1092. month_picker
  1093. .find('.' + options.prev)
  1094. .css('visibility', !options.prevButton ? 'hidden' : 'visible');
  1095. month_picker
  1096. .find('.' + options.next)
  1097. .css('visibility', !options.nextButton ? 'hidden' : 'visible');
  1098. setMask(options);
  1099. if (options.validateOnBlur) {
  1100. input
  1101. .off('blur.xdsoft')
  1102. .on('blur.xdsoft', function () {
  1103. if (options.allowBlank && (!$.trim($(this).val()).length || (typeof options.mask == "string" && $.trim($(this).val()) === options.mask.replace(/[0-9]/g, '_')))) {
  1104. $(this).val(null);
  1105. datetimepicker.data('xdsoft_datetime').empty();
  1106. } else {
  1107. var d = dateHelper.parseDate($(this).val(), options.format);
  1108. if (d) { // parseDate() may skip some invalid parts like date or time, so make it clear for user: show parsed date/time
  1109. $(this).val(dateHelper.formatDate(d, options.format));
  1110. } else {
  1111. var splittedHours = +([$(this).val()[0], $(this).val()[1]].join('')),
  1112. splittedMinutes = +([$(this).val()[2], $(this).val()[3]].join(''));
  1113. // parse the numbers as 0312 => 03:12
  1114. if (!options.datepicker && options.timepicker && splittedHours >= 0 && splittedHours < 24 && splittedMinutes >= 0 && splittedMinutes < 60) {
  1115. $(this).val([splittedHours, splittedMinutes].map(function (item) {
  1116. return item > 9 ? item : '0' + item;
  1117. }).join(':'));
  1118. } else {
  1119. $(this).val(dateHelper.formatDate(_xdsoft_datetime.now(), options.format));
  1120. }
  1121. }
  1122. datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
  1123. }
  1124. datetimepicker.trigger('changedatetime.xdsoft');
  1125. datetimepicker.trigger('close.xdsoft');
  1126. });
  1127. }
  1128. options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
  1129. datetimepicker
  1130. .trigger('xchange.xdsoft')
  1131. .trigger('afterOpen.xdsoft');
  1132. };
  1133. datetimepicker
  1134. .data('options', options)
  1135. .on('touchstart mousedown.xdsoft', function (event) {
  1136. event.stopPropagation();
  1137. event.preventDefault();
  1138. yearselect.hide();
  1139. monthselect.hide();
  1140. return false;
  1141. });
  1142. //scroll_element = timepicker.find('.xdsoft_time_box');
  1143. timeboxparent.append(timebox);
  1144. timeboxparent.xdsoftScroller(options);
  1145. datetimepicker.on('afterOpen.xdsoft', function () {
  1146. timeboxparent.xdsoftScroller(options);
  1147. });
  1148. datetimepicker
  1149. .append(datepicker)
  1150. .append(timepicker);
  1151. if (options.withoutCopyright !== true) {
  1152. datetimepicker
  1153. .append(xdsoft_copyright);
  1154. }
  1155. datepicker
  1156. .append(month_picker)
  1157. .append(calendar)
  1158. .append(applyButton);
  1159. $(options.parentID)
  1160. .append(datetimepicker);
  1161. XDSoft_datetime = function () {
  1162. var _this = this;
  1163. _this.now = function (norecursion) {
  1164. var d = new Date(),
  1165. date,
  1166. time;
  1167. if (!norecursion && options.defaultDate) {
  1168. date = _this.strToDateTime(options.defaultDate);
  1169. d.setFullYear(date.getFullYear());
  1170. d.setMonth(date.getMonth());
  1171. d.setDate(date.getDate());
  1172. }
  1173. if (options.yearOffset) {
  1174. d.setFullYear(d.getFullYear() + options.yearOffset);
  1175. }
  1176. if (!norecursion && options.defaultTime) {
  1177. time = _this.strtotime(options.defaultTime);
  1178. d.setHours(time.getHours());
  1179. d.setMinutes(time.getMinutes());
  1180. }
  1181. return d;
  1182. };
  1183. _this.isValidDate = function (d) {
  1184. if (Object.prototype.toString.call(d) !== "[object Date]") {
  1185. return false;
  1186. }
  1187. return !isNaN(d.getTime());
  1188. };
  1189. _this.setCurrentTime = function (dTime, requireValidDate) {
  1190. if (typeof dTime === 'string') {
  1191. _this.currentTime = _this.strToDateTime(dTime);
  1192. }
  1193. else if (_this.isValidDate(dTime)) {
  1194. _this.currentTime = dTime;
  1195. }
  1196. else if (!dTime && !requireValidDate && options.allowBlank) {
  1197. _this.currentTime = null;
  1198. }
  1199. else {
  1200. _this.currentTime = _this.now();
  1201. }
  1202. datetimepicker.trigger('xchange.xdsoft');
  1203. };
  1204. _this.empty = function () {
  1205. _this.currentTime = null;
  1206. };
  1207. _this.getCurrentTime = function (dTime) {
  1208. return _this.currentTime;
  1209. };
  1210. _this.nextMonth = function () {
  1211. if (_this.currentTime === undefined || _this.currentTime === null) {
  1212. _this.currentTime = _this.now();
  1213. }
  1214. var month = _this.currentTime.getMonth() + 1,
  1215. year;
  1216. if (month === 12) {
  1217. _this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1);
  1218. month = 0;
  1219. }
  1220. year = _this.currentTime.getFullYear();
  1221. _this.currentTime.setDate(
  1222. Math.min(
  1223. new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
  1224. _this.currentTime.getDate()
  1225. )
  1226. );
  1227. _this.currentTime.setMonth(month);
  1228. if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
  1229. options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
  1230. }
  1231. if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
  1232. options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
  1233. }
  1234. datetimepicker.trigger('xchange.xdsoft');
  1235. return month;
  1236. };
  1237. _this.prevMonth = function () {
  1238. if (_this.currentTime === undefined || _this.currentTime === null) {
  1239. _this.currentTime = _this.now();
  1240. }
  1241. var month = _this.currentTime.getMonth() - 1;
  1242. if (month === -1) {
  1243. _this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1);
  1244. month = 11;
  1245. }
  1246. _this.currentTime.setDate(
  1247. Math.min(
  1248. new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
  1249. _this.currentTime.getDate()
  1250. )
  1251. );
  1252. _this.currentTime.setMonth(month);
  1253. if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
  1254. options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
  1255. }
  1256. datetimepicker.trigger('xchange.xdsoft');
  1257. return month;
  1258. };
  1259. _this.getWeekOfYear = function (datetime) {
  1260. if (options.onGetWeekOfYear && $.isFunction(options.onGetWeekOfYear)) {
  1261. var week = options.onGetWeekOfYear.call(datetimepicker, datetime);
  1262. if (typeof week !== 'undefined') {
  1263. return week;
  1264. }
  1265. }
  1266. var onejan = new Date(datetime.getFullYear(), 0, 1);
  1267. //First week of the year is th one with the first Thursday according to ISO8601
  1268. if(onejan.getDay()!=4)
  1269. onejan.setMonth(0, 1 + ((4 - onejan.getDay()+ 7) % 7));
  1270. return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7);
  1271. };
  1272. _this.strToDateTime = function (sDateTime) {
  1273. var tmpDate = [], timeOffset, currentTime;
  1274. if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) {
  1275. return sDateTime;
  1276. }
  1277. tmpDate = /^(\+|\-)(.*)$/.exec(sDateTime);
  1278. if (tmpDate) {
  1279. tmpDate[2] = dateHelper.parseDate(tmpDate[2], options.formatDate);
  1280. }
  1281. if (tmpDate && tmpDate[2]) {
  1282. timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
  1283. currentTime = new Date((_this.now(true)).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset);
  1284. } else {
  1285. currentTime = sDateTime ? dateHelper.parseDate(sDateTime, options.format) : _this.now();
  1286. }
  1287. if (!_this.isValidDate(currentTime)) {
  1288. currentTime = _this.now();
  1289. }
  1290. return currentTime;
  1291. };
  1292. _this.strToDate = function (sDate) {
  1293. if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) {
  1294. return sDate;
  1295. }
  1296. var currentTime = sDate ? dateHelper.parseDate(sDate, options.formatDate) : _this.now(true);
  1297. if (!_this.isValidDate(currentTime)) {
  1298. currentTime = _this.now(true);
  1299. }
  1300. return currentTime;
  1301. };
  1302. _this.strtotime = function (sTime) {
  1303. if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) {
  1304. return sTime;
  1305. }
  1306. var currentTime = sTime ? dateHelper.parseDate(sTime, options.formatTime) : _this.now(true);
  1307. if (!_this.isValidDate(currentTime)) {
  1308. currentTime = _this.now(true);
  1309. }
  1310. return currentTime;
  1311. };
  1312. _this.str = function () {
  1313. return dateHelper.formatDate(_this.currentTime, options.format);
  1314. };
  1315. _this.currentTime = this.now();
  1316. };
  1317. _xdsoft_datetime = new XDSoft_datetime();
  1318. applyButton.on('touchend click', function (e) {//pathbrite
  1319. e.preventDefault();
  1320. datetimepicker.data('changed', true);
  1321. _xdsoft_datetime.setCurrentTime(getCurrentValue());
  1322. input.val(_xdsoft_datetime.str());
  1323. datetimepicker.trigger('close.xdsoft');
  1324. });
  1325. month_picker
  1326. .find('.xdsoft_today_button')
  1327. .on('touchend mousedown.xdsoft', function () {
  1328. datetimepicker.data('changed', true);
  1329. _xdsoft_datetime.setCurrentTime(0, true);
  1330. datetimepicker.trigger('afterOpen.xdsoft');
  1331. }).on('dblclick.xdsoft', function () {
  1332. var currentDate = _xdsoft_datetime.getCurrentTime(), minDate, maxDate;
  1333. currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
  1334. minDate = _xdsoft_datetime.strToDate(options.minDate);
  1335. minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
  1336. if (currentDate < minDate) {
  1337. return;
  1338. }
  1339. maxDate = _xdsoft_datetime.strToDate(options.maxDate);
  1340. maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate());
  1341. if (currentDate > maxDate) {
  1342. return;
  1343. }
  1344. input.val(_xdsoft_datetime.str());
  1345. input.trigger('change');
  1346. datetimepicker.trigger('close.xdsoft');
  1347. });
  1348. month_picker
  1349. .find('.xdsoft_prev,.xdsoft_next')
  1350. .on('touchend mousedown.xdsoft', function () {
  1351. var $this = $(this),
  1352. timer = 0,
  1353. stop = false;
  1354. (function arguments_callee1(v) {
  1355. if ($this.hasClass(options.next)) {
  1356. _xdsoft_datetime.nextMonth();
  1357. } else if ($this.hasClass(options.prev)) {
  1358. _xdsoft_datetime.prevMonth();
  1359. }
  1360. if (options.monthChangeSpinner) {
  1361. if (!stop) {
  1362. timer = setTimeout(arguments_callee1, v || 100);
  1363. }
  1364. }
  1365. }(500));
  1366. $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft', function arguments_callee2() {
  1367. clearTimeout(timer);
  1368. stop = true;
  1369. $([options.ownerDocument.body, options.contentWindow]).off('touchend mouseup.xdsoft', arguments_callee2);
  1370. });
  1371. });
  1372. timepicker
  1373. .find('.xdsoft_prev,.xdsoft_next')
  1374. .on('touchend mousedown.xdsoft', function () {
  1375. var $this = $(this),
  1376. timer = 0,
  1377. stop = false,
  1378. period = 110;
  1379. (function arguments_callee4(v) {
  1380. var pheight = timeboxparent[0].clientHeight,
  1381. height = timebox[0].offsetHeight,
  1382. top = Math.abs(parseInt(timebox.css('marginTop'), 10));
  1383. if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) {
  1384. timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px');
  1385. } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
  1386. timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
  1387. }
  1388. /**
  1389. * Fixed bug:
  1390. * When using css3 transition, it will cause a bug that you cannot scroll the timepicker list.
  1391. * The reason is that the transition-duration time, if you set it to 0, all things fine, otherwise, this
  1392. * would cause a bug when you use jquery.css method.
  1393. * Let's say: * { transition: all .5s ease; }
  1394. * jquery timebox.css('marginTop') will return the original value which is before you clicking the next/prev button,
  1395. * meanwhile the timebox[0].style.marginTop will return the right value which is after you clicking the
  1396. * next/prev button.
  1397. *
  1398. * What we should do:
  1399. * Replace timebox.css('marginTop') with timebox[0].style.marginTop.
  1400. */
  1401. timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox[0].style.marginTop, 10) / (height - pheight))]);
  1402. period = (period > 10) ? 10 : period - 10;
  1403. if (!stop) {
  1404. timer = setTimeout(arguments_callee4, v || period);
  1405. }
  1406. }(500));
  1407. $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft', function arguments_callee5() {
  1408. clearTimeout(timer);
  1409. stop = true;
  1410. $([options.ownerDocument.body, options.contentWindow])
  1411. .off('touchend mouseup.xdsoft', arguments_callee5);
  1412. });
  1413. });
  1414. xchangeTimer = 0;
  1415. // base handler - generating a calendar and timepicker
  1416. datetimepicker
  1417. .on('xchange.xdsoft', function (event) {
  1418. clearTimeout(xchangeTimer);
  1419. xchangeTimer = setTimeout(function () {
  1420. if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
  1421. //In case blanks are allowed, delay construction until we have a valid date
  1422. if (options.allowBlank)
  1423. return;
  1424. _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
  1425. }
  1426. var table = '',
  1427. start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0),
  1428. i = 0,
  1429. j,
  1430. today = _xdsoft_datetime.now(),
  1431. maxDate = false,
  1432. minDate = false,
  1433. hDate,
  1434. day,
  1435. d,
  1436. y,
  1437. m,
  1438. w,
  1439. classes = [],
  1440. customDateSettings,
  1441. newRow = true,
  1442. time = '',
  1443. h = '',
  1444. line_time,
  1445. description;
  1446. while (start.getDay() !== options.dayOfWeekStart) {
  1447. start.setDate(start.getDate() - 1);
  1448. }
  1449. table += '<table><thead><tr>';
  1450. if (options.weeks) {
  1451. table += '<th></th>';
  1452. }
  1453. for (j = 0; j < 7; j += 1) {
  1454. table += '<th>' + options.i18n[globalLocale].dayOfWeekShort[(j + options.dayOfWeekStart) % 7] + '</th>';
  1455. }
  1456. table += '</tr></thead>';
  1457. table += '<tbody>';
  1458. if (options.maxDate !== false) {
  1459. maxDate = _xdsoft_datetime.strToDate(options.maxDate);
  1460. maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
  1461. }
  1462. if (options.minDate !== false) {
  1463. minDate = _xdsoft_datetime.strToDate(options.minDate);
  1464. minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
  1465. }
  1466. while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
  1467. classes = [];
  1468. i += 1;
  1469. day = start.getDay();
  1470. d = start.getDate();
  1471. y = start.getFullYear();
  1472. m = start.getMonth();
  1473. w = _xdsoft_datetime.getWeekOfYear(start);
  1474. description = '';
  1475. classes.push('xdsoft_date');
  1476. if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) {
  1477. customDateSettings = options.beforeShowDay.call(datetimepicker, start);
  1478. } else {
  1479. customDateSettings = null;
  1480. }
  1481. if(options.allowDateRe && Object.prototype.toString.call(options.allowDateRe) === "[object RegExp]"){
  1482. if(!options.allowDateRe.test(dateHelper.formatDate(start, options.formatDate))){
  1483. classes.push('xdsoft_disabled');
  1484. }
  1485. } else if(options.allowDates && options.allowDates.length>0){
  1486. if(options.allowDates.indexOf(dateHelper.formatDate(start, options.formatDate)) === -1){
  1487. classes.push('xdsoft_disabled');
  1488. }
  1489. } else if ((maxDate !== false && start > maxDate) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) {
  1490. classes.push('xdsoft_disabled');
  1491. } else if (options.disabledDates.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
  1492. classes.push('xdsoft_disabled');
  1493. } else if (options.disabledWeekDays.indexOf(day) !== -1) {
  1494. classes.push('xdsoft_disabled');
  1495. }else if (input.is('[readonly]')) {
  1496. classes.push('xdsoft_disabled');
  1497. }
  1498. if (customDateSettings && customDateSettings[1] !== "") {
  1499. classes.push(customDateSettings[1]);
  1500. }
  1501. if (_xdsoft_datetime.currentTime.getMonth() !== m) {
  1502. classes.push('xdsoft_other_month');
  1503. }
  1504. if ((options.defaultSelect || datetimepicker.data('changed')) && dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
  1505. classes.push('xdsoft_current');
  1506. }
  1507. if (dateHelper.formatDate(today, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
  1508. classes.push('xdsoft_today');
  1509. }
  1510. if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
  1511. classes.push('xdsoft_weekend');
  1512. }
  1513. if (options.highlightedDates[dateHelper.formatDate(start, options.formatDate)] !== undefined) {
  1514. hDate = options.highlightedDates[dateHelper.formatDate(start, options.formatDate)];
  1515. classes.push(hDate.style === undefined ? 'xdsoft_highlighted_default' : hDate.style);
  1516. description = hDate.desc === undefined ? '' : hDate.desc;
  1517. }
  1518. if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) {
  1519. classes.push(options.beforeShowDay(start));
  1520. }
  1521. if (newRow) {
  1522. table += '<tr>';
  1523. newRow = false;
  1524. if (options.weeks) {
  1525. table += '<th>' + w + '</th>';
  1526. }
  1527. }
  1528. table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '" title="' + description + '">' +
  1529. '<div>' + d + '</div>' +
  1530. '</td>';
  1531. if (start.getDay() === options.dayOfWeekStartPrev) {
  1532. table += '</tr>';
  1533. newRow = true;
  1534. }
  1535. start.setDate(d + 1);
  1536. }
  1537. table += '</tbody></table>';
  1538. calendar.html(table);
  1539. month_picker.find('.xdsoft_label span').eq(0).text(options.i18n[globalLocale].months[_xdsoft_datetime.currentTime.getMonth()]);
  1540. month_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear());
  1541. // generate timebox
  1542. time = '';
  1543. h = '';
  1544. m = '';
  1545. line_time = function line_time(h, m) {
  1546. var now = _xdsoft_datetime.now(), optionDateTime, current_time,
  1547. isALlowTimesInit = options.allowTimes && $.isArray(options.allowTimes) && options.allowTimes.length;
  1548. now.setHours(h);
  1549. h = parseInt(now.getHours(), 10);
  1550. now.setMinutes(m);
  1551. m = parseInt(now.getMinutes(), 10);
  1552. optionDateTime = new Date(_xdsoft_datetime.currentTime);
  1553. optionDateTime.setHours(h);
  1554. optionDateTime.setMinutes(m);
  1555. classes = [];
  1556. if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || (options.maxTime !== false && _xdsoft_datetime.strtotime(options.maxTime).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime(options.minTime).getTime() > now.getTime())) {
  1557. classes.push('xdsoft_disabled');
  1558. } else if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || ((options.disabledMinTime !== false && now.getTime() > _xdsoft_datetime.strtotime(options.disabledMinTime).getTime()) && (options.disabledMaxTime !== false && now.getTime() < _xdsoft_datetime.strtotime(options.disabledMaxTime).getTime()))) {
  1559. classes.push('xdsoft_disabled');
  1560. } else if (input.is('[readonly]')) {
  1561. classes.push('xdsoft_disabled');
  1562. }
  1563. current_time = new Date(_xdsoft_datetime.currentTime);
  1564. current_time.setHours(parseInt(_xdsoft_datetime.currentTime.getHours(), 10));
  1565. if (!isALlowTimesInit) {
  1566. current_time.setMinutes(Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step);
  1567. }
  1568. if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && current_time.getHours() === parseInt(h, 10) && ((!isALlowTimesInit && options.step > 59) || current_time.getMinutes() === parseInt(m, 10))) {
  1569. if (options.defaultSelect || datetimepicker.data('changed')) {
  1570. classes.push('xdsoft_current');
  1571. } else if (options.initTime) {
  1572. classes.push('xdsoft_init_time');
  1573. }
  1574. }
  1575. if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) {
  1576. classes.push('xdsoft_today');
  1577. }
  1578. time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + dateHelper.formatDate(now, options.formatTime) + '</div>';
  1579. };
  1580. if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) {
  1581. for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
  1582. for (j = 0; j < 60; j += options.step) {
  1583. h = (i < 10 ? '0' : '') + i;
  1584. m = (j < 10 ? '0' : '') + j;
  1585. line_time(h, m);
  1586. }
  1587. }
  1588. } else {
  1589. for (i = 0; i < options.allowTimes.length; i += 1) {
  1590. h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
  1591. m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
  1592. line_time(h, m);
  1593. }
  1594. }
  1595. timebox.html(time);
  1596. opt = '';
  1597. i = 0;
  1598. for (i = parseInt(options.yearStart, 10) + options.yearOffset; i <= parseInt(options.yearEnd, 10) + options.yearOffset; i += 1) {
  1599. opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + i + '</div>';
  1600. }
  1601. yearselect.children().eq(0)
  1602. .html(opt);
  1603. for (i = parseInt(options.monthStart, 10), opt = ''; i <= parseInt(options.monthEnd, 10); i += 1) {
  1604. opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[globalLocale].months[i] + '</div>';
  1605. }
  1606. monthselect.children().eq(0).html(opt);
  1607. $(datetimepicker)
  1608. .trigger('generate.xdsoft');
  1609. }, 10);
  1610. event.stopPropagation();
  1611. })
  1612. .on('afterOpen.xdsoft', function () {
  1613. if (options.timepicker) {
  1614. var classType, pheight, height, top;
  1615. if (timebox.find('.xdsoft_current').length) {
  1616. classType = '.xdsoft_current';
  1617. } else if (timebox.find('.xdsoft_init_time').length) {
  1618. classType = '.xdsoft_init_time';
  1619. }
  1620. if (classType) {
  1621. pheight = timeboxparent[0].clientHeight;
  1622. height = timebox[0].offsetHeight;
  1623. top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1;
  1624. if ((height - pheight) < top) {
  1625. top = height - pheight;
  1626. }
  1627. timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]);
  1628. } else {
  1629. timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]);
  1630. }
  1631. }
  1632. });
  1633. timerclick = 0;
  1634. calendar
  1635. .on('touchend click.xdsoft', 'td', function (xdevent) {
  1636. xdevent.stopPropagation(); // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
  1637. timerclick += 1;
  1638. var $this = $(this),
  1639. currentTime = _xdsoft_datetime.currentTime;
  1640. if (currentTime === undefined || currentTime === null) {
  1641. _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
  1642. currentTime = _xdsoft_datetime.currentTime;
  1643. }
  1644. if ($this.hasClass('xdsoft_disabled')) {
  1645. return false;
  1646. }
  1647. currentTime.setDate(1);
  1648. currentTime.setFullYear($this.data('year'));
  1649. currentTime.setMonth($this.data('month'));
  1650. currentTime.setDate($this.data('date'));
  1651. datetimepicker.trigger('select.xdsoft', [currentTime]);
  1652. input.val(_xdsoft_datetime.str());
  1653. if (options.onSelectDate && $.isFunction(options.onSelectDate)) {
  1654. options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
  1655. }
  1656. datetimepicker.data('changed', true);
  1657. datetimepicker.trigger('xchange.xdsoft');
  1658. datetimepicker.trigger('changedatetime.xdsoft');
  1659. if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === false && !options.timepicker))) && !options.inline) {
  1660. datetimepicker.trigger('close.xdsoft');
  1661. }
  1662. setTimeout(function () {
  1663. timerclick = 0;
  1664. }, 200);
  1665. });
  1666. timebox
  1667. .on('touchend click.xdsoft', 'div', function (xdevent) {
  1668. xdevent.stopPropagation();
  1669. var $this = $(this),
  1670. currentTime = _xdsoft_datetime.currentTime;
  1671. if (currentTime === undefined || currentTime === null) {
  1672. _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
  1673. currentTime = _xdsoft_datetime.currentTime;
  1674. }
  1675. if ($this.hasClass('xdsoft_disabled')) {
  1676. return false;
  1677. }
  1678. currentTime.setHours($this.data('hour'));
  1679. currentTime.setMinutes($this.data('minute'));
  1680. datetimepicker.trigger('select.xdsoft', [currentTime]);
  1681. datetimepicker.data('input').val(_xdsoft_datetime.str());
  1682. if (options.onSelectTime && $.isFunction(options.onSelectTime)) {
  1683. options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
  1684. }
  1685. datetimepicker.data('changed', true);
  1686. datetimepicker.trigger('xchange.xdsoft');
  1687. datetimepicker.trigger('changedatetime.xdsoft');
  1688. if (options.inline !== true && options.closeOnTimeSelect === true) {
  1689. datetimepicker.trigger('close.xdsoft');
  1690. }
  1691. });
  1692. datepicker
  1693. .on('mousewheel.xdsoft', function (event) {
  1694. if (!options.scrollMonth) {
  1695. return true;
  1696. }
  1697. if (event.deltaY < 0) {
  1698. _xdsoft_datetime.nextMonth();
  1699. } else {
  1700. _xdsoft_datetime.prevMonth();
  1701. }
  1702. return false;
  1703. });
  1704. input
  1705. .on('mousewheel.xdsoft', function (event) {
  1706. if (!options.scrollInput) {
  1707. return true;
  1708. }
  1709. if (!options.datepicker && options.timepicker) {
  1710. current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0;
  1711. if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
  1712. current_time_index += event.deltaY;
  1713. }
  1714. if (timebox.children().eq(current_time_index).length) {
  1715. timebox.children().eq(current_time_index).trigger('mousedown');
  1716. }
  1717. return false;
  1718. }
  1719. if (options.datepicker && !options.timepicker) {
  1720. datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]);
  1721. if (input.val) {
  1722. input.val(_xdsoft_datetime.str());
  1723. }
  1724. datetimepicker.trigger('changedatetime.xdsoft');
  1725. return false;
  1726. }
  1727. });
  1728. datetimepicker
  1729. .on('changedatetime.xdsoft', function (event) {
  1730. if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) {
  1731. var $input = datetimepicker.data('input');
  1732. options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event);
  1733. delete options.value;
  1734. $input.trigger('change');
  1735. }
  1736. })
  1737. .on('generate.xdsoft', function () {
  1738. if (options.onGenerate && $.isFunction(options.onGenerate)) {
  1739. options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
  1740. }
  1741. if (triggerAfterOpen) {
  1742. datetimepicker.trigger('afterOpen.xdsoft');
  1743. triggerAfterOpen = false;
  1744. }
  1745. })
  1746. .on('click.xdsoft', function (xdevent) {
  1747. xdevent.stopPropagation();
  1748. });
  1749. current_time_index = 0;
  1750. /**
  1751. * Runs the callback for each of the specified node's ancestors.
  1752. *
  1753. * Return FALSE from the callback to stop ascending.
  1754. *
  1755. * @param {DOMNode} node
  1756. * @param {Function} callback
  1757. * @returns {undefined}
  1758. */
  1759. forEachAncestorOf = function (node, callback) {
  1760. do {
  1761. node = node.parentNode;
  1762. if (callback(node) === false) {
  1763. break;
  1764. }
  1765. } while (node.nodeName !== 'HTML');
  1766. };
  1767. /**
  1768. * Sets the position of the picker.
  1769. *
  1770. * @returns {undefined}
  1771. */
  1772. setPos = function () {
  1773. var dateInputOffset,
  1774. dateInputElem,
  1775. verticalPosition,
  1776. left,
  1777. position,
  1778. datetimepickerElem,
  1779. dateInputHasFixedAncestor,
  1780. $dateInput,
  1781. windowWidth,
  1782. verticalAnchorEdge,
  1783. datetimepickerCss,
  1784. windowHeight,
  1785. windowScrollTop;
  1786. $dateInput = datetimepicker.data('input');
  1787. dateInputOffset = $dateInput.offset();
  1788. dateInputElem = $dateInput[0];
  1789. verticalAnchorEdge = 'top';
  1790. verticalPosition = (dateInputOffset.top + dateInputElem.offsetHeight) - 1;
  1791. left = dateInputOffset.left;
  1792. position = "absolute";
  1793. windowWidth = $(options.contentWindow).width();
  1794. windowHeight = $(options.contentWindow).height();
  1795. windowScrollTop = $(options.contentWindow).scrollTop();
  1796. if ((options.ownerDocument.documentElement.clientWidth - dateInputOffset.left) < datepicker.parent().outerWidth(true)) {
  1797. var diff = datepicker.parent().outerWidth(true) - dateInputElem.offsetWidth;
  1798. left = left - diff;
  1799. }
  1800. if ($dateInput.parent().css('direction') === 'rtl') {
  1801. left -= (datetimepicker.outerWidth() - $dateInput.outerWidth());
  1802. }
  1803. if (options.fixed) {
  1804. verticalPosition -= windowScrollTop;
  1805. left -= $(options.contentWindow).scrollLeft();
  1806. position = "fixed";
  1807. } else {
  1808. dateInputHasFixedAncestor = false;
  1809. forEachAncestorOf(dateInputElem, function (ancestorNode) {
  1810. if (options.contentWindow.getComputedStyle(ancestorNode).getPropertyValue('position') === 'fixed') {
  1811. dateInputHasFixedAncestor = true;
  1812. return false;
  1813. }
  1814. });
  1815. if (dateInputHasFixedAncestor) {
  1816. position = 'fixed';
  1817. //If the picker won't fit entirely within the viewport then display it above the date input.
  1818. if (verticalPosition + datetimepicker.outerHeight() > windowHeight + windowScrollTop) {
  1819. verticalAnchorEdge = 'bottom';
  1820. verticalPosition = (windowHeight + windowScrollTop) - dateInputOffset.top;
  1821. } else {
  1822. verticalPosition -= windowScrollTop;
  1823. }
  1824. } else {
  1825. if (verticalPosition + dateInputElem.offsetHeight > windowHeight + windowScrollTop) {
  1826. verticalPosition = dateInputOffset.top - dateInputElem.offsetHeight + 1;
  1827. }
  1828. }
  1829. if (verticalPosition < 0) {
  1830. verticalPosition = 0;
  1831. }
  1832. if (left + dateInputElem.offsetWidth > windowWidth) {
  1833. left = windowWidth - dateInputElem.offsetWidth;
  1834. }
  1835. }
  1836. datetimepickerElem = datetimepicker[0];
  1837. forEachAncestorOf(datetimepickerElem, function (ancestorNode) {
  1838. var ancestorNodePosition;
  1839. ancestorNodePosition = options.contentWindow.getComputedStyle(ancestorNode).getPropertyValue('position');
  1840. if (ancestorNodePosition === 'relative' && windowWidth >= ancestorNode.offsetWidth) {
  1841. left = left - ((windowWidth - ancestorNode.offsetWidth) / 2);
  1842. return false;
  1843. }
  1844. });
  1845. datetimepickerCss = {
  1846. position: position,
  1847. left: left,
  1848. top: '', //Initialize to prevent previous values interfering with new ones.
  1849. bottom: '' //Initialize to prevent previous values interfering with new ones.
  1850. };
  1851. datetimepickerCss[verticalAnchorEdge] = verticalPosition;
  1852. datetimepicker.css(datetimepickerCss);
  1853. };
  1854. datetimepicker
  1855. .on('open.xdsoft', function (event) {
  1856. var onShow = true;
  1857. if (options.onShow && $.isFunction(options.onShow)) {
  1858. onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
  1859. }
  1860. if (onShow !== false) {
  1861. datetimepicker.show();
  1862. setPos();
  1863. $(options.contentWindow)
  1864. .off('resize.xdsoft', setPos)
  1865. .on('resize.xdsoft', setPos);
  1866. if (options.closeOnWithoutClick) {
  1867. $([options.ownerDocument.body, options.contentWindow]).on('touchstart mousedown.xdsoft', function arguments_callee6() {
  1868. datetimepicker.trigger('close.xdsoft');
  1869. $([options.ownerDocument.body, options.contentWindow]).off('touchstart mousedown.xdsoft', arguments_callee6);
  1870. });
  1871. }
  1872. }
  1873. })
  1874. .on('close.xdsoft', function (event) {
  1875. var onClose = true;
  1876. month_picker
  1877. .find('.xdsoft_month,.xdsoft_year')
  1878. .find('.xdsoft_select')
  1879. .hide();
  1880. if (options.onClose && $.isFunction(options.onClose)) {
  1881. onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
  1882. }
  1883. if (onClose !== false && !options.opened && !options.inline) {
  1884. datetimepicker.hide();
  1885. }
  1886. event.stopPropagation();
  1887. })
  1888. .on('toggle.xdsoft', function () {
  1889. if (datetimepicker.is(':visible')) {
  1890. datetimepicker.trigger('close.xdsoft');
  1891. } else {
  1892. datetimepicker.trigger('open.xdsoft');
  1893. }
  1894. })
  1895. .data('input', input);
  1896. timer = 0;
  1897. datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
  1898. datetimepicker.setOptions(options);
  1899. function getCurrentValue() {
  1900. var ct = false, time;
  1901. if (options.startDate) {
  1902. ct = _xdsoft_datetime.strToDate(options.startDate);
  1903. } else {
  1904. ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
  1905. if (ct) {
  1906. ct = _xdsoft_datetime.strToDateTime(ct);
  1907. } else if (options.defaultDate) {
  1908. ct = _xdsoft_datetime.strToDateTime(options.defaultDate);
  1909. if (options.defaultTime) {
  1910. time = _xdsoft_datetime.strtotime(options.defaultTime);
  1911. ct.setHours(time.getHours());
  1912. ct.setMinutes(time.getMinutes());
  1913. }
  1914. }
  1915. }
  1916. if (ct && _xdsoft_datetime.isValidDate(ct)) {
  1917. datetimepicker.data('changed', true);
  1918. } else {
  1919. ct = '';
  1920. }
  1921. return ct || 0;
  1922. }
  1923. function setMask(options) {
  1924. var isValidValue = function (mask, value) {
  1925. var reg = mask
  1926. .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
  1927. .replace(/_/g, '{digit+}')
  1928. .replace(/([0-9]{1})/g, '{digit$1}')
  1929. .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
  1930. .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
  1931. return (new RegExp(reg)).test(value);
  1932. },
  1933. getCaretPos = function (input) {
  1934. try {
  1935. if (options.ownerDocument.selection && options.ownerDocument.selection.createRange) {
  1936. var range = options.ownerDocument.selection.createRange();
  1937. return range.getBookmark().charCodeAt(2) - 2;
  1938. }
  1939. if (input.setSelectionRange) {
  1940. return input.selectionStart;
  1941. }
  1942. } catch (e) {
  1943. return 0;
  1944. }
  1945. },
  1946. setCaretPos = function (node, pos) {
  1947. node = (typeof node === "string" || node instanceof String) ? options.ownerDocument.getElementById(node) : node;
  1948. if (!node) {
  1949. return false;
  1950. }
  1951. if (node.createTextRange) {
  1952. var textRange = node.createTextRange();
  1953. textRange.collapse(true);
  1954. textRange.moveEnd('character', pos);
  1955. textRange.moveStart('character', pos);
  1956. textRange.select();
  1957. return true;
  1958. }
  1959. if (node.setSelectionRange) {
  1960. node.setSelectionRange(pos, pos);
  1961. return true;
  1962. }
  1963. return false;
  1964. };
  1965. if(options.mask) {
  1966. input.off('keydown.xdsoft');
  1967. }
  1968. if (options.mask === true) {
  1969. if (typeof moment != 'undefined') {
  1970. options.mask = options.format
  1971. .replace(/Y{4}/g, '9999')
  1972. .replace(/Y{2}/g, '99')
  1973. .replace(/M{2}/g, '19')
  1974. .replace(/D{2}/g, '39')
  1975. .replace(/H{2}/g, '29')
  1976. .replace(/m{2}/g, '59')
  1977. .replace(/s{2}/g, '59');
  1978. } else {
  1979. options.mask = options.format
  1980. .replace(/Y/g, '9999')
  1981. .replace(/F/g, '9999')
  1982. .replace(/m/g, '19')
  1983. .replace(/d/g, '39')
  1984. .replace(/H/g, '29')
  1985. .replace(/i/g, '59')
  1986. .replace(/s/g, '59');
  1987. }
  1988. }
  1989. if ($.type(options.mask) === 'string') {
  1990. if (!isValidValue(options.mask, input.val())) {
  1991. input.val(options.mask.replace(/[0-9]/g, '_'));
  1992. setCaretPos(input[0], 0);
  1993. }
  1994. input.on('keydown.xdsoft', function (event) {
  1995. var val = this.value,
  1996. key = event.which,
  1997. pos,
  1998. digit;
  1999. if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) {
  2000. pos = getCaretPos(this);
  2001. digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_';
  2002. if ((key === BACKSPACE || key === DEL) && pos) {
  2003. pos -= 1;
  2004. digit = '_';
  2005. }
  2006. while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
  2007. pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
  2008. }
  2009. val = val.substr(0, pos) + digit + val.substr(pos + 1);
  2010. if ($.trim(val) === '') {
  2011. val = options.mask.replace(/[0-9]/g, '_');
  2012. } else {
  2013. if (pos === options.mask.length) {
  2014. event.preventDefault();
  2015. return false;
  2016. }
  2017. }
  2018. pos += (key === BACKSPACE || key === DEL) ? 0 : 1;
  2019. while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
  2020. pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
  2021. }
  2022. if (isValidValue(options.mask, val)) {
  2023. this.value = val;
  2024. setCaretPos(this, pos);
  2025. } else if ($.trim(val) === '') {
  2026. this.value = options.mask.replace(/[0-9]/g, '_');
  2027. } else {
  2028. input.trigger('error_input.xdsoft');
  2029. }
  2030. } else {
  2031. if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
  2032. return true;
  2033. }
  2034. }
  2035. event.preventDefault();
  2036. return false;
  2037. });
  2038. }
  2039. }
  2040. _xdsoft_datetime.setCurrentTime(getCurrentValue());
  2041. input
  2042. .data('xdsoft_datetimepicker', datetimepicker)
  2043. .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function () {
  2044. if (input.is(':disabled') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
  2045. return;
  2046. }
  2047. clearTimeout(timer);
  2048. timer = setTimeout(function () {
  2049. if (input.is(':disabled')) {
  2050. return;
  2051. }
  2052. triggerAfterOpen = true;
  2053. _xdsoft_datetime.setCurrentTime(getCurrentValue(), true);
  2054. if(options.mask) {
  2055. setMask(options);
  2056. }
  2057. datetimepicker.trigger('open.xdsoft');
  2058. }, 100);
  2059. })
  2060. .on('keydown.xdsoft', function (event) {
  2061. var elementSelector,
  2062. key = event.which;
  2063. if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
  2064. elementSelector = $("input:visible,textarea:visible,button:visible,a:visible");
  2065. datetimepicker.trigger('close.xdsoft');
  2066. elementSelector.eq(elementSelector.index(this) + 1).focus();
  2067. return false;
  2068. }
  2069. if ([TAB].indexOf(key) !== -1) {
  2070. datetimepicker.trigger('close.xdsoft');
  2071. return true;
  2072. }
  2073. })
  2074. .on('blur.xdsoft', function () {
  2075. datetimepicker.trigger('close.xdsoft');
  2076. });
  2077. };
  2078. destroyDateTimePicker = function (input) {
  2079. var datetimepicker = input.data('xdsoft_datetimepicker');
  2080. if (datetimepicker) {
  2081. datetimepicker.data('xdsoft_datetime', null);
  2082. datetimepicker.remove();
  2083. input
  2084. .data('xdsoft_datetimepicker', null)
  2085. .off('.xdsoft');
  2086. $(options.contentWindow).off('resize.xdsoft');
  2087. $([options.contentWindow, options.ownerDocument.body]).off('mousedown.xdsoft touchstart');
  2088. if (input.unmousewheel) {
  2089. input.unmousewheel();
  2090. }
  2091. }
  2092. };
  2093. $(options.ownerDocument)
  2094. .off('keydown.xdsoftctrl keyup.xdsoftctrl')
  2095. .on('keydown.xdsoftctrl', function (e) {
  2096. if (e.keyCode === CTRLKEY) {
  2097. ctrlDown = true;
  2098. }
  2099. })
  2100. .on('keyup.xdsoftctrl', function (e) {
  2101. if (e.keyCode === CTRLKEY) {
  2102. ctrlDown = false;
  2103. }
  2104. });
  2105. this.each(function () {
  2106. var datetimepicker = $(this).data('xdsoft_datetimepicker'), $input;
  2107. if (datetimepicker) {
  2108. if ($.type(opt) === 'string') {
  2109. switch (opt) {
  2110. case 'show':
  2111. $(this).select().focus();
  2112. datetimepicker.trigger('open.xdsoft');
  2113. break;
  2114. case 'hide':
  2115. datetimepicker.trigger('close.xdsoft');
  2116. break;
  2117. case 'toggle':
  2118. datetimepicker.trigger('toggle.xdsoft');
  2119. break;
  2120. case 'destroy':
  2121. destroyDateTimePicker($(this));
  2122. break;
  2123. case 'reset':
  2124. this.value = this.defaultValue;
  2125. if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(dateHelper.parseDate(this.value, options.format))) {
  2126. datetimepicker.data('changed', false);
  2127. }
  2128. datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
  2129. break;
  2130. case 'validate':
  2131. $input = datetimepicker.data('input');
  2132. $input.trigger('blur.xdsoft');
  2133. break;
  2134. default:
  2135. if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) {
  2136. result = datetimepicker[opt](opt2);
  2137. }
  2138. }
  2139. } else {
  2140. datetimepicker
  2141. .setOptions(opt);
  2142. }
  2143. return 0;
  2144. }
  2145. if ($.type(opt) !== 'string') {
  2146. if (!options.lazyInit || options.open || options.inline) {
  2147. createDateTimePicker($(this));
  2148. } else {
  2149. lazyInit($(this));
  2150. }
  2151. }
  2152. });
  2153. return result;
  2154. };
  2155. $.fn.datetimepicker.defaults = default_options;
  2156. function HighlightedDate(date, desc, style) {
  2157. "use strict";
  2158. this.date = date;
  2159. this.desc = desc;
  2160. this.style = style;
  2161. }
  2162. }));