source: branches/2.7/admin/themes/default/js/datepicker.js @ 30959

Last change on this file since 30959 was 30959, checked in by mistic100, 9 years ago

Merged revision(s) 30958 from trunk:
bug 3190: Datetime picker, can't change year on Chrome & IE11

File size: 5.5 KB
Line 
1(function($) {
2jQuery.timepicker.log = jQuery.noop; // that's ugly, but the timepicker is acting weird and throws parsing errors
3
4
5// modify DatePicker internal methods to replace year select by a numeric input
6var origGenerateMonthYearHeader = $.datepicker._generateMonthYearHeader,
7    origSelectMonthYear = $.datepicker._selectMonthYear;
8
9$.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,
10      secondary, monthNames, monthNamesShort) {
11
12  var html = origGenerateMonthYearHeader.call(this, inst, drawMonth, drawYear, minDate, maxDate,
13      secondary, monthNames, monthNamesShort);
14
15  var yearshtml = "<input type='number' class='ui-datepicker-year' data-handler='selectYear' data-event='change keyup' value='"+drawYear+"' style='width:4em;margin-left:2px;'>";
16
17  return html.replace(new RegExp('<select class=\'ui-datepicker-year\'.*</select>', 'gm'), yearshtml);
18};
19
20$.datepicker._selectMonthYear = debounce(function(id, select, period) {
21  if (period === 'M') {
22    origSelectMonthYear.call(this, id, select, period);
23  }
24  else {
25    var target = $(id),
26      inst = this._getInst(target[0]),
27      val = parseInt(select.value, 10);
28
29    if (isNaN(val)) {
30      inst['drawYear'] = '';
31    }
32    else {
33      inst['selectedYear'] = inst['drawYear'] = val;
34
35      this._notifyChange(inst);
36      this._adjustDate(target);
37
38      $('.ui-datepicker-year').focus();
39    }
40  }
41}, 500);
42
43
44// plugin definition
45jQuery.fn.pwgDatepicker = function(settings) {
46  var options = jQuery.extend(true, {
47    showTimepicker: false,
48    cancelButton: false,
49  }, settings || {});
50
51  return this.each(function() {
52    var $this = jQuery(this),
53        originalValue = $this.val(),
54        originalDate,
55        $target = jQuery('[name="'+ $this.data('datepicker') +'"]'),
56        linked = !!$target.length,
57        $start, $end;
58
59    if (linked) {
60      originalValue = $target.val();
61    }
62
63    // custom setter
64    function set(date, init) {
65      if (date === '') date = null;
66      $this.datetimepicker('setDate', date);
67
68      if ($this.data('datepicker-start') && $start) {
69        $start.datetimepicker('option', 'maxDate', date);
70      }
71      else if ($this.data('datepicker-end') && $end) {
72        if (!init) { // on init, "end" is not initialized yet (assuming "start" is before "end" in the DOM)
73          $end.datetimepicker('option', 'minDate', date);
74        }
75      }
76
77      if (!date && linked) {
78        $target.val('');
79      }
80    }
81
82    // and custom cancel button
83    if (options.cancelButton) {
84      options.beforeShow = options.onChangeMonthYear = function() {
85        setTimeout(function() {
86          var buttonPane = $this.datepicker('widget')
87              .find('.ui-datepicker-buttonpane');
88
89          if (buttonPane.find('.pwg-datepicker-cancel').length == 0) {
90            $('<button type="button">'+ options.cancelButton +'</button>')
91              .on('click', function() {
92                set(originalDate, false);
93                $this.datepicker('hide').blur();
94              })
95              .addClass('pwg-datepicker-cancel ui-state-error ui-corner-all')
96              .appendTo(buttonPane);
97          }
98        }, 1);
99      };
100    }
101
102    // init picker
103    $this.datetimepicker(jQuery.extend({
104      dateFormat: linked ? 'DD d MM yy' : 'yy-mm-dd',
105      timeFormat: 'HH:mm',
106      separator: options.showTimepicker ? ' ' : '',
107
108      altField: linked ? $target : null,
109      altFormat: 'yy-mm-dd',
110      altTimeFormat: options.showTimepicker ? 'HH:mm:ss' : '',
111
112      autoSize: true,
113      changeMonth : true,
114      changeYear: true,
115      altFieldTimeOnly: false,
116      showSecond: false,
117      alwaysSetTime: false
118    }, options));
119
120    // attach range pickers
121    if ($this.data('datepicker-start')) {
122      $start = jQuery('[data-datepicker="'+ $this.data('datepicker-start') +'"]');
123
124      $this.datetimepicker('option', 'onClose', function(date) {
125        $start.datetimepicker('option', 'maxDate', date);
126      });
127
128      $this.datetimepicker('option', 'minDate', $start.datetimepicker('getDate'));
129    }
130    else if ($this.data('datepicker-end')) {
131      $end = jQuery('[data-datepicker="'+ $this.data('datepicker-end') +'"]');
132
133      $this.datetimepicker('option', 'onClose', function(date) {
134        $end.datetimepicker('option', 'minDate', date);
135      });
136    }
137
138    // attach unset button
139    if ($this.data('datepicker-unset')) {
140      jQuery('#'+ $this.data('datepicker-unset')).on('click', function(e) {
141        e.preventDefault();
142        set(null, false);
143      });
144    }
145
146    // set value from linked input
147    if (linked) {
148      var splitted = originalValue.split(' ');
149      if (splitted.length == 2 && options.showTimepicker) {
150        set(jQuery.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', originalValue), true);
151      }
152      else if (splitted[0].length == 10) {
153        set(jQuery.datepicker.parseDate('yy-mm-dd', splitted[0]), true);
154      }
155      else {
156        set(null, true);
157      }
158    }
159
160    originalDate = $this.datetimepicker('getDate');
161
162    // autoSize not handled by timepicker
163    if (options.showTimepicker) {
164      $this.attr('size', parseInt($this.attr('size'))+6);
165    }
166  });
167};
168
169function debounce(func, wait, immediate) {
170  var timeout;
171  return function() {
172    var context = this, args = arguments;
173    var later = function() {
174      timeout = null;
175      if (!immediate) func.apply(context, args);
176    };
177    var callNow = immediate && !timeout;
178    clearTimeout(timeout);
179    timeout = setTimeout(later, wait);
180    if (callNow) func.apply(context, args);
181  };
182}
183
184}(jQuery));
Note: See TracBrowser for help on using the repository browser.