You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3019 lines
91 KiB

  1. //No.1 时间选择器
  2. $(document).ready(function(){
  3. var hour_temp = "";
  4. var minute_temp = "";
  5. for(var i=0;i<24;i++){
  6. if(i<10){
  7. if(i==0){
  8. hour_temp += '<div class="select_hour select_option">0'+i+'</div>'
  9. }else{
  10. hour_temp += '<div class="select_hour">0'+i+'</div>'
  11. }
  12. }else{
  13. hour_temp += '<div class="select_hour">'+i+'</div>'
  14. }
  15. }
  16. for(var i=0;i<60;i++){
  17. if(i<10){
  18. if(i==0){
  19. minute_temp += '<div class="select_minute select_option">0'+i+'</div>'
  20. }else{
  21. minute_temp += '<div class="select_minute">0'+i+'</div>'
  22. }
  23. }else{
  24. minute_temp += '<div class="select_minute">'+i+'</div>'
  25. }
  26. }
  27. $(".select_hour_box").html(hour_temp);
  28. $(".select_minute_box").html(minute_temp);
  29. $(".select_hour").on("click",function(){
  30. var time_id = $(this).closest(".timepicker_box").attr("id");
  31. var parent_height = $("#"+time_id).find(".timepicker_select").offset().top;
  32. var this_height = $(this).offset().top;
  33. var scroll_height = $("#"+time_id).find(".select_hour_box").scrollTop();
  34. var move_height = this_height - parent_height + scroll_height;
  35. $("#"+time_id).find(".select_hour_box").animate({scrollTop:move_height},200);
  36. $("#"+time_id).find(".select_hour_box").children().removeClass("select_option");
  37. $(this).addClass("select_option");
  38. var times = $("#"+time_id).find(".select_hour_box .select_option").text() + ':' + $("#"+time_id).find(".select_minute_box .select_option").text();
  39. $("#"+time_id).find(".timepicker input").val(times);
  40. });
  41. $(".select_minute").on("click",function(){
  42. var time_id = $(this).closest(".timepicker_box").attr("id");
  43. var parent_height = $("#"+time_id).find(".timepicker_select").offset().top;
  44. var this_height = $(this).offset().top;
  45. var scroll_height = $("#"+time_id).find(".select_minute_box").scrollTop();
  46. var move_height = this_height - parent_height + scroll_height;
  47. $("#"+time_id).find(".select_minute_box").animate({scrollTop:move_height},200);
  48. $("#"+time_id).find(".select_minute_box").children().removeClass("select_option");
  49. $(this).addClass("select_option");
  50. var times = $("#"+time_id).find(".select_hour_box .select_option").text() + ':' + $("#"+time_id).find(".select_minute_box .select_option").text();
  51. $("#"+time_id).find(".timepicker input").val(times);
  52. });
  53. $(".timepicker_box").on("click",function(e){
  54. var time_id = this.id;
  55. $(".timepicker_select").not("#"+time_id+" .timepicker_select").animate({
  56. height:'hide'
  57. },200);
  58. $("#"+this.id).find(".timepicker_select").animate({
  59. height:'show'
  60. },200);
  61. e.stopPropagation();
  62. });
  63. });
  64. $(document).on("click",function(e){
  65. var time_id = this.id;
  66. $(".timepicker_select").animate({
  67. height:'hide'
  68. },200);
  69. e.stopPropagation();
  70. });
  71. //。。。。。。。。。。。。。。。。。。。。。。。。。。。。//
  72. //No.2 分页
  73. (function($){
  74. var ms = {
  75. init:function(obj,args){
  76. return (function(){
  77. ms.fillHtml(obj,args);
  78. ms.bindEvent(obj,args);
  79. })();
  80. },
  81. //填充html
  82. fillHtml:function(obj,args){
  83. return (function(){
  84. obj.empty();
  85. //上一页
  86. if(args.current > 1){
  87. obj.append('<a href="javascript:;" class="prevPage icon-left"></a>');
  88. }else{
  89. obj.remove('.prevPage');
  90. obj.append('<span class="disabled icon-left"></span>');
  91. }
  92. //中间页码
  93. if(args.current != 1 && args.current >= 4 && args.pageCount != 4){
  94. obj.append('<a href="javascript:;" class="tcdNumber">'+1+'</a>');
  95. }
  96. if(args.current-2 > 2 && args.current <= args.pageCount && args.pageCount > 5){
  97. obj.append('<span>...</span>');
  98. }
  99. var start = args.current -2,end = args.current+2;
  100. if((start > 1 && args.current < 4)||args.current == 1){
  101. end++;
  102. }
  103. if(args.current > args.pageCount-4 && args.current >= args.pageCount){
  104. start--;
  105. }
  106. for (;start <= end; start++) {
  107. if(start <= args.pageCount && start >= 1){
  108. if(start != args.current){
  109. obj.append('<a href="javascript:;" class="tcdNumber">'+ start +'</a>');
  110. }else{
  111. obj.append('<span class="current">'+ start +'</span>');
  112. }
  113. }
  114. }
  115. if(args.current + 2 < args.pageCount - 1 && args.current >= 1 && args.pageCount > 5){
  116. obj.append('<span>...</span>');
  117. }
  118. if(args.current != args.pageCount && args.current < args.pageCount -2 && args.pageCount != 4){
  119. obj.append('<a href="javascript:;" class="tcdNumber">'+args.pageCount+'</a>');
  120. }
  121. //下一页
  122. if(args.current < args.pageCount){
  123. obj.append('<a href="javascript:;" class="nextPage icon-right"></a>');
  124. }else{
  125. obj.remove('.nextPage');
  126. obj.append('<span class="disabled icon-right"></span>');
  127. }
  128. obj.append('<span class="pagecount">共'+args.pageCount+'页</span>');
  129. //跳转页码
  130. if(args.turndown == 'true'){
  131. obj.append('<span class="countYe">跳至<input type="text" onkeyup="this.value=this.value.replace(/\\D/g,\'\')" onafterpaste="this.value=this.value.replace(/\\D/g,\'\')" maxlength='+args.pageCount.toString().length+'>页<a href="javascript:;" class="turndown">确定</a><span>');
  132. }
  133. })();
  134. },
  135. //绑定事件
  136. bindEvent:function(obj,args){
  137. return (function(){
  138. obj.off("click","a.tcdNumber"); //移除原有事件 避免重复绑定
  139. obj.on("click","a.tcdNumber",function(){
  140. var current = parseInt($(this).text());
  141. ms.fillHtml(obj,{"current":current,"pageCount":args.pageCount,"turndown":args.turndown});
  142. if(typeof(args.backFn)=="function"){
  143. args.backFn(current);
  144. }
  145. });
  146. //上一页
  147. obj.off("click","a.prevPage"); //移除原有事件 避免重复绑定
  148. obj.on("click","a.prevPage",function(){
  149. var current = parseInt(obj.children("span.current").text());
  150. ms.fillHtml(obj,{"current":current-1,"pageCount":args.pageCount,"turndown":args.turndown});
  151. if(typeof(args.backFn)=="function"){
  152. args.backFn(current-1);
  153. }
  154. });
  155. //下一页
  156. obj.off("click","a.nextPage"); //移除原有事件 避免重复绑定
  157. obj.on("click","a.nextPage",function(){
  158. var current = parseInt(obj.children("span.current").text());
  159. ms.fillHtml(obj,{"current":current+1,"pageCount":args.pageCount,"turndown":args.turndown});
  160. if(typeof(args.backFn)=="function"){
  161. args.backFn(current+1);
  162. }
  163. });
  164. //跳转
  165. obj.off("click","a.turndown"); //移除原有事件 避免重复绑定
  166. obj.on("click","a.turndown",function(){
  167. var page = $("span.countYe input").val();
  168. if(page.trim()==""){page=1;}
  169. page=parseInt(page);
  170. if(page==0){page=1;}
  171. if (page > args.pageCount) {
  172. ZZAlertInfo("您的输入有误,请重新输入!");
  173. $("span.countYe input").val('');
  174. $("span.countYe input").focus();
  175. return;
  176. }
  177. ms.fillHtml(obj,{"current":page,"pageCount":args.pageCount,"turndown":args.turndown});
  178. if(typeof(args.backFn)=="function"){
  179. args.backFn(page);
  180. }
  181. // var page = parseInt($("span.countYe input").val());
  182. // if (page > args.pageCount) {
  183. // ZZAlertInfo("您的输入有误,请重新输入!");
  184. // return;
  185. // }
  186. // ms.fillHtml(obj,{"current":page,"pageCount":args.pageCount,"turndown":args.turndown});
  187. // if(typeof(args.backFn)=="function"){
  188. // args.backFn(page);
  189. // }
  190. });
  191. })();
  192. }
  193. }
  194. $.fn.createPage = function(options){
  195. var args = $.extend({
  196. pageCount : 10,
  197. current : 1,
  198. turndown:true,
  199. backFn : function(){}
  200. },options);
  201. ms.init(this,args);
  202. }
  203. })(jQuery);
  204. //NO.3 下拉筛选
  205. (function (factory) {
  206. 'use strict';
  207. if (typeof define === 'function' && define.amd) {
  208. // AMD. Register as an anonymous module.
  209. define(['jquery'], factory);
  210. } else if (typeof exports === 'object' && typeof require === 'function') {
  211. // Browserify
  212. factory(require('jquery'));
  213. } else {
  214. // Browser globals
  215. factory(jQuery);
  216. }
  217. }(function ( $, undefined ) {
  218. var pluginName = "comboSelect",
  219. dataKey = 'comboselect';
  220. var defaults = {
  221. comboClass : 'combo-select',
  222. comboArrowClass : 'combo-arrow',
  223. comboDropDownClass : 'combo-dropdown',
  224. inputClass : 'combo-input text-input',
  225. disabledClass : 'option-disabled',
  226. hoverClass : 'option-hover',
  227. selectedClass : 'option-selected',
  228. markerClass : 'combo-marker',
  229. themeClass : '',
  230. maxHeight : 200,
  231. extendStyle : true,
  232. focusInput : true
  233. };
  234. /**
  235. * Utility functions
  236. */
  237. var keys = {
  238. ESC: 27,
  239. TAB: 9,
  240. RETURN: 13,
  241. LEFT: 37,
  242. UP: 38,
  243. RIGHT: 39,
  244. DOWN: 40,
  245. ENTER: 13,
  246. SHIFT: 16
  247. },
  248. isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
  249. /**
  250. * Constructor
  251. * @param {[Node]} element [Select element]
  252. * @param {[Object]} options [Option object]
  253. */
  254. function Plugin ( element, options ) {
  255. /* Name of the plugin */
  256. this._name = pluginName;
  257. /* Reverse lookup */
  258. this.el = element
  259. /* Element */
  260. this.$el = $(element)
  261. /* If multiple select: stop */
  262. if(this.$el.prop('multiple')) return;
  263. /* Settings */
  264. this.settings = $.extend( {}, defaults, options, this.$el.data() );
  265. /* Defaults */
  266. this._defaults = defaults;
  267. /* Options */
  268. this.$options = this.$el.find('option, optgroup')
  269. /* Initialize */
  270. this.init();
  271. /* Instances */
  272. $.fn[ pluginName ].instances.push(this);
  273. }
  274. $.extend(Plugin.prototype, {
  275. init: function () {
  276. /* Construct the comboselect */
  277. this._construct();
  278. /* Add event bindings */
  279. this._events();
  280. },
  281. _construct: function(){
  282. var self = this
  283. /**
  284. * Add negative TabIndex to `select`
  285. * Preserves previous tabindex
  286. */
  287. this.$el.data('plugin_'+ dataKey + '_tabindex', this.$el.prop('tabindex'))
  288. /* Add a tab index for desktop browsers */
  289. !isMobile && this.$el.prop("tabIndex", -1)
  290. /**
  291. * Wrap the Select
  292. */
  293. this.$container = this.$el.wrapAll('<div class="' + this.settings.comboClass + ' '+ this.settings.themeClass + '" />').parent();
  294. /**
  295. * Check if select has a width attribute
  296. */
  297. if(this.settings.extendStyle && this.$el.attr('style')){
  298. this.$container.attr('style', this.$el.attr("style"))
  299. }
  300. /**
  301. * Append dropdown arrow
  302. */
  303. this.$arrow = $('<div class="'+ this.settings.comboArrowClass+ '" />').appendTo(this.$container)
  304. /**
  305. * Append dropdown
  306. */
  307. this.$dropdown = $('<ul class="'+this.settings.comboDropDownClass+'" />').appendTo(this.$container)
  308. /**
  309. * Create dropdown options
  310. */
  311. var o = '', k = 0, p = '';
  312. this.selectedIndex = this.$el.prop('selectedIndex')
  313. this.$options.each(function(i, e){
  314. if(e.nodeName.toLowerCase() == 'optgroup'){
  315. return o+='<li class="option-group">'+this.label+'</li>'
  316. }
  317. if(!e.value) p = e.innerHTML
  318. o+='<li class="'+(this.disabled? self.settings.disabledClass : "option-item") + ' ' +(k == self.selectedIndex? self.settings.selectedClass : '')+ '" data-index="'+(k)+'" data-value="'+this.value+'">'+ (this.innerHTML) + '</li>'
  319. k++;
  320. })
  321. this.$dropdown.html(o)
  322. /**
  323. * Items
  324. */
  325. this.$items = this.$dropdown.children();
  326. /**
  327. * Append Input
  328. */
  329. this.$input = $('<input type="text"' + (isMobile? 'tabindex="-1"': '') + ' placeholder="'+p+'" class="'+ this.settings.inputClass + '">').appendTo(this.$container)
  330. /* Update input text */
  331. this._updateInput()
  332. },
  333. _events: function(){
  334. /* Input: focus */
  335. this.$container.on('focus.input', 'input', $.proxy(this._focus, this))
  336. /**
  337. * Input: mouseup
  338. * For input select() event to function correctly
  339. */
  340. this.$container.on('mouseup.input', 'input', function(e){
  341. e.preventDefault()
  342. })
  343. /* Input: blur */
  344. this.$container.on('blur.input', 'input', $.proxy(this._blur, this))
  345. /* Select: change */
  346. this.$el.on('change.select', $.proxy(this._change, this))
  347. /* Select: focus */
  348. this.$el.on('focus.select', $.proxy(this._focus, this))
  349. /* Select: blur */
  350. this.$el.on('blur.select', $.proxy(this._blurSelect, this))
  351. /* Dropdown Arrow: click */
  352. this.$container.on('click.arrow', '.'+this.settings.comboArrowClass , $.proxy(this._toggle, this))
  353. /* Dropdown: close */
  354. this.$container.on('comboselect:close', $.proxy(this._close, this))
  355. /* Dropdown: open */
  356. this.$container.on('comboselect:open', $.proxy(this._open, this))
  357. /* HTML Click */
  358. $('html').off('click.comboselect').on('click.comboselect', function(){
  359. $.each($.fn[ pluginName ].instances, function(i, plugin){
  360. plugin.$container.trigger('comboselect:close')
  361. })
  362. });
  363. /* Stop `event:click` bubbling */
  364. this.$container.on('click.comboselect', function(e){
  365. e.stopPropagation();
  366. })
  367. /* Input: keydown */
  368. this.$container.on('keydown', 'input', $.proxy(this._keydown, this))
  369. /* Input: keyup */
  370. this.$container.on('keyup', 'input', $.proxy(this._keyup, this))
  371. /* Dropdown item: click */
  372. this.$container.on('click.item', '.option-item', $.proxy(this._select, this))
  373. },
  374. _keydown: function(event){
  375. switch(event.which){
  376. case keys.UP:
  377. this._move('up', event)
  378. break;
  379. case keys.DOWN:
  380. this._move('down', event)
  381. break;
  382. case keys.TAB:
  383. this._enter(event)
  384. break;
  385. case keys.RIGHT:
  386. this._autofill(event);
  387. break;
  388. case keys.ENTER:
  389. this._enter(event);
  390. break;
  391. default:
  392. break;
  393. }
  394. },
  395. _keyup: function(event){
  396. switch(event.which){
  397. case keys.ESC:
  398. this.$container.trigger('comboselect:close')
  399. break;
  400. case keys.ENTER:
  401. case keys.UP:
  402. case keys.DOWN:
  403. case keys.LEFT:
  404. case keys.RIGHT:
  405. case keys.TAB:
  406. case keys.SHIFT:
  407. break;
  408. default:
  409. this._filter(event.target.value)
  410. break;
  411. }
  412. },
  413. _enter: function(event){
  414. var item = this._getHovered()
  415. item.length && this._select(item);
  416. /* Check if it enter key */
  417. if(event && event.which == keys.ENTER){
  418. if(!item.length) {
  419. /* Check if its illegal value */
  420. this._blur();
  421. return true;
  422. }
  423. event.preventDefault();
  424. }
  425. },
  426. _move: function(dir){
  427. var items = this._getVisible(),
  428. current = this._getHovered(),
  429. index = current.prevAll('.option-item').filter(':visible').length,
  430. total = items.length
  431. switch(dir){
  432. case 'up':
  433. index--;
  434. (index < 0) && (index = (total - 1));
  435. break;
  436. case 'down':
  437. index++;
  438. (index >= total) && (index = 0);
  439. break;
  440. }
  441. items
  442. .removeClass(this.settings.hoverClass)
  443. .eq(index)
  444. .addClass(this.settings.hoverClass)
  445. if(!this.opened) this.$container.trigger('comboselect:open');
  446. this._fixScroll()
  447. },
  448. _select: function(event){
  449. var item = event.currentTarget? $(event.currentTarget) : $(event);
  450. if(!item.length) return;
  451. /**
  452. * 1. get Index
  453. */
  454. var index = item.data('index');
  455. this._selectByIndex(index);
  456. this.$container.trigger('comboselect:close')
  457. },
  458. _selectByIndex: function(index){
  459. /**
  460. * Set selected index and trigger change
  461. * @type {[type]}
  462. */
  463. if(typeof index == 'undefined'){
  464. index = 0
  465. }
  466. if(this.$el.prop('selectedIndex') != index){
  467. this.$el.prop('selectedIndex', index).trigger('change');
  468. }
  469. },
  470. _autofill: function(){
  471. var item = this._getHovered();
  472. if(item.length){
  473. var index = item.data('index')
  474. this._selectByIndex(index)
  475. }
  476. },
  477. _filter: function(search){
  478. var self = this,
  479. items = this._getAll();
  480. needle = $.trim(search).toLowerCase(),
  481. reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g'),
  482. pattern = '(' + search.replace(reEscape, '\\$1') + ')';
  483. /**
  484. * Unwrap all markers
  485. */
  486. $('.'+self.settings.markerClass, items).contents().unwrap();
  487. /* Search */
  488. if(needle){
  489. /* Hide Disabled and optgroups */
  490. this.$items.filter('.option-group, .option-disabled').hide();
  491. items
  492. .hide()
  493. .filter(function(){
  494. var $this = $(this),
  495. text = $.trim($this.text()).toLowerCase();
  496. /* Found */
  497. if(text.toString().indexOf(needle) != -1){
  498. /**
  499. * Wrap the selection
  500. */
  501. $this
  502. .html(function(index, oldhtml){
  503. return oldhtml.replace(new RegExp(pattern, 'gi'), '<span class="'+self.settings.markerClass+'">$1</span>')
  504. })
  505. return true
  506. }
  507. })
  508. .show()
  509. }else{
  510. this.$items.show();
  511. }
  512. /* Open the comboselect */
  513. this.$container.trigger('comboselect:open')
  514. },
  515. _highlight: function(){
  516. /*
  517. 1. Check if there is a selected item
  518. 2. Add hover class to it
  519. 3. If not add hover class to first item
  520. */
  521. var visible = this._getVisible().removeClass(this.settings.hoverClass),
  522. $selected = visible.filter('.'+this.settings.selectedClass)
  523. if($selected.length){
  524. $selected.addClass(this.settings.hoverClass);
  525. }else{
  526. visible
  527. .removeClass(this.settings.hoverClass)
  528. .first()
  529. .addClass(this.settings.hoverClass)
  530. }
  531. },
  532. _updateInput: function(){
  533. var selected = this.$el.prop('selectedIndex')
  534. if(this.$el.val()){
  535. text = this.$el.find('option').eq(selected).text()
  536. this.$input.val(text)
  537. }else{
  538. this.$input.val('')
  539. }
  540. return this._getAll()
  541. .removeClass(this.settings.selectedClass)
  542. .filter(function(){
  543. return $(this).data('index') == selected
  544. })
  545. .addClass(this.settings.selectedClass)
  546. },
  547. _blurSelect: function(){
  548. this.$container.removeClass('combo-focus');
  549. },
  550. _focus: function(event){
  551. /* Toggle focus class */
  552. this.$container.toggleClass('combo-focus', !this.opened);
  553. /* If mobile: stop */
  554. if(isMobile) return;
  555. /* Open combo */
  556. if(!this.opened) this.$container.trigger('comboselect:open');
  557. /* Select the input */
  558. this.settings.focusInput && event && event.currentTarget && event.currentTarget.nodeName == 'INPUT' && event.currentTarget.select()
  559. },
  560. _blur: function(){
  561. /**
  562. * 1. Get hovered item
  563. * 2. If not check if input value == select option
  564. * 3. If none
  565. */
  566. var val = $.trim(this.$input.val().toLowerCase()),
  567. isNumber = !isNaN(val);
  568. var index = this.$options.filter(function(){
  569. if(isNumber){
  570. return parseInt($.trim(this.innerHTML).toLowerCase()) == val
  571. }
  572. return $.trim(this.innerHTML).toLowerCase() == val
  573. }).prop('index')
  574. /* Select by Index */
  575. this._selectByIndex(index)
  576. },
  577. _change: function(){
  578. this._updateInput();
  579. },
  580. _getAll: function(){
  581. return this.$items.filter('.option-item')
  582. },
  583. _getVisible: function(){
  584. return this.$items.filter('.option-item').filter(':visible')
  585. },
  586. _getHovered: function(){
  587. return this._getVisible().filter('.' + this.settings.hoverClass);
  588. },
  589. _open: function(){
  590. var self = this
  591. this.$container.addClass('combo-open')
  592. this.opened = true
  593. /* Focus input field */
  594. this.settings.focusInput && setTimeout(function(){ !self.$input.is(':focus') && self.$input.focus(); });
  595. /* Highligh the items */
  596. this._highlight()
  597. /* Fix scroll */
  598. this._fixScroll()
  599. /* Close all others */
  600. $.each($.fn[ pluginName ].instances, function(i, plugin){
  601. if(plugin != self && plugin.opened) plugin.$container.trigger('comboselect:close')
  602. })
  603. },
  604. _toggle: function(){
  605. this.opened? this._close.call(this) : this._open.call(this)
  606. },
  607. _close: function(){
  608. this.$container.removeClass('combo-open combo-focus')
  609. this.$container.trigger('comboselect:closed')
  610. this.opened = false
  611. /* Show all items */
  612. this.$items.show();
  613. },
  614. _fixScroll: function(){
  615. /**
  616. * If dropdown is hidden
  617. */
  618. if(this.$dropdown.is(':hidden')) return;
  619. /**
  620. * Else
  621. */
  622. var item = this._getHovered();
  623. if(!item.length) return;
  624. /**
  625. * Scroll
  626. */
  627. var offsetTop,
  628. upperBound,
  629. lowerBound,
  630. heightDelta = item.outerHeight()
  631. offsetTop = item[0].offsetTop;
  632. upperBound = this.$dropdown.scrollTop();
  633. lowerBound = upperBound + this.settings.maxHeight - heightDelta;
  634. if (offsetTop < upperBound) {
  635. this.$dropdown.scrollTop(offsetTop);
  636. } else if (offsetTop > lowerBound) {
  637. this.$dropdown.scrollTop(offsetTop - this.settings.maxHeight + heightDelta);
  638. }
  639. },
  640. /**
  641. * Destroy API
  642. */
  643. dispose: function(){
  644. /* Remove combo arrow, input, dropdown */
  645. this.$arrow.remove()
  646. this.$input.remove()
  647. this.$dropdown.remove()
  648. /* Remove tabindex property */
  649. this.$el
  650. .removeAttr("tabindex")
  651. /* Check if there is a tabindex set before */
  652. if(!!this.$el.data('plugin_'+ dataKey + '_tabindex')){
  653. this.$el.prop('tabindex', this.$el.data('plugin_'+ dataKey + '_tabindex'))
  654. }
  655. /* Unwrap */
  656. this.$el.unwrap()
  657. /* Remove data */
  658. this.$el.removeData('plugin_'+dataKey)
  659. /* Remove tabindex data */
  660. this.$el.removeData('plugin_'+dataKey + '_tabindex')
  661. /* Remove change event on select */
  662. this.$el.off('change.select focus.select blur.select');
  663. }
  664. });
  665. // A really lightweight plugin wrapper around the constructor,
  666. // preventing against multiple instantiations
  667. $.fn[ pluginName ] = function ( options, args ) {
  668. this.each(function() {
  669. var $e = $(this),
  670. instance = $e.data('plugin_'+dataKey)
  671. if (typeof options === 'string') {
  672. if (instance && typeof instance[options] === 'function') {
  673. instance[options](args);
  674. }
  675. }else{
  676. if (instance && instance.dispose) {
  677. instance.dispose();
  678. }
  679. $.data( this, "plugin_" + dataKey, new Plugin( this, options ) );
  680. }
  681. });
  682. // chain jQuery functions
  683. return this;
  684. };
  685. $.fn[ pluginName ].instances = [];
  686. }));
  687. //No.4日历
  688. /* =========================================================
  689. * bootstrap-datetimepicker.js
  690. * =========================================================
  691. * Copyright 2012 Stefan Petre
  692. *
  693. * Improvements by Andrew Rowls
  694. * Improvements by Sébastien Malot
  695. * Improvements by Yun Lai
  696. * Improvements by Kenneth Henderick
  697. * Improvements by CuGBabyBeaR
  698. * Improvements by Christian Vaas <auspex@auspex.eu>
  699. *
  700. * Project URL : http://www.malot.fr/bootstrap-datetimepicker
  701. *
  702. * Licensed under the Apache License, Version 2.0 (the "License");
  703. * you may not use this file except in compliance with the License.
  704. * You may obtain a copy of the License at
  705. *
  706. * http://www.apache.org/licenses/LICENSE-2.0
  707. *
  708. * Unless required by applicable law or agreed to in writing, software
  709. * distributed under the License is distributed on an "AS IS" BASIS,
  710. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  711. * See the License for the specific language governing permissions and
  712. * limitations under the License.
  713. * ========================================================= */
  714. (function(factory){
  715. if (typeof define === 'function' && define.amd)
  716. define(['jquery'], factory);
  717. else if (typeof exports === 'object')
  718. factory(require('jquery'));
  719. else
  720. factory(jQuery);
  721. }(function($, undefined){
  722. // Add ECMA262-5 Array methods if not supported natively (IE8)
  723. if (!('indexOf' in Array.prototype)) {
  724. Array.prototype.indexOf = function (find, i) {
  725. if (i === undefined) i = 0;
  726. if (i < 0) i += this.length;
  727. if (i < 0) i = 0;
  728. for (var n = this.length; i < n; i++) {
  729. if (i in this && this[i] === find) {
  730. return i;
  731. }
  732. }
  733. return -1;
  734. }
  735. }
  736. // Add timezone abbreviation support for ie6+, Chrome, Firefox
  737. function timeZoneAbbreviation() {
  738. var abbreviation, date, formattedStr, i, len, matchedStrings, ref, str;
  739. date = (new Date()).toString();
  740. formattedStr = ((ref = date.split('(')[1]) != null ? ref.slice(0, -1) : 0) || date.split(' ');
  741. if (formattedStr instanceof Array) {
  742. matchedStrings = [];
  743. for (var i = 0, len = formattedStr.length; i < len; i++) {
  744. str = formattedStr[i];
  745. if ((abbreviation = (ref = str.match(/\b[A-Z]+\b/)) !== null) ? ref[0] : 0) {
  746. matchedStrings.push(abbreviation);
  747. }
  748. }
  749. formattedStr = matchedStrings.pop();
  750. }
  751. return formattedStr;
  752. }
  753. function UTCDate() {
  754. return new Date(Date.UTC.apply(Date, arguments));
  755. }
  756. // Picker object
  757. var Datetimepicker = function (element, options) {
  758. var that = this;
  759. this.element = $(element);
  760. // add container for single page application
  761. // when page switch the datetimepicker div will be removed also.
  762. this.container = options.container || 'body';
  763. this.language = options.language || this.element.data('date-language') || 'en';
  764. this.language = this.language in dates ? this.language : this.language.split('-')[0]; // fr-CA fallback to fr
  765. this.language = this.language in dates ? this.language : 'en';
  766. this.isRTL = dates[this.language].rtl || false;
  767. this.formatType = options.formatType || this.element.data('format-type') || 'standard';
  768. this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || dates[this.language].format || DPGlobal.getDefaultFormat(this.formatType, 'input'), this.formatType);
  769. this.isInline = false;
  770. this.isVisible = false;
  771. this.isInput = this.element.is('input');
  772. this.fontAwesome = options.fontAwesome || this.element.data('font-awesome') || false;
  773. this.bootcssVer = options.bootcssVer || (this.isInput ? (this.element.is('.form-control') ? 3 : 2) : ( this.bootcssVer = this.element.is('.input-group') ? 3 : 2 ));
  774. this.component = this.element.is('.date') ? ( this.bootcssVer === 3 ? this.element.find('.input-group-addon .glyphicon-th, .input-group-addon .glyphicon-time, .input-group-addon .glyphicon-remove, .input-group-addon .glyphicon-calendar, .input-group-addon .fa-calendar, .input-group-addon .fa-clock-o').parent() : this.element.find('.add-on .icon-th, .add-on .icon-time, .add-on .icon-calendar, .add-on .fa-calendar, .add-on .fa-clock-o').parent()) : false;
  775. this.componentReset = this.element.is('.date') ? ( this.bootcssVer === 3 ? this.element.find('.input-group-addon .glyphicon-remove, .input-group-addon .fa-times').parent():this.element.find('.add-on .icon-remove, .add-on .fa-times').parent()) : false;
  776. this.hasInput = this.component && this.element.find('input').length;
  777. if (this.component && this.component.length === 0) {
  778. this.component = false;
  779. }
  780. this.linkField = options.linkField || this.element.data('link-field') || false;
  781. this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || DPGlobal.getDefaultFormat(this.formatType, 'link'), this.formatType);
  782. this.minuteStep = options.minuteStep || this.element.data('minute-step') || 5;
  783. this.pickerPosition = options.pickerPosition || this.element.data('picker-position') || 'bottom-right';
  784. this.showMeridian = options.showMeridian || this.element.data('show-meridian') || false;
  785. this.initialDate = options.initialDate || new Date();
  786. this.zIndex = options.zIndex || this.element.data('z-index') || undefined;
  787. this.title = typeof options.title === 'undefined' ? false : options.title;
  788. this.timezone = options.timezone || timeZoneAbbreviation();
  789. this.icons = {
  790. leftArrow: this.fontAwesome ? 'fa-arrow-left' : (this.bootcssVer === 3 ? 'glyphicon-arrow-left' : 'icon-arrow-left'),
  791. rightArrow: this.fontAwesome ? 'fa-arrow-right' : (this.bootcssVer === 3 ? 'glyphicon-arrow-right' : 'icon-arrow-right')
  792. }
  793. this.icontype = this.fontAwesome ? 'fa' : 'glyphicon';
  794. this._attachEvents();
  795. this.clickedOutside = function (e) {
  796. // Clicked outside the datetimepicker, hide it
  797. if ($(e.target).closest('.datetimepicker').length === 0) {
  798. that.hide();
  799. }
  800. }
  801. this.formatViewType = 'datetime';
  802. if ('formatViewType' in options) {
  803. this.formatViewType = options.formatViewType;
  804. } else if ('formatViewType' in this.element.data()) {
  805. this.formatViewType = this.element.data('formatViewType');
  806. }
  807. this.minView = 0;
  808. if ('minView' in options) {
  809. this.minView = options.minView;
  810. } else if ('minView' in this.element.data()) {
  811. this.minView = this.element.data('min-view');
  812. }
  813. this.minView = DPGlobal.convertViewMode(this.minView);
  814. this.maxView = DPGlobal.modes.length - 1;
  815. if ('maxView' in options) {
  816. this.maxView = options.maxView;
  817. } else if ('maxView' in this.element.data()) {
  818. this.maxView = this.element.data('max-view');
  819. }
  820. this.maxView = DPGlobal.convertViewMode(this.maxView);
  821. this.wheelViewModeNavigation = false;
  822. if ('wheelViewModeNavigation' in options) {
  823. this.wheelViewModeNavigation = options.wheelViewModeNavigation;
  824. } else if ('wheelViewModeNavigation' in this.element.data()) {
  825. this.wheelViewModeNavigation = this.element.data('view-mode-wheel-navigation');
  826. }
  827. this.wheelViewModeNavigationInverseDirection = false;
  828. if ('wheelViewModeNavigationInverseDirection' in options) {
  829. this.wheelViewModeNavigationInverseDirection = options.wheelViewModeNavigationInverseDirection;
  830. } else if ('wheelViewModeNavigationInverseDirection' in this.element.data()) {
  831. this.wheelViewModeNavigationInverseDirection = this.element.data('view-mode-wheel-navigation-inverse-dir');
  832. }
  833. this.wheelViewModeNavigationDelay = 100;
  834. if ('wheelViewModeNavigationDelay' in options) {
  835. this.wheelViewModeNavigationDelay = options.wheelViewModeNavigationDelay;
  836. } else if ('wheelViewModeNavigationDelay' in this.element.data()) {
  837. this.wheelViewModeNavigationDelay = this.element.data('view-mode-wheel-navigation-delay');
  838. }
  839. this.startViewMode = 2;
  840. if ('startView' in options) {
  841. this.startViewMode = options.startView;
  842. } else if ('startView' in this.element.data()) {
  843. this.startViewMode = this.element.data('start-view');
  844. }
  845. this.startViewMode = DPGlobal.convertViewMode(this.startViewMode);
  846. this.viewMode = this.startViewMode;
  847. this.viewSelect = this.minView;
  848. if ('viewSelect' in options) {
  849. this.viewSelect = options.viewSelect;
  850. } else if ('viewSelect' in this.element.data()) {
  851. this.viewSelect = this.element.data('view-select');
  852. }
  853. this.viewSelect = DPGlobal.convertViewMode(this.viewSelect);
  854. this.forceParse = true;
  855. if ('forceParse' in options) {
  856. this.forceParse = options.forceParse;
  857. } else if ('dateForceParse' in this.element.data()) {
  858. this.forceParse = this.element.data('date-force-parse');
  859. }
  860. var template = this.bootcssVer === 3 ? DPGlobal.templateV3 : DPGlobal.template;
  861. while (template.indexOf('{iconType}') !== -1) {
  862. template = template.replace('{iconType}', this.icontype);
  863. }
  864. while (template.indexOf('{leftArrow}') !== -1) {
  865. template = template.replace('{leftArrow}', this.icons.leftArrow);
  866. }
  867. while (template.indexOf('{rightArrow}') !== -1) {
  868. template = template.replace('{rightArrow}', this.icons.rightArrow);
  869. }
  870. this.picker = $(template)
  871. .appendTo(this.isInline ? this.element : this.container) // 'body')
  872. .on({
  873. click: $.proxy(this.click, this),
  874. mousedown: $.proxy(this.mousedown, this)
  875. });
  876. if (this.wheelViewModeNavigation) {
  877. if ($.fn.mousewheel) {
  878. this.picker.on({mousewheel: $.proxy(this.mousewheel, this)});
  879. } else {
  880. console.log('Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option');
  881. }
  882. }
  883. if (this.isInline) {
  884. this.picker.addClass('datetimepicker-inline');
  885. } else {
  886. this.picker.addClass('datetimepicker-dropdown-' + this.pickerPosition + ' dropdown-menu');
  887. }
  888. if (this.isRTL) {
  889. this.picker.addClass('datetimepicker-rtl');
  890. var selector = this.bootcssVer === 3 ? '.prev span, .next span' : '.prev i, .next i';
  891. this.picker.find(selector).toggleClass(this.icons.leftArrow + ' ' + this.icons.rightArrow);
  892. }
  893. $(document).on('mousedown touchend', this.clickedOutside);
  894. this.autoclose = false;
  895. if ('autoclose' in options) {
  896. this.autoclose = options.autoclose;
  897. } else if ('dateAutoclose' in this.element.data()) {
  898. this.autoclose = this.element.data('date-autoclose');
  899. }
  900. this.keyboardNavigation = true;
  901. if ('keyboardNavigation' in options) {
  902. this.keyboardNavigation = options.keyboardNavigation;
  903. } else if ('dateKeyboardNavigation' in this.element.data()) {
  904. this.keyboardNavigation = this.element.data('date-keyboard-navigation');
  905. }
  906. this.todayBtn = (options.todayBtn || this.element.data('date-today-btn') || false);
  907. this.clearBtn = (options.clearBtn || this.element.data('date-clear-btn') || false);
  908. this.todayHighlight = (options.todayHighlight || this.element.data('date-today-highlight') || false);
  909. this.weekStart = 0;
  910. if (typeof options.weekStart !== 'undefined') {
  911. this.weekStart = options.weekStart;
  912. } else if (typeof this.element.data('date-weekstart') !== 'undefined') {
  913. this.weekStart = this.element.data('date-weekstart');
  914. } else if (typeof dates[this.language].weekStart !== 'undefined') {
  915. this.weekStart = dates[this.language].weekStart;
  916. }
  917. this.weekStart = this.weekStart % 7;
  918. this.weekEnd = ((this.weekStart + 6) % 7);
  919. this.onRenderDay = function (date) {
  920. var render = (options.onRenderDay || function () { return []; })(date);
  921. if (typeof render === 'string') {
  922. render = [render];
  923. }
  924. var res = ['day'];
  925. return res.concat((render ? render : []));
  926. };
  927. this.onRenderHour = function (date) {
  928. var render = (options.onRenderHour || function () { return []; })(date);
  929. var res = ['hour'];
  930. if (typeof render === 'string') {
  931. render = [render];
  932. }
  933. return res.concat((render ? render : []));
  934. };
  935. this.onRenderMinute = function (date) {
  936. var render = (options.onRenderMinute || function () { return []; })(date);
  937. var res = ['minute'];
  938. if (typeof render === 'string') {
  939. render = [render];
  940. }
  941. if (date < this.startDate || date > this.endDate) {
  942. res.push('disabled');
  943. } else if (Math.floor(this.date.getUTCMinutes() / this.minuteStep) === Math.floor(date.getUTCMinutes() / this.minuteStep)) {
  944. res.push('active');
  945. }
  946. return res.concat((render ? render : []));
  947. };
  948. this.onRenderYear = function (date) {
  949. var render = (options.onRenderYear || function () { return []; })(date);
  950. var res = ['year'];
  951. if (typeof render === 'string') {
  952. render = [render];
  953. }
  954. if (this.date.getUTCFullYear() === date.getUTCFullYear()) {
  955. res.push('active');
  956. }
  957. var currentYear = date.getUTCFullYear();
  958. var endYear = this.endDate.getUTCFullYear();
  959. if (date < this.startDate || currentYear > endYear) {
  960. res.push('disabled');
  961. }
  962. return res.concat((render ? render : []));
  963. }
  964. this.onRenderMonth = function (date) {
  965. var render = (options.onRenderMonth || function () { return []; })(date);
  966. var res = ['month'];
  967. if (typeof render === 'string') {
  968. render = [render];
  969. }
  970. return res.concat((render ? render : []));
  971. }
  972. this.startDate = new Date(-8639968443048000);
  973. this.endDate = new Date(8639968443048000);
  974. this.datesDisabled = [];
  975. this.daysOfWeekDisabled = [];
  976. this.setStartDate(options.startDate || this.element.data('date-startdate'));
  977. this.setEndDate(options.endDate || this.element.data('date-enddate'));
  978. this.setDatesDisabled(options.datesDisabled || this.element.data('date-dates-disabled'));
  979. this.setDaysOfWeekDisabled(options.daysOfWeekDisabled || this.element.data('date-days-of-week-disabled'));
  980. this.setMinutesDisabled(options.minutesDisabled || this.element.data('date-minute-disabled'));
  981. this.setHoursDisabled(options.hoursDisabled || this.element.data('date-hour-disabled'));
  982. this.fillDow();
  983. this.fillMonths();
  984. this.update();
  985. this.showMode();
  986. if (this.isInline) {
  987. this.show();
  988. }
  989. };
  990. Datetimepicker.prototype = {
  991. constructor: Datetimepicker,
  992. _events: [],
  993. _attachEvents: function () {
  994. this._detachEvents();
  995. if (this.isInput) { // single input
  996. this._events = [
  997. [this.element, {
  998. focus: $.proxy(this.show, this),
  999. keyup: $.proxy(this.update, this),
  1000. keydown: $.proxy(this.keydown, this)
  1001. }]
  1002. ];
  1003. }
  1004. else if (this.component && this.hasInput) { // component: input + button
  1005. this._events = [
  1006. // For components that are not readonly, allow keyboard nav
  1007. [this.element.find('input'), {
  1008. focus: $.proxy(this.show, this),
  1009. keyup: $.proxy(this.update, this),
  1010. keydown: $.proxy(this.keydown, this)
  1011. }],
  1012. [this.component, {
  1013. click: $.proxy(this.show, this)
  1014. }]
  1015. ];
  1016. if (this.componentReset) {
  1017. this._events.push([
  1018. this.componentReset,
  1019. {click: $.proxy(this.reset, this)}
  1020. ]);
  1021. }
  1022. }
  1023. else if (this.element.is('div')) { // inline datetimepicker
  1024. this.isInline = true;
  1025. }
  1026. else {
  1027. this._events = [
  1028. [this.element, {
  1029. click: $.proxy(this.show, this)
  1030. }]
  1031. ];
  1032. }
  1033. for (var i = 0, el, ev; i < this._events.length; i++) {
  1034. el = this._events[i][0];
  1035. ev = this._events[i][1];
  1036. el.on(ev);
  1037. }
  1038. },
  1039. _detachEvents: function () {
  1040. for (var i = 0, el, ev; i < this._events.length; i++) {
  1041. el = this._events[i][0];
  1042. ev = this._events[i][1];
  1043. el.off(ev);
  1044. }
  1045. this._events = [];
  1046. },
  1047. show: function (e) {
  1048. this.picker.show();
  1049. this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
  1050. if (this.forceParse) {
  1051. this.update();
  1052. }
  1053. this.place();
  1054. $(window).on('resize', $.proxy(this.place, this));
  1055. if (e) {
  1056. e.stopPropagation();
  1057. e.preventDefault();
  1058. }
  1059. this.isVisible = true;
  1060. this.element.trigger({
  1061. type: 'show',
  1062. date: this.date
  1063. });
  1064. },
  1065. hide: function () {
  1066. if (!this.isVisible) return;
  1067. if (this.isInline) return;
  1068. this.picker.hide();
  1069. $(window).off('resize', this.place);
  1070. this.viewMode = this.startViewMode;
  1071. this.showMode();
  1072. if (!this.isInput) {
  1073. $(document).off('mousedown', this.hide);
  1074. }
  1075. if (
  1076. this.forceParse &&
  1077. (
  1078. this.isInput && this.element.val() ||
  1079. this.hasInput && this.element.find('input').val()
  1080. )
  1081. )
  1082. this.setValue();
  1083. this.isVisible = false;
  1084. this.element.trigger({
  1085. type: 'hide',
  1086. date: this.date
  1087. });
  1088. },
  1089. remove: function () {
  1090. this._detachEvents();
  1091. $(document).off('mousedown', this.clickedOutside);
  1092. this.picker.remove();
  1093. delete this.picker;
  1094. delete this.element.data().datetimepicker;
  1095. },
  1096. getDate: function () {
  1097. var d = this.getUTCDate();
  1098. if (d === null) {
  1099. return null;
  1100. }
  1101. return new Date(d.getTime() + (d.getTimezoneOffset() * 60000));
  1102. },
  1103. getUTCDate: function () {
  1104. return this.date;
  1105. },
  1106. getInitialDate: function () {
  1107. return this.initialDate
  1108. },
  1109. setInitialDate: function (initialDate) {
  1110. this.initialDate = initialDate;
  1111. },
  1112. setDate: function (d) {
  1113. this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset() * 60000)));
  1114. },
  1115. setUTCDate: function (d) {
  1116. if (d >= this.startDate && d <= this.endDate) {
  1117. this.date = d;
  1118. this.setValue();
  1119. this.viewDate = this.date;
  1120. this.fill();
  1121. } else {
  1122. this.element.trigger({
  1123. type: 'outOfRange',
  1124. date: d,
  1125. startDate: this.startDate,
  1126. endDate: this.endDate
  1127. });
  1128. }
  1129. },
  1130. setFormat: function (format) {
  1131. this.format = DPGlobal.parseFormat(format, this.formatType);
  1132. var element;
  1133. if (this.isInput) {
  1134. element = this.element;
  1135. } else if (this.component) {
  1136. element = this.element.find('input');
  1137. }
  1138. if (element && element.val()) {
  1139. this.setValue();
  1140. }
  1141. },
  1142. setValue: function () {
  1143. var formatted = this.getFormattedDate();
  1144. if (!this.isInput) {
  1145. if (this.component) {
  1146. this.element.find('input').val(formatted);
  1147. }
  1148. this.element.data('date', formatted);
  1149. } else {
  1150. this.element.val(formatted);
  1151. }
  1152. if (this.linkField) {
  1153. $('#' + this.linkField).val(this.getFormattedDate(this.linkFormat));
  1154. }
  1155. },
  1156. getFormattedDate: function (format) {
  1157. format = format || this.format;
  1158. return DPGlobal.formatDate(this.date, format, this.language, this.formatType, this.timezone);
  1159. },
  1160. setStartDate: function (startDate) {
  1161. this.startDate = startDate || this.startDate;
  1162. if (this.startDate.valueOf() !== 8639968443048000) {
  1163. this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language, this.formatType, this.timezone);
  1164. }
  1165. this.update();
  1166. this.updateNavArrows();
  1167. },
  1168. setEndDate: function (endDate) {
  1169. this.endDate = endDate || this.endDate;
  1170. if (this.endDate.valueOf() !== 8639968443048000) {
  1171. this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language, this.formatType, this.timezone);
  1172. }
  1173. this.update();
  1174. this.updateNavArrows();
  1175. },
  1176. setDatesDisabled: function (datesDisabled) {
  1177. this.datesDisabled = datesDisabled || [];
  1178. if (!$.isArray(this.datesDisabled)) {
  1179. this.datesDisabled = this.datesDisabled.split(/,\s*/);
  1180. }
  1181. var mThis = this;
  1182. this.datesDisabled = $.map(this.datesDisabled, function (d) {
  1183. return DPGlobal.parseDate(d, mThis.format, mThis.language, mThis.formatType, mThis.timezone).toDateString();
  1184. });
  1185. this.update();
  1186. this.updateNavArrows();
  1187. },
  1188. setTitle: function (selector, value) {
  1189. return this.picker.find(selector)
  1190. .find('th:eq(1)')
  1191. .text(this.title === false ? value : this.title);
  1192. },
  1193. setDaysOfWeekDisabled: function (daysOfWeekDisabled) {
  1194. this.daysOfWeekDisabled = daysOfWeekDisabled || [];
  1195. if (!$.isArray(this.daysOfWeekDisabled)) {
  1196. this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
  1197. }
  1198. this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {
  1199. return parseInt(d, 10);
  1200. });
  1201. this.update();
  1202. this.updateNavArrows();
  1203. },
  1204. setMinutesDisabled: function (minutesDisabled) {
  1205. this.minutesDisabled = minutesDisabled || [];
  1206. if (!$.isArray(this.minutesDisabled)) {
  1207. this.minutesDisabled = this.minutesDisabled.split(/,\s*/);
  1208. }
  1209. this.minutesDisabled = $.map(this.minutesDisabled, function (d) {
  1210. return parseInt(d, 10);
  1211. });
  1212. this.update();
  1213. this.updateNavArrows();
  1214. },
  1215. setHoursDisabled: function (hoursDisabled) {
  1216. this.hoursDisabled = hoursDisabled || [];
  1217. if (!$.isArray(this.hoursDisabled)) {
  1218. this.hoursDisabled = this.hoursDisabled.split(/,\s*/);
  1219. }
  1220. this.hoursDisabled = $.map(this.hoursDisabled, function (d) {
  1221. return parseInt(d, 10);
  1222. });
  1223. this.update();
  1224. this.updateNavArrows();
  1225. },
  1226. place: function () {
  1227. if (this.isInline) return;
  1228. if (!this.zIndex) {
  1229. var index_highest = 0;
  1230. $('div').each(function () {
  1231. var index_current = parseInt($(this).css('zIndex'), 10);
  1232. if (index_current > index_highest) {
  1233. index_highest = index_current;
  1234. }
  1235. });
  1236. this.zIndex = index_highest + 10;
  1237. }
  1238. var offset, top, left, containerOffset;
  1239. if (this.container instanceof $) {
  1240. containerOffset = this.container.offset();
  1241. } else {
  1242. containerOffset = $(this.container).offset();
  1243. }
  1244. if (this.component) {
  1245. offset = this.component.offset();
  1246. left = offset.left;
  1247. if (this.pickerPosition === 'bottom-left' || this.pickerPosition === 'top-left') {
  1248. left += this.component.outerWidth() - this.picker.outerWidth();
  1249. }
  1250. } else {
  1251. offset = this.element.offset();
  1252. left = offset.left;
  1253. if (this.pickerPosition === 'bottom-left' || this.pickerPosition === 'top-left') {
  1254. left += this.element.outerWidth() - this.picker.outerWidth();
  1255. }
  1256. }
  1257. var bodyWidth = document.body.clientWidth || window.innerWidth;
  1258. if (left + 220 > bodyWidth) {
  1259. left = bodyWidth - 220;
  1260. }
  1261. if (this.pickerPosition === 'top-left' || this.pickerPosition === 'top-right') {
  1262. top = offset.top - this.picker.outerHeight();
  1263. } else {
  1264. top = offset.top + this.height;
  1265. }
  1266. top = top - containerOffset.top;
  1267. left = left - containerOffset.left;
  1268. this.picker.css({
  1269. top: top,
  1270. left: left,
  1271. zIndex: this.zIndex
  1272. });
  1273. },
  1274. hour_minute: "^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]",
  1275. update: function () {
  1276. var date, fromArgs = false;
  1277. if (arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
  1278. date = arguments[0];
  1279. fromArgs = true;
  1280. } else {
  1281. date = (this.isInput ? this.element.val() : this.element.find('input').val()) || this.element.data('date') || this.initialDate;
  1282. if (typeof date === 'string') {
  1283. date = date.replace(/^\s+|\s+$/g,'');
  1284. }
  1285. }
  1286. if (!date) {
  1287. date = new Date();
  1288. fromArgs = false;
  1289. }
  1290. if (typeof date === "string") {
  1291. if (new RegExp(this.hour_minute).test(date) || new RegExp(this.hour_minute + ":[0-5][0-9]").test(date)) {
  1292. date = this.getDate()
  1293. }
  1294. }
  1295. this.date = DPGlobal.parseDate(date, this.format, this.language, this.formatType, this.timezone);
  1296. if (fromArgs) this.setValue();
  1297. if (this.date < this.startDate) {
  1298. this.viewDate = new Date(this.startDate);
  1299. } else if (this.date > this.endDate) {
  1300. this.viewDate = new Date(this.endDate);
  1301. } else {
  1302. this.viewDate = new Date(this.date);
  1303. }
  1304. this.fill();
  1305. },
  1306. fillDow: function () {
  1307. var dowCnt = this.weekStart,
  1308. html = '<tr>';
  1309. while (dowCnt < this.weekStart + 7) {
  1310. html += '<th class="dow">' + dates[this.language].daysMin[(dowCnt++) % 7] + '</th>';
  1311. }
  1312. html += '</tr>';
  1313. this.picker.find('.datetimepicker-days thead').append(html);
  1314. },
  1315. fillMonths: function () {
  1316. var html = '';
  1317. var d = new Date(this.viewDate);
  1318. for (var i = 0; i < 12; i++) {
  1319. d.setUTCMonth(i);
  1320. var classes = this.onRenderMonth(d);
  1321. html += '<span class="' + classes.join(' ') + '">' + dates[this.language].monthsShort[i] + '</span>';
  1322. }
  1323. this.picker.find('.datetimepicker-months td').html(html);
  1324. },
  1325. fill: function () {
  1326. if (!this.date || !this.viewDate) {
  1327. return;
  1328. }
  1329. var d = new Date(this.viewDate),
  1330. year = d.getUTCFullYear(),
  1331. month = d.getUTCMonth(),
  1332. dayMonth = d.getUTCDate(),
  1333. hours = d.getUTCHours(),
  1334. startYear = this.startDate.getUTCFullYear(),
  1335. startMonth = this.startDate.getUTCMonth(),
  1336. endYear = this.endDate.getUTCFullYear(),
  1337. endMonth = this.endDate.getUTCMonth() + 1,
  1338. currentDate = (new UTCDate(this.date.getUTCFullYear(), this.date.getUTCMonth(), this.date.getUTCDate())).valueOf(),
  1339. today = new Date();
  1340. this.setTitle('.datetimepicker-days', dates[this.language].months[month] + ' ' + year)
  1341. if (this.formatViewType === 'time') {
  1342. var formatted = this.getFormattedDate();
  1343. this.setTitle('.datetimepicker-hours', formatted);
  1344. this.setTitle('.datetimepicker-minutes', formatted);
  1345. } else {
  1346. this.setTitle('.datetimepicker-hours', dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);
  1347. this.setTitle('.datetimepicker-minutes', dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);
  1348. }
  1349. this.picker.find('tfoot th.today')
  1350. .text(dates[this.language].today || dates['en'].today)
  1351. .toggle(this.todayBtn !== false);
  1352. this.picker.find('tfoot th.clear')
  1353. .text(dates[this.language].clear || dates['en'].clear)
  1354. .toggle(this.clearBtn !== false);
  1355. this.updateNavArrows();
  1356. this.fillMonths();
  1357. var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0),
  1358. day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
  1359. prevMonth.setUTCDate(day);
  1360. prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7);
  1361. var nextMonth = new Date(prevMonth);
  1362. nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
  1363. nextMonth = nextMonth.valueOf();
  1364. var html = [];
  1365. var classes;
  1366. while (prevMonth.valueOf() < nextMonth) {
  1367. if (prevMonth.getUTCDay() === this.weekStart) {
  1368. html.push('<tr>');
  1369. }
  1370. classes = this.onRenderDay(prevMonth);
  1371. if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() === year && prevMonth.getUTCMonth() < month)) {
  1372. classes.push('old');
  1373. } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() === year && prevMonth.getUTCMonth() > month)) {
  1374. classes.push('new');
  1375. }
  1376. // Compare internal UTC date with local today, not UTC today
  1377. if (this.todayHighlight &&
  1378. prevMonth.getUTCFullYear() === today.getFullYear() &&
  1379. prevMonth.getUTCMonth() === today.getMonth() &&
  1380. prevMonth.getUTCDate() === today.getDate()) {
  1381. classes.push('today');
  1382. }
  1383. if (prevMonth.valueOf() === currentDate) {
  1384. classes.push('active');
  1385. }
  1386. if ((prevMonth.valueOf() + 86400000) <= this.startDate || prevMonth.valueOf() > this.endDate ||
  1387. $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1 ||
  1388. $.inArray(prevMonth.toDateString(), this.datesDisabled) !== -1) {
  1389. classes.push('disabled');
  1390. }
  1391. html.push('<td class="' + classes.join(' ') + '">' + prevMonth.getUTCDate() + '</td>');
  1392. if (prevMonth.getUTCDay() === this.weekEnd) {
  1393. html.push('</tr>');
  1394. }
  1395. prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
  1396. }
  1397. this.picker.find('.datetimepicker-days tbody').empty().append(html.join(''));
  1398. html = [];
  1399. var txt = '', meridian = '', meridianOld = '';
  1400. var hoursDisabled = this.hoursDisabled || [];
  1401. d = new Date(this.viewDate)
  1402. for (var i = 0; i < 24; i++) {
  1403. d.setUTCHours(i);
  1404. classes = this.onRenderHour(d);
  1405. if (hoursDisabled.indexOf(i) !== -1) {
  1406. classes.push('disabled');
  1407. }
  1408. var actual = UTCDate(year, month, dayMonth, i);
  1409. // We want the previous hour for the startDate
  1410. if ((actual.valueOf() + 3600000) <= this.startDate || actual.valueOf() > this.endDate) {
  1411. classes.push('disabled');
  1412. } else if (hours === i) {
  1413. classes.push('active');
  1414. }
  1415. if (this.showMeridian && dates[this.language].meridiem.length === 2) {
  1416. meridian = (i < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]);
  1417. if (meridian !== meridianOld) {
  1418. if (meridianOld !== '') {
  1419. html.push('</fieldset>');
  1420. }
  1421. html.push('<fieldset class="hour"><legend>' + meridian.toUpperCase() + '</legend>');
  1422. }
  1423. meridianOld = meridian;
  1424. txt = (i % 12 ? i % 12 : 12);
  1425. if (i < 12) {
  1426. classes.push('hour_am');
  1427. } else {
  1428. classes.push('hour_pm');
  1429. }
  1430. html.push('<span class="' + classes.join(' ') + '">' + txt + '</span>');
  1431. if (i === 23) {
  1432. html.push('</fieldset>');
  1433. }
  1434. } else {
  1435. txt = i + ':00';
  1436. html.push('<span class="' + classes.join(' ') + '">' + txt + '</span>');
  1437. }
  1438. }
  1439. this.picker.find('.datetimepicker-hours td').html(html.join(''));
  1440. html = [];
  1441. txt = '';
  1442. meridian = '';
  1443. meridianOld = '';
  1444. var minutesDisabled = this.minutesDisabled || [];
  1445. d = new Date(this.viewDate);
  1446. for (var i = 0; i < 60; i += this.minuteStep) {
  1447. if (minutesDisabled.indexOf(i) !== -1) continue;
  1448. d.setUTCMinutes(i);
  1449. d.setUTCSeconds(0);
  1450. classes = this.onRenderMinute(d);
  1451. if (this.showMeridian && dates[this.language].meridiem.length === 2) {
  1452. meridian = (hours < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]);
  1453. if (meridian !== meridianOld) {
  1454. if (meridianOld !== '') {
  1455. html.push('</fieldset>');
  1456. }
  1457. html.push('<fieldset class="minute"><legend>' + meridian.toUpperCase() + '</legend>');
  1458. }
  1459. meridianOld = meridian;
  1460. txt = (hours % 12 ? hours % 12 : 12);
  1461. html.push('<span class="' + classes.join(' ') + '">' + txt + ':' + (i < 10 ? '0' + i : i) + '</span>');
  1462. if (i === 59) {
  1463. html.push('</fieldset>');
  1464. }
  1465. } else {
  1466. txt = i + ':00';
  1467. html.push('<span class="' + classes.join(' ') + '">' + hours + ':' + (i < 10 ? '0' + i : i) + '</span>');
  1468. }
  1469. }
  1470. this.picker.find('.datetimepicker-minutes td').html(html.join(''));
  1471. var currentYear = this.date.getUTCFullYear();
  1472. var months = this.setTitle('.datetimepicker-months', year)
  1473. .end()
  1474. .find('.month').removeClass('active');
  1475. if (currentYear === year) {
  1476. // getUTCMonths() returns 0 based, and we need to select the next one
  1477. // To cater bootstrap 2 we don't need to select the next one
  1478. months.eq(this.date.getUTCMonth()).addClass('active');
  1479. }
  1480. if (year < startYear || year > endYear) {
  1481. months.addClass('disabled');
  1482. }
  1483. if (year === startYear) {
  1484. months.slice(0, startMonth).addClass('disabled');
  1485. }
  1486. if (year === endYear) {
  1487. months.slice(endMonth).addClass('disabled');
  1488. }
  1489. html = '';
  1490. year = parseInt(year / 10, 10) * 10;
  1491. var yearCont = this.setTitle('.datetimepicker-years', year + '-' + (year + 9))
  1492. .end()
  1493. .find('td');
  1494. year -= 1;
  1495. d = new Date(this.viewDate);
  1496. for (var i = -1; i < 11; i++) {
  1497. d.setUTCFullYear(year);
  1498. classes = this.onRenderYear(d);
  1499. if (i === -1 || i === 10) {
  1500. classes.push(old);
  1501. }
  1502. html += '<span class="' + classes.join(' ') + '">' + year + '</span>';
  1503. year += 1;
  1504. }
  1505. yearCont.html(html);
  1506. this.place();
  1507. },
  1508. updateNavArrows: function () {
  1509. var d = new Date(this.viewDate),
  1510. year = d.getUTCFullYear(),
  1511. month = d.getUTCMonth(),
  1512. day = d.getUTCDate(),
  1513. hour = d.getUTCHours();
  1514. switch (this.viewMode) {
  1515. case 0:
  1516. if (year <= this.startDate.getUTCFullYear()
  1517. && month <= this.startDate.getUTCMonth()
  1518. && day <= this.startDate.getUTCDate()
  1519. && hour <= this.startDate.getUTCHours()) {
  1520. this.picker.find('.prev').css({visibility: 'hidden'});
  1521. } else {
  1522. this.picker.find('.prev').css({visibility: 'visible'});
  1523. }
  1524. if (year >= this.endDate.getUTCFullYear()
  1525. && month >= this.endDate.getUTCMonth()
  1526. && day >= this.endDate.getUTCDate()
  1527. && hour >= this.endDate.getUTCHours()) {
  1528. this.picker.find('.next').css({visibility: 'hidden'});
  1529. } else {
  1530. this.picker.find('.next').css({visibility: 'visible'});
  1531. }
  1532. break;
  1533. case 1:
  1534. if (year <= this.startDate.getUTCFullYear()
  1535. && month <= this.startDate.getUTCMonth()
  1536. && day <= this.startDate.getUTCDate()) {
  1537. this.picker.find('.prev').css({visibility: 'hidden'});
  1538. } else {
  1539. this.picker.find('.prev').css({visibility: 'visible'});
  1540. }
  1541. if (year >= this.endDate.getUTCFullYear()
  1542. && month >= this.endDate.getUTCMonth()
  1543. && day >= this.endDate.getUTCDate()) {
  1544. this.picker.find('.next').css({visibility: 'hidden'});
  1545. } else {
  1546. this.picker.find('.next').css({visibility: 'visible'});
  1547. }
  1548. break;
  1549. case 2:
  1550. if (year <= this.startDate.getUTCFullYear()
  1551. && month <= this.startDate.getUTCMonth()) {
  1552. this.picker.find('.prev').css({visibility: 'hidden'});
  1553. } else {
  1554. this.picker.find('.prev').css({visibility: 'visible'});
  1555. }
  1556. if (year >= this.endDate.getUTCFullYear()
  1557. && month >= this.endDate.getUTCMonth()) {
  1558. this.picker.find('.next').css({visibility: 'hidden'});
  1559. } else {
  1560. this.picker.find('.next').css({visibility: 'visible'});
  1561. }
  1562. break;
  1563. case 3:
  1564. case 4:
  1565. if (year <= this.startDate.getUTCFullYear()) {
  1566. this.picker.find('.prev').css({visibility: 'hidden'});
  1567. } else {
  1568. this.picker.find('.prev').css({visibility: 'visible'});
  1569. }
  1570. if (year >= this.endDate.getUTCFullYear()) {
  1571. this.picker.find('.next').css({visibility: 'hidden'});
  1572. } else {
  1573. this.picker.find('.next').css({visibility: 'visible'});
  1574. }
  1575. break;
  1576. }
  1577. },
  1578. mousewheel: function (e) {
  1579. e.preventDefault();
  1580. e.stopPropagation();
  1581. if (this.wheelPause) {
  1582. return;
  1583. }
  1584. this.wheelPause = true;
  1585. var originalEvent = e.originalEvent;
  1586. var delta = originalEvent.wheelDelta;
  1587. var mode = delta > 0 ? 1 : (delta === 0) ? 0 : -1;
  1588. if (this.wheelViewModeNavigationInverseDirection) {
  1589. mode = -mode;
  1590. }
  1591. this.showMode(mode);
  1592. setTimeout($.proxy(function () {
  1593. this.wheelPause = false
  1594. }, this), this.wheelViewModeNavigationDelay);
  1595. },
  1596. click: function (e) {
  1597. e.stopPropagation();
  1598. e.preventDefault();
  1599. var target = $(e.target).closest('span, td, th, legend');
  1600. if (target.is('.' + this.icontype)) {
  1601. target = $(target).parent().closest('span, td, th, legend');
  1602. }
  1603. if (target.length === 1) {
  1604. if (target.is('.disabled')) {
  1605. this.element.trigger({
  1606. type: 'outOfRange',
  1607. date: this.viewDate,
  1608. startDate: this.startDate,
  1609. endDate: this.endDate
  1610. });
  1611. return;
  1612. }
  1613. switch (target[0].nodeName.toLowerCase()) {
  1614. case 'th':
  1615. switch (target[0].className) {
  1616. case 'switch':
  1617. this.showMode(1);
  1618. break;
  1619. case 'prev':
  1620. case 'next':
  1621. var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
  1622. switch (this.viewMode) {
  1623. case 0:
  1624. this.viewDate = this.moveHour(this.viewDate, dir);
  1625. break;
  1626. case 1:
  1627. this.viewDate = this.moveDate(this.viewDate, dir);
  1628. break;
  1629. case 2:
  1630. this.viewDate = this.moveMonth(this.viewDate, dir);
  1631. break;
  1632. case 3:
  1633. case 4:
  1634. this.viewDate = this.moveYear(this.viewDate, dir);
  1635. break;
  1636. }
  1637. this.fill();
  1638. this.element.trigger({
  1639. type: target[0].className + ':' + this.convertViewModeText(this.viewMode),
  1640. date: this.viewDate,
  1641. startDate: this.startDate,
  1642. endDate: this.endDate
  1643. });
  1644. break;
  1645. case 'clear':
  1646. this.reset();
  1647. if (this.autoclose) {
  1648. this.hide();
  1649. }
  1650. break;
  1651. case 'today':
  1652. var date = new Date();
  1653. date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0);
  1654. // Respect startDate and endDate.
  1655. if (date < this.startDate) date = this.startDate;
  1656. else if (date > this.endDate) date = this.endDate;
  1657. this.viewMode = this.startViewMode;
  1658. this.showMode(0);
  1659. this._setDate(date);
  1660. this.fill();
  1661. if (this.autoclose) {
  1662. this.hide();
  1663. }
  1664. break;
  1665. }
  1666. break;
  1667. case 'span':
  1668. if (!target.is('.disabled')) {
  1669. var year = this.viewDate.getUTCFullYear(),
  1670. month = this.viewDate.getUTCMonth(),
  1671. day = this.viewDate.getUTCDate(),
  1672. hours = this.viewDate.getUTCHours(),
  1673. minutes = this.viewDate.getUTCMinutes(),
  1674. seconds = this.viewDate.getUTCSeconds();
  1675. if (target.is('.month')) {
  1676. this.viewDate.setUTCDate(1);
  1677. month = target.parent().find('span').index(target);
  1678. day = this.viewDate.getUTCDate();
  1679. this.viewDate.setUTCMonth(month);
  1680. this.element.trigger({
  1681. type: 'changeMonth',
  1682. date: this.viewDate
  1683. });
  1684. if (this.viewSelect >= 3) {
  1685. this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
  1686. }
  1687. } else if (target.is('.year')) {
  1688. this.viewDate.setUTCDate(1);
  1689. year = parseInt(target.text(), 10) || 0;
  1690. this.viewDate.setUTCFullYear(year);
  1691. this.element.trigger({
  1692. type: 'changeYear',
  1693. date: this.viewDate
  1694. });
  1695. if (this.viewSelect >= 4) {
  1696. this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
  1697. }
  1698. } else if (target.is('.hour')) {
  1699. hours = parseInt(target.text(), 10) || 0;
  1700. if (target.hasClass('hour_am') || target.hasClass('hour_pm')) {
  1701. if (hours === 12 && target.hasClass('hour_am')) {
  1702. hours = 0;
  1703. } else if (hours !== 12 && target.hasClass('hour_pm')) {
  1704. hours += 12;
  1705. }
  1706. }
  1707. this.viewDate.setUTCHours(hours);
  1708. this.element.trigger({
  1709. type: 'changeHour',
  1710. date: this.viewDate
  1711. });
  1712. if (this.viewSelect >= 1) {
  1713. this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
  1714. }
  1715. } else if (target.is('.minute')) {
  1716. minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0;
  1717. this.viewDate.setUTCMinutes(minutes);
  1718. this.element.trigger({
  1719. type: 'changeMinute',
  1720. date: this.viewDate
  1721. });
  1722. if (this.viewSelect >= 0) {
  1723. this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
  1724. }
  1725. }
  1726. if (this.viewMode !== 0) {
  1727. var oldViewMode = this.viewMode;
  1728. this.showMode(-1);
  1729. this.fill();
  1730. if (oldViewMode === this.viewMode && this.autoclose) {
  1731. this.hide();
  1732. }
  1733. } else {
  1734. this.fill();
  1735. if (this.autoclose) {
  1736. this.hide();
  1737. }
  1738. }
  1739. }
  1740. break;
  1741. case 'td':
  1742. if (target.is('.day') && !target.is('.disabled')) {
  1743. var day = parseInt(target.text(), 10) || 1;
  1744. var year = this.viewDate.getUTCFullYear(),
  1745. month = this.viewDate.getUTCMonth(),
  1746. hours = this.viewDate.getUTCHours(),
  1747. minutes = this.viewDate.getUTCMinutes(),
  1748. seconds = this.viewDate.getUTCSeconds();
  1749. if (target.is('.old')) {
  1750. if (month === 0) {
  1751. month = 11;
  1752. year -= 1;
  1753. } else {
  1754. month -= 1;
  1755. }
  1756. } else if (target.is('.new')) {
  1757. if (month === 11) {
  1758. month = 0;
  1759. year += 1;
  1760. } else {
  1761. month += 1;
  1762. }
  1763. }
  1764. this.viewDate.setUTCFullYear(year);
  1765. this.viewDate.setUTCMonth(month, day);
  1766. this.element.trigger({
  1767. type: 'changeDay',
  1768. date: this.viewDate
  1769. });
  1770. if (this.viewSelect >= 2) {
  1771. this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
  1772. }
  1773. }
  1774. var oldViewMode = this.viewMode;
  1775. this.showMode(-1);
  1776. this.fill();
  1777. if (oldViewMode === this.viewMode && this.autoclose) {
  1778. this.hide();
  1779. }
  1780. break;
  1781. }
  1782. }
  1783. },
  1784. _setDate: function (date, which) {
  1785. if (!which || which === 'date')
  1786. this.date = date;
  1787. if (!which || which === 'view')
  1788. this.viewDate = date;
  1789. this.fill();
  1790. this.setValue();
  1791. var element;
  1792. if (this.isInput) {
  1793. element = this.element;
  1794. } else if (this.component) {
  1795. element = this.element.find('input');
  1796. }
  1797. if (element) {
  1798. element.change();
  1799. }
  1800. this.element.trigger({
  1801. type: 'changeDate',
  1802. date: this.getDate()
  1803. });
  1804. if(date === null)
  1805. this.date = this.viewDate;
  1806. },
  1807. moveMinute: function (date, dir) {
  1808. if (!dir) return date;
  1809. var new_date = new Date(date.valueOf());
  1810. //dir = dir > 0 ? 1 : -1;
  1811. new_date.setUTCMinutes(new_date.getUTCMinutes() + (dir * this.minuteStep));
  1812. return new_date;
  1813. },
  1814. moveHour: function (date, dir) {
  1815. if (!dir) return date;
  1816. var new_date = new Date(date.valueOf());
  1817. //dir = dir > 0 ? 1 : -1;
  1818. new_date.setUTCHours(new_date.getUTCHours() + dir);
  1819. return new_date;
  1820. },
  1821. moveDate: function (date, dir) {
  1822. if (!dir) return date;
  1823. var new_date = new Date(date.valueOf());
  1824. //dir = dir > 0 ? 1 : -1;
  1825. new_date.setUTCDate(new_date.getUTCDate() + dir);
  1826. return new_date;
  1827. },
  1828. moveMonth: function (date, dir) {
  1829. if (!dir) return date;
  1830. var new_date = new Date(date.valueOf()),
  1831. day = new_date.getUTCDate(),
  1832. month = new_date.getUTCMonth(),
  1833. mag = Math.abs(dir),
  1834. new_month, test;
  1835. dir = dir > 0 ? 1 : -1;
  1836. if (mag === 1) {
  1837. test = dir === -1
  1838. // If going back one month, make sure month is not current month
  1839. // (eg, Mar 31 -> Feb 31 === Feb 28, not Mar 02)
  1840. ? function () {
  1841. return new_date.getUTCMonth() === month;
  1842. }
  1843. // If going forward one month, make sure month is as expected
  1844. // (eg, Jan 31 -> Feb 31 === Feb 28, not Mar 02)
  1845. : function () {
  1846. return new_date.getUTCMonth() !== new_month;
  1847. };
  1848. new_month = month + dir;
  1849. new_date.setUTCMonth(new_month);
  1850. // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
  1851. if (new_month < 0 || new_month > 11)
  1852. new_month = (new_month + 12) % 12;
  1853. } else {
  1854. // For magnitudes >1, move one month at a time...
  1855. for (var i = 0; i < mag; i++)
  1856. // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
  1857. new_date = this.moveMonth(new_date, dir);
  1858. // ...then reset the day, keeping it in the new month
  1859. new_month = new_date.getUTCMonth();
  1860. new_date.setUTCDate(day);
  1861. test = function () {
  1862. return new_month !== new_date.getUTCMonth();
  1863. };
  1864. }
  1865. // Common date-resetting loop -- if date is beyond end of month, make it
  1866. // end of month
  1867. while (test()) {
  1868. new_date.setUTCDate(--day);
  1869. new_date.setUTCMonth(new_month);
  1870. }
  1871. return new_date;
  1872. },
  1873. moveYear: function (date, dir) {
  1874. return this.moveMonth(date, dir * 12);
  1875. },
  1876. dateWithinRange: function (date) {
  1877. return date >= this.startDate && date <= this.endDate;
  1878. },
  1879. keydown: function (e) {
  1880. if (this.picker.is(':not(:visible)')) {
  1881. if (e.keyCode === 27) // allow escape to hide and re-show picker
  1882. this.show();
  1883. return;
  1884. }
  1885. var dateChanged = false,
  1886. dir, newDate, newViewDate;
  1887. switch (e.keyCode) {
  1888. case 27: // escape
  1889. this.hide();
  1890. e.preventDefault();
  1891. break;
  1892. case 37: // left
  1893. case 39: // right
  1894. if (!this.keyboardNavigation) break;
  1895. dir = e.keyCode === 37 ? -1 : 1;
  1896. var viewMode = this.viewMode;
  1897. if (e.ctrlKey) {
  1898. viewMode += 2;
  1899. } else if (e.shiftKey) {
  1900. viewMode += 1;
  1901. }
  1902. if (viewMode === 4) {
  1903. newDate = this.moveYear(this.date, dir);
  1904. newViewDate = this.moveYear(this.viewDate, dir);
  1905. } else if (viewMode === 3) {
  1906. newDate = this.moveMonth(this.date, dir);
  1907. newViewDate = this.moveMonth(this.viewDate, dir);
  1908. } else if (viewMode === 2) {
  1909. newDate = this.moveDate(this.date, dir);
  1910. newViewDate = this.moveDate(this.viewDate, dir);
  1911. } else if (viewMode === 1) {
  1912. newDate = this.moveHour(this.date, dir);
  1913. newViewDate = this.moveHour(this.viewDate, dir);
  1914. } else if (viewMode === 0) {
  1915. newDate = this.moveMinute(this.date, dir);
  1916. newViewDate = this.moveMinute(this.viewDate, dir);
  1917. }
  1918. if (this.dateWithinRange(newDate)) {
  1919. this.date = newDate;
  1920. this.viewDate = newViewDate;
  1921. this.setValue();
  1922. this.update();
  1923. e.preventDefault();
  1924. dateChanged = true;
  1925. }
  1926. break;
  1927. case 38: // up
  1928. case 40: // down
  1929. if (!this.keyboardNavigation) break;
  1930. dir = e.keyCode === 38 ? -1 : 1;
  1931. viewMode = this.viewMode;
  1932. if (e.ctrlKey) {
  1933. viewMode += 2;
  1934. } else if (e.shiftKey) {
  1935. viewMode += 1;
  1936. }
  1937. if (viewMode === 4) {
  1938. newDate = this.moveYear(this.date, dir);
  1939. newViewDate = this.moveYear(this.viewDate, dir);
  1940. } else if (viewMode === 3) {
  1941. newDate = this.moveMonth(this.date, dir);
  1942. newViewDate = this.moveMonth(this.viewDate, dir);
  1943. } else if (viewMode === 2) {
  1944. newDate = this.moveDate(this.date, dir * 7);
  1945. newViewDate = this.moveDate(this.viewDate, dir * 7);
  1946. } else if (viewMode === 1) {
  1947. if (this.showMeridian) {
  1948. newDate = this.moveHour(this.date, dir * 6);
  1949. newViewDate = this.moveHour(this.viewDate, dir * 6);
  1950. } else {
  1951. newDate = this.moveHour(this.date, dir * 4);
  1952. newViewDate = this.moveHour(this.viewDate, dir * 4);
  1953. }
  1954. } else if (viewMode === 0) {
  1955. newDate = this.moveMinute(this.date, dir * 4);
  1956. newViewDate = this.moveMinute(this.viewDate, dir * 4);
  1957. }
  1958. if (this.dateWithinRange(newDate)) {
  1959. this.date = newDate;
  1960. this.viewDate = newViewDate;
  1961. this.setValue();
  1962. this.update();
  1963. e.preventDefault();
  1964. dateChanged = true;
  1965. }
  1966. break;
  1967. case 13: // enter
  1968. if (this.viewMode !== 0) {
  1969. var oldViewMode = this.viewMode;
  1970. this.showMode(-1);
  1971. this.fill();
  1972. if (oldViewMode === this.viewMode && this.autoclose) {
  1973. this.hide();
  1974. }
  1975. } else {
  1976. this.fill();
  1977. if (this.autoclose) {
  1978. this.hide();
  1979. }
  1980. }
  1981. e.preventDefault();
  1982. break;
  1983. case 9: // tab
  1984. this.hide();
  1985. break;
  1986. }
  1987. if (dateChanged) {
  1988. var element;
  1989. if (this.isInput) {
  1990. element = this.element;
  1991. } else if (this.component) {
  1992. element = this.element.find('input');
  1993. }
  1994. if (element) {
  1995. element.change();
  1996. }
  1997. this.element.trigger({
  1998. type: 'changeDate',
  1999. date: this.getDate()
  2000. });
  2001. }
  2002. },
  2003. showMode: function (dir) {
  2004. if (dir) {
  2005. var newViewMode = Math.max(0, Math.min(DPGlobal.modes.length - 1, this.viewMode + dir));
  2006. if (newViewMode >= this.minView && newViewMode <= this.maxView) {
  2007. this.element.trigger({
  2008. type: 'changeMode',
  2009. date: this.viewDate,
  2010. oldViewMode: this.viewMode,
  2011. newViewMode: newViewMode
  2012. });
  2013. this.viewMode = newViewMode;
  2014. }
  2015. }
  2016. /*
  2017. vitalets: fixing bug of very special conditions:
  2018. jquery 1.7.1 + webkit + show inline datetimepicker in bootstrap popover.
  2019. Method show() does not set display css correctly and datetimepicker is not shown.
  2020. Changed to .css('display', 'block') solve the problem.
  2021. See https://github.com/vitalets/x-editable/issues/37
  2022. In jquery 1.7.2+ everything works fine.
  2023. */
  2024. //this.picker.find('>div').hide().filter('.datetimepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
  2025. this.picker.find('>div').hide().filter('.datetimepicker-' + DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
  2026. this.updateNavArrows();
  2027. },
  2028. reset: function () {
  2029. this._setDate(null, 'date');
  2030. },
  2031. convertViewModeText: function (viewMode) {
  2032. switch (viewMode) {
  2033. case 4:
  2034. return 'decade';
  2035. case 3:
  2036. return 'year';
  2037. case 2:
  2038. return 'month';
  2039. case 1:
  2040. return 'day';
  2041. case 0:
  2042. return 'hour';
  2043. }
  2044. }
  2045. };
  2046. var old = $.fn.datetimepicker;
  2047. $.fn.datetimepicker = function (option) {
  2048. var args = Array.apply(null, arguments);
  2049. args.shift();
  2050. var internal_return;
  2051. this.each(function () {
  2052. var $this = $(this),
  2053. data = $this.data('datetimepicker'),
  2054. options = typeof option === 'object' && option;
  2055. if (!data) {
  2056. $this.data('datetimepicker', (data = new Datetimepicker(this, $.extend({}, $.fn.datetimepicker.defaults, options))));
  2057. }
  2058. if (typeof option === 'string' && typeof data[option] === 'function') {
  2059. internal_return = data[option].apply(data, args);
  2060. if (internal_return !== undefined) {
  2061. return false;
  2062. }
  2063. }
  2064. });
  2065. if (internal_return !== undefined)
  2066. return internal_return;
  2067. else
  2068. return this;
  2069. };
  2070. $.fn.datetimepicker.defaults = {
  2071. };
  2072. $.fn.datetimepicker.Constructor = Datetimepicker;
  2073. var dates = $.fn.datetimepicker.dates = {
  2074. en: {
  2075. days: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
  2076. daysShort: ['日', '一', '二', '三', '四', '五', '六', '日'],
  2077. daysMin: ['日', '一', '二', '三', '四', '五', '六', '日'],
  2078. months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
  2079. monthsShort: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
  2080. meridiem: ['am', 'pm'],
  2081. suffix: ['st', 'nd', 'rd', 'th'],
  2082. today: 'Today',
  2083. clear: 'Clear'
  2084. }
  2085. };
  2086. var DPGlobal = {
  2087. modes: [
  2088. {
  2089. clsName: 'minutes',
  2090. navFnc: 'Hours',
  2091. navStep: 1
  2092. },
  2093. {
  2094. clsName: 'hours',
  2095. navFnc: 'Date',
  2096. navStep: 1
  2097. },
  2098. {
  2099. clsName: 'days',
  2100. navFnc: 'Month',
  2101. navStep: 1
  2102. },
  2103. {
  2104. clsName: 'months',
  2105. navFnc: 'FullYear',
  2106. navStep: 1
  2107. },
  2108. {
  2109. clsName: 'years',
  2110. navFnc: 'FullYear',
  2111. navStep: 10
  2112. }
  2113. ],
  2114. isLeapYear: function (year) {
  2115. return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
  2116. },
  2117. getDaysInMonth: function (year, month) {
  2118. return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
  2119. },
  2120. getDefaultFormat: function (type, field) {
  2121. if (type === 'standard') {
  2122. if (field === 'input')
  2123. return 'yyyy-mm-dd hh:ii';
  2124. else
  2125. return 'yyyy-mm-dd hh:ii:ss';
  2126. } else if (type === 'php') {
  2127. if (field === 'input')
  2128. return 'Y-m-d H:i';
  2129. else
  2130. return 'Y-m-d H:i:s';
  2131. } else {
  2132. throw new Error('Invalid format type.');
  2133. }
  2134. },
  2135. validParts: function (type) {
  2136. if (type === 'standard') {
  2137. return /t|hh?|HH?|p|P|z|Z|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g;
  2138. } else if (type === 'php') {
  2139. return /[dDjlNwzFmMnStyYaABgGhHis]/g;
  2140. } else {
  2141. throw new Error('Invalid format type.');
  2142. }
  2143. },
  2144. nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,
  2145. parseFormat: function (format, type) {
  2146. // IE treats \0 as a string end in inputs (truncating the value),
  2147. // so it's a bad format delimiter, anyway
  2148. var separators = format.replace(this.validParts(type), '\0').split('\0'),
  2149. parts = format.match(this.validParts(type));
  2150. if (!separators || !separators.length || !parts || parts.length === 0) {
  2151. throw new Error('Invalid date format.');
  2152. }
  2153. return {separators: separators, parts: parts};
  2154. },
  2155. parseDate: function (date, format, language, type, timezone) {
  2156. if (date instanceof Date) {
  2157. var dateUTC = new Date(date.valueOf() - date.getTimezoneOffset() * 60000);
  2158. dateUTC.setMilliseconds(0);
  2159. return dateUTC;
  2160. }
  2161. if (/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(date)) {
  2162. format = this.parseFormat('yyyy-mm-dd', type);
  2163. }
  2164. if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(date)) {
  2165. format = this.parseFormat('yyyy-mm-dd hh:ii', type);
  2166. }
  2167. if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(date)) {
  2168. format = this.parseFormat('yyyy-mm-dd hh:ii:ss', type);
  2169. }
  2170. if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) {
  2171. var part_re = /([-+]\d+)([dmwy])/,
  2172. parts = date.match(/([-+]\d+)([dmwy])/g),
  2173. part, dir;
  2174. date = new Date();
  2175. for (var i = 0; i < parts.length; i++) {
  2176. part = part_re.exec(parts[i]);
  2177. dir = parseInt(part[1]);
  2178. switch (part[2]) {
  2179. case 'd':
  2180. date.setUTCDate(date.getUTCDate() + dir);
  2181. break;
  2182. case 'm':
  2183. date = Datetimepicker.prototype.moveMonth.call(Datetimepicker.prototype, date, dir);
  2184. break;
  2185. case 'w':
  2186. date.setUTCDate(date.getUTCDate() + dir * 7);
  2187. break;
  2188. case 'y':
  2189. date = Datetimepicker.prototype.moveYear.call(Datetimepicker.prototype, date, dir);
  2190. break;
  2191. }
  2192. }
  2193. return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), 0);
  2194. }
  2195. var parts = date && date.toString().match(this.nonpunctuation) || [],
  2196. date = new Date(0, 0, 0, 0, 0, 0, 0),
  2197. parsed = {},
  2198. setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'D', 'DD', 'd', 'dd', 'H', 'HH', 'p', 'P', 'z', 'Z'],
  2199. setters_map = {
  2200. hh: function (d, v) {
  2201. return d.setUTCHours(v);
  2202. },
  2203. h: function (d, v) {
  2204. return d.setUTCHours(v);
  2205. },
  2206. HH: function (d, v) {
  2207. return d.setUTCHours(v === 12 ? 0 : v);
  2208. },
  2209. H: function (d, v) {
  2210. return d.setUTCHours(v === 12 ? 0 : v);
  2211. },
  2212. ii: function (d, v) {
  2213. return d.setUTCMinutes(v);
  2214. },
  2215. i: function (d, v) {
  2216. return d.setUTCMinutes(v);
  2217. },
  2218. ss: function (d, v) {
  2219. return d.setUTCSeconds(v);
  2220. },
  2221. s: function (d, v) {
  2222. return d.setUTCSeconds(v);
  2223. },
  2224. yyyy: function (d, v) {
  2225. return d.setUTCFullYear(v);
  2226. },
  2227. yy: function (d, v) {
  2228. return d.setUTCFullYear(2000 + v);
  2229. },
  2230. m: function (d, v) {
  2231. v -= 1;
  2232. while (v < 0) v += 12;
  2233. v %= 12;
  2234. d.setUTCMonth(v);
  2235. while (d.getUTCMonth() !== v)
  2236. if (isNaN(d.getUTCMonth()))
  2237. return d;
  2238. else
  2239. d.setUTCDate(d.getUTCDate() - 1);
  2240. return d;
  2241. },
  2242. d: function (d, v) {
  2243. return d.setUTCDate(v);
  2244. },
  2245. p: function (d, v) {
  2246. return d.setUTCHours(v === 1 ? d.getUTCHours() + 12 : d.getUTCHours());
  2247. },
  2248. z: function () {
  2249. return timezone
  2250. }
  2251. },
  2252. val, filtered, part;
  2253. setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
  2254. setters_map['dd'] = setters_map['d'];
  2255. setters_map['P'] = setters_map['p'];
  2256. setters_map['Z'] = setters_map['z'];
  2257. date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
  2258. if (parts.length === format.parts.length) {
  2259. for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
  2260. val = parseInt(parts[i], 10);
  2261. part = format.parts[i];
  2262. if (isNaN(val)) {
  2263. switch (part) {
  2264. case 'MM':
  2265. filtered = $(dates[language].months).filter(function () {
  2266. var m = this.slice(0, parts[i].length),
  2267. p = parts[i].slice(0, m.length);
  2268. return m === p;
  2269. });
  2270. val = $.inArray(filtered[0], dates[language].months) + 1;
  2271. break;
  2272. case 'M':
  2273. filtered = $(dates[language].monthsShort).filter(function () {
  2274. var m = this.slice(0, parts[i].length),
  2275. p = parts[i].slice(0, m.length);
  2276. return m.toLowerCase() === p.toLowerCase();
  2277. });
  2278. val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
  2279. break;
  2280. case 'p':
  2281. case 'P':
  2282. val = $.inArray(parts[i].toLowerCase(), dates[language].meridiem);
  2283. break;
  2284. case 'z':
  2285. case 'Z':
  2286. timezone;
  2287. break;
  2288. }
  2289. }
  2290. parsed[part] = val;
  2291. }
  2292. for (var i = 0, s; i < setters_order.length; i++) {
  2293. s = setters_order[i];
  2294. if (s in parsed && !isNaN(parsed[s]))
  2295. setters_map[s](date, parsed[s])
  2296. }
  2297. }
  2298. return date;
  2299. },
  2300. formatDate: function (date, format, language, type, timezone) {
  2301. if (date === null) {
  2302. return '';
  2303. }
  2304. var val;
  2305. if (type === 'standard') {
  2306. val = {
  2307. t: date.getTime(),
  2308. // year
  2309. yy: date.getUTCFullYear().toString().substring(2),
  2310. yyyy: date.getUTCFullYear(),
  2311. // month
  2312. m: date.getUTCMonth() + 1,
  2313. M: dates[language].monthsShort[date.getUTCMonth()],
  2314. MM: dates[language].months[date.getUTCMonth()],
  2315. // day
  2316. d: date.getUTCDate(),
  2317. D: dates[language].daysShort[date.getUTCDay()],
  2318. DD: dates[language].days[date.getUTCDay()],
  2319. p: (dates[language].meridiem.length === 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),
  2320. // hour
  2321. h: date.getUTCHours(),
  2322. // minute
  2323. i: date.getUTCMinutes(),
  2324. // second
  2325. s: date.getUTCSeconds(),
  2326. // timezone
  2327. z: timezone
  2328. };
  2329. if (dates[language].meridiem.length === 2) {
  2330. val.H = (val.h % 12 === 0 ? 12 : val.h % 12);
  2331. }
  2332. else {
  2333. val.H = val.h;
  2334. }
  2335. val.HH = (val.H < 10 ? '0' : '') + val.H;
  2336. val.P = val.p.toUpperCase();
  2337. val.Z = val.z;
  2338. val.hh = (val.h < 10 ? '0' : '') + val.h;
  2339. val.ii = (val.i < 10 ? '0' : '') + val.i;
  2340. val.ss = (val.s < 10 ? '0' : '') + val.s;
  2341. val.dd = (val.d < 10 ? '0' : '') + val.d;
  2342. val.mm = (val.m < 10 ? '0' : '') + val.m;
  2343. } else if (type === 'php') {
  2344. // php format
  2345. val = {
  2346. // year
  2347. y: date.getUTCFullYear().toString().substring(2),
  2348. Y: date.getUTCFullYear(),
  2349. // month
  2350. F: dates[language].months[date.getUTCMonth()],
  2351. M: dates[language].monthsShort[date.getUTCMonth()],
  2352. n: date.getUTCMonth() + 1,
  2353. t: DPGlobal.getDaysInMonth(date.getUTCFullYear(), date.getUTCMonth()),
  2354. // day
  2355. j: date.getUTCDate(),
  2356. l: dates[language].days[date.getUTCDay()],
  2357. D: dates[language].daysShort[date.getUTCDay()],
  2358. w: date.getUTCDay(), // 0 -> 6
  2359. N: (date.getUTCDay() === 0 ? 7 : date.getUTCDay()), // 1 -> 7
  2360. S: (date.getUTCDate() % 10 <= dates[language].suffix.length ? dates[language].suffix[date.getUTCDate() % 10 - 1] : ''),
  2361. // hour
  2362. a: (dates[language].meridiem.length === 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),
  2363. g: (date.getUTCHours() % 12 === 0 ? 12 : date.getUTCHours() % 12),
  2364. G: date.getUTCHours(),
  2365. // minute
  2366. i: date.getUTCMinutes(),
  2367. // second
  2368. s: date.getUTCSeconds()
  2369. };
  2370. val.m = (val.n < 10 ? '0' : '') + val.n;
  2371. val.d = (val.j < 10 ? '0' : '') + val.j;
  2372. val.A = val.a.toString().toUpperCase();
  2373. val.h = (val.g < 10 ? '0' : '') + val.g;
  2374. val.H = (val.G < 10 ? '0' : '') + val.G;
  2375. val.i = (val.i < 10 ? '0' : '') + val.i;
  2376. val.s = (val.s < 10 ? '0' : '') + val.s;
  2377. } else {
  2378. throw new Error('Invalid format type.');
  2379. }
  2380. var date = [],
  2381. seps = $.extend([], format.separators);
  2382. for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
  2383. if (seps.length) {
  2384. date.push(seps.shift());
  2385. }
  2386. date.push(val[format.parts[i]]);
  2387. }
  2388. if (seps.length) {
  2389. date.push(seps.shift());
  2390. }
  2391. return date.join('');
  2392. },
  2393. convertViewMode: function (viewMode) {
  2394. switch (viewMode) {
  2395. case 4:
  2396. case 'decade':
  2397. viewMode = 4;
  2398. break;
  2399. case 3:
  2400. case 'year':
  2401. viewMode = 3;
  2402. break;
  2403. case 2:
  2404. case 'month':
  2405. viewMode = 2;
  2406. break;
  2407. case 1:
  2408. case 'day':
  2409. viewMode = 1;
  2410. break;
  2411. case 0:
  2412. case 'hour':
  2413. viewMode = 0;
  2414. break;
  2415. }
  2416. return viewMode;
  2417. },
  2418. headTemplate: '<thead>' +
  2419. '<tr>' +
  2420. '<th class="prev"><i class="{iconType} {leftArrow}"/></th>' +
  2421. '<th colspan="5" class="switch"></th>' +
  2422. '<th class="next"><i class="{iconType} {rightArrow}"/></th>' +
  2423. '</tr>' +
  2424. '</thead>',
  2425. headTemplateV3: '<thead>' +
  2426. '<tr>' +
  2427. '<th class="prev"><span class="{iconType} {leftArrow}"></span> </th>' +
  2428. '<th colspan="5" class="switch"></th>' +
  2429. '<th class="next"><span class="{iconType} {rightArrow}"></span> </th>' +
  2430. '</tr>' +
  2431. '</thead>',
  2432. contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
  2433. footTemplate: '<tfoot>' +
  2434. '<tr><th colspan="7" class="today"></th></tr>' +
  2435. '<tr><th colspan="7" class="clear"></th></tr>' +
  2436. '</tfoot>'
  2437. };
  2438. DPGlobal.template = '<div class="datetimepicker">' +
  2439. '<div class="datetimepicker-minutes">' +
  2440. '<table class=" table-condensed">' +
  2441. DPGlobal.headTemplate +
  2442. DPGlobal.contTemplate +
  2443. DPGlobal.footTemplate +
  2444. '</table>' +
  2445. '</div>' +
  2446. '<div class="datetimepicker-hours">' +
  2447. '<table class=" table-condensed">' +
  2448. DPGlobal.headTemplate +
  2449. DPGlobal.contTemplate +
  2450. DPGlobal.footTemplate +
  2451. '</table>' +
  2452. '</div>' +
  2453. '<div class="datetimepicker-days">' +
  2454. '<table class=" table-condensed">' +
  2455. DPGlobal.headTemplate +
  2456. '<tbody></tbody>' +
  2457. DPGlobal.footTemplate +
  2458. '</table>' +
  2459. '</div>' +
  2460. '<div class="datetimepicker-months">' +
  2461. '<table class="table-condensed">' +
  2462. DPGlobal.headTemplate +
  2463. DPGlobal.contTemplate +
  2464. DPGlobal.footTemplate +
  2465. '</table>' +
  2466. '</div>' +
  2467. '<div class="datetimepicker-years">' +
  2468. '<table class="table-condensed">' +
  2469. DPGlobal.headTemplate +
  2470. DPGlobal.contTemplate +
  2471. DPGlobal.footTemplate +
  2472. '</table>' +
  2473. '</div>' +
  2474. '</div>';
  2475. DPGlobal.templateV3 = '<div class="datetimepicker">' +
  2476. '<div class="datetimepicker-minutes">' +
  2477. '<table class=" table-condensed">' +
  2478. DPGlobal.headTemplateV3 +
  2479. DPGlobal.contTemplate +
  2480. DPGlobal.footTemplate +
  2481. '</table>' +
  2482. '</div>' +
  2483. '<div class="datetimepicker-hours">' +
  2484. '<table class=" table-condensed">' +
  2485. DPGlobal.headTemplateV3 +
  2486. DPGlobal.contTemplate +
  2487. DPGlobal.footTemplate +
  2488. '</table>' +
  2489. '</div>' +
  2490. '<div class="datetimepicker-days">' +
  2491. '<table class=" table-condensed">' +
  2492. DPGlobal.headTemplateV3 +
  2493. '<tbody></tbody>' +
  2494. DPGlobal.footTemplate +
  2495. '</table>' +
  2496. '</div>' +
  2497. '<div class="datetimepicker-months">' +
  2498. '<table class="table-condensed">' +
  2499. DPGlobal.headTemplateV3 +
  2500. DPGlobal.contTemplate +
  2501. DPGlobal.footTemplate +
  2502. '</table>' +
  2503. '</div>' +
  2504. '<div class="datetimepicker-years">' +
  2505. '<table class="table-condensed">' +
  2506. DPGlobal.headTemplateV3 +
  2507. DPGlobal.contTemplate +
  2508. DPGlobal.footTemplate +
  2509. '</table>' +
  2510. '</div>' +
  2511. '</div>';
  2512. $.fn.datetimepicker.DPGlobal = DPGlobal;
  2513. /* DATETIMEPICKER NO CONFLICT
  2514. * =================== */
  2515. $.fn.datetimepicker.noConflict = function () {
  2516. $.fn.datetimepicker = old;
  2517. return this;
  2518. };
  2519. /* DATETIMEPICKER DATA-API
  2520. * ================== */
  2521. $(document).on(
  2522. 'focus.datetimepicker.data-api click.datetimepicker.data-api',
  2523. '[data-provide="datetimepicker"]',
  2524. function (e) {
  2525. var $this = $(this);
  2526. if ($this.data('datetimepicker')) return;
  2527. e.preventDefault();
  2528. // component click requires us to explicitly show it
  2529. $this.datetimepicker('show');
  2530. }
  2531. );
  2532. $(function () {
  2533. $('[data-provide="datetimepicker-inline"]').datetimepicker();
  2534. });
  2535. }));
  2536. //弹框
  2537. //需要成功回调的弹出框
  2538. function ZZAlertInfo(info, callok) {
  2539. window.wxc.xcConfirm(info, window.wxc.xcConfirm.typeEnum.info, {
  2540. onOk: function() {
  2541. if(callok) {
  2542. callok();
  2543. }
  2544. }
  2545. });
  2546. }
  2547. //确认框(提示信息,成功回调,取消回调,关闭回调)
  2548. function ZZConfirm(info, callok, callcancel, callclose) {
  2549. window.wxc.xcConfirm(info, window.wxc.xcConfirm.typeEnum.confirm, {
  2550. onOk: function() {
  2551. if(callok) {
  2552. callok();
  2553. }
  2554. },
  2555. onCancel: function() {
  2556. if(callcancel) {
  2557. callcancel();
  2558. }
  2559. },
  2560. onClose: function() {
  2561. if(callclose) {
  2562. callclose();
  2563. }
  2564. }
  2565. })
  2566. }
  2567. //输入框(输入的信息,成功回调,关闭的回调)
  2568. function ZZInput(info, callok, callclose) {
  2569. window.wxc.xcConfirm(info, window.wxc.xcConfirm.typeEnum.input, {
  2570. onOk: function(ok) {
  2571. if(callok) {
  2572. callok(ok);
  2573. }
  2574. },
  2575. onClose: function(close) {
  2576. if(callclose) {
  2577. callclose(close);
  2578. }
  2579. }
  2580. });
  2581. }