diff --git a/docs/methods.rst b/docs/methods.rst
index c8dce0ef7..1102c84d7 100644
--- a/docs/methods.rst
+++ b/docs/methods.rst
@@ -17,6 +17,7 @@ Remove the datepicker. Removes attached events, internal attached objects, and
*Alias: remove*
+
show
----
@@ -168,7 +169,7 @@ Arguments:
* startDate (Date)
-Sets a new lower date limit on the datepicker. See :ref:`startdate` for valid values.
+Sets a new lower date limit on the datepicker. See :ref:`startDate` for valid values.
Omit startDate (or provide an otherwise falsey value) to unset the limit.
@@ -180,7 +181,7 @@ Arguments:
* endDate (Date)
-Sets a new upper date limit on the datepicker. See :ref:`enddate` for valid values.
+Sets a new upper date limit on the datepicker. See :ref:`endDate` for valid values.
Omit endDate (or provide an otherwise falsey value) to unset the limit.
@@ -204,9 +205,9 @@ Arguments:
* daysOfWeekDisabled (String|Array)
-Sets the days of week that should be disabled. See :ref:`daysofweekdisabled` for valid values.
+Sets the days of week that should be disabled. See :ref:`daysOfWeekDisabled` for valid values.
-Omit daysOfWeekDisabled (or provide an otherwise falsey value) to unset the disabled days.
+Omit daysOfWeekDisabled (or provide an otherwise falsey value) to unset the disabled days of week.
setDaysOfWeekHighlighted
@@ -218,4 +219,4 @@ Arguments:
Sets the days of week that should be highlighted. See :ref:`daysOfWeekHighlighted` for valid values.
-Omit daysOfWeekHighlighted (or provide an otherwise falsey value) to unset the disabled days.
+Omit daysOfWeekHighlighted (or provide an otherwise falsey value) to unset the highlighted days of week.
diff --git a/docs/options.rst b/docs/options.rst
index 538df6e35..e9649c434 100644
--- a/docs/options.rst
+++ b/docs/options.rst
@@ -130,7 +130,7 @@ String. Default: "body"
Appends the date picker popup to a specific element; eg: container: '#picker-container' (will default to "body")
-.. _datesdisabled:
+.. _datesDisabled:
datesDisabled
@@ -140,7 +140,7 @@ String, Array. Default: []
Array of date strings or a single date string formatted in the given date format
-.. _daysofweekdisabled:
+.. _daysOfWeekDisabled:
daysOfWeekDisabled
@@ -153,7 +153,7 @@ Days of the week that should be disabled. Values are 0 (Sunday) to 6 (Saturday).
.. figure:: _static/screenshots/option_daysofweekdisabled.png
:align: center
-.. _daysofweekhighlighted:
+.. _daysOfWeekHighlighted:
daysOfWeekHighlighted
@@ -163,8 +163,6 @@ String, Array. Default: []
Days of the week that should be highlighted. Values are 0 (Sunday) to 6 (Saturday). Multiple values should be comma-separated. Example: highlight weekends: ``'06'`` or ``'0,6'`` or ``[0,6]``.
-.. _defaultviewdate:
-
defaultViewDate
---------------
@@ -193,7 +191,7 @@ Boolean. Default: true
If false the datepicker will not show on a readonly datepicker field.
-.. _enddate:
+.. _endDate:
endDate
diff --git a/js/bootstrap-datepicker.js b/js/bootstrap-datepicker.js
index ac2de7f99..40ee58446 100644
--- a/js/bootstrap-datepicker.js
+++ b/js/bootstrap-datepicker.js
@@ -101,7 +101,7 @@
// Picker object
var Datepicker = function(element, options){
- $(element).data('datepicker', this);
+ $.data(element, 'datepicker', this);
this._process_options(options);
this.dates = new DateArray();
@@ -112,7 +112,6 @@
this.isInput = this.element.is('input');
this.inputField = this.isInput ? this.element : this.element.find('input');
this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
- this.hasInput = this.component && this.inputField.length;
if (this.component && this.component.length === 0)
this.component = false;
this.isInline = !this.component && this.element.is('div');
@@ -123,6 +122,7 @@
if (this._check_template(this.o.templates.leftArrow)) {
this.picker.find('.prev').html(this.o.templates.leftArrow);
}
+
if (this._check_template(this.o.templates.rightArrow)) {
this.picker.find('.next').html(this.o.templates.rightArrow);
}
@@ -141,13 +141,12 @@
this.picker.addClass('datepicker-rtl');
}
- this.viewMode = this.o.startView;
-
- if (this.o.calendarWeeks)
- this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')
- .attr('colspan', function(i, val){
- return parseInt(val) + 1;
- });
+ if (this.o.calendarWeeks) {
+ this.picker.find('.datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear')
+ .attr('colspan', function(i, val){
+ return Number(val) + 1;
+ });
+ }
this._allow_update = false;
@@ -157,13 +156,13 @@
this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
this.setDatesDisabled(this.o.datesDisabled);
+ this.setViewMode(this.o.startView);
this.fillDow();
this.fillMonths();
this._allow_update = true;
this.update();
- this.showMode();
if (this.isInline){
this.show();
@@ -173,23 +172,21 @@
Datepicker.prototype = {
constructor: Datepicker,
- _resolveViewName: function(view, default_value){
- if (view === 0 || view === 'days' || view === 'month') {
- return 0;
- }
- if (view === 1 || view === 'months' || view === 'year') {
- return 1;
- }
- if (view === 2 || view === 'years' || view === 'decade') {
- return 2;
- }
- if (view === 3 || view === 'decades' || view === 'century') {
- return 3;
- }
- if (view === 4 || view === 'centuries' || view === 'millennium') {
- return 4;
- }
- return default_value === undefined ? false : default_value;
+ _resolveViewName: function(view){
+ $.each(DPGlobal.viewModes, function(i, viewMode){
+ if (view === i || $.inArray(view, viewMode.names) !== -1){
+ view = i;
+ return false;
+ }
+ });
+
+ return view;
+ },
+
+ _resolveDaysOfWeek: function(daysOfWeek){
+ if (!$.isArray(daysOfWeek))
+ daysOfWeek = daysOfWeek.split(/[,\s]*/);
+ return $.map(daysOfWeek, Number);
},
_check_template: function(tmp){
@@ -228,13 +225,12 @@
o.language = lang;
// Retrieve view index from any aliases
- o.startView = this._resolveViewName(o.startView, 0);
- o.minViewMode = this._resolveViewName(o.minViewMode, 0);
- o.maxViewMode = this._resolveViewName(o.maxViewMode, 4);
+ o.startView = this._resolveViewName(o.startView);
+ o.minViewMode = this._resolveViewName(o.minViewMode);
+ o.maxViewMode = this._resolveViewName(o.maxViewMode);
- // Check that the start view is between min and max
- o.startView = Math.min(o.startView, o.maxViewMode);
- o.startView = Math.max(o.startView, o.minViewMode);
+ // Check view is between min and max
+ o.startView = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, o.startView));
// true, false, or Number > 0
if (o.multidate !== true){
@@ -271,19 +267,8 @@
}
}
- o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
- if (!$.isArray(o.daysOfWeekDisabled))
- o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
- o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
- return parseInt(d, 10);
- });
-
- o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
- if (!$.isArray(o.daysOfWeekHighlighted))
- o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
- o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
- return parseInt(d, 10);
- });
+ o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]);
+ o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
o.datesDisabled = o.datesDisabled||[];
if (!$.isArray(o.datesDisabled)) {
@@ -291,7 +276,7 @@
o.datesDisabled
];
}
- o.datesDisabled = $.map(o.datesDisabled,function(d){
+ o.datesDisabled = $.map(o.datesDisabled, function(d){
return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
});
@@ -343,8 +328,7 @@
if (evs[i].length === 2){
ch = undefined;
ev = evs[i][1];
- }
- else if (evs[i].length === 3){
+ } else if (evs[i].length === 3){
ch = evs[i][1];
ev = evs[i][2];
}
@@ -357,8 +341,7 @@
if (evs[i].length === 2){
ch = undefined;
ev = evs[i][1];
- }
- else if (evs[i].length === 3){
+ } else if (evs[i].length === 3){
ch = evs[i][1];
ev = evs[i][2];
}
@@ -384,7 +367,8 @@
[this.element, events]
];
}
- else if (this.component && this.hasInput) { // component: input + button
+ // component: input + button
+ else if (this.component && this.inputField.length) {
this._events = [
// For components that are not readonly, allow keyboard nav
[this.inputField, events],
@@ -429,6 +413,9 @@
[this.picker, {
click: $.proxy(this.click, this)
}],
+ [this.picker, '.prev, .next', {
+ click: $.proxy(this.navArrowsClick, this)
+ }],
[$(window), {
resize: $.proxy(this.place, this)
}],
@@ -474,8 +461,7 @@
if (arguments.length === 0){
ix = this.dates.length - 1;
format = this.o.format;
- }
- else if (typeof ix === 'string'){
+ } else if (typeof ix === 'string'){
format = ix;
ix = this.dates.length - 1;
}
@@ -507,8 +493,7 @@
this.focusDate = null;
this.picker.hide().detach();
this._detachSecondaryEvents();
- this.viewMode = this.o.startView;
- this.showMode();
+ this.setViewMode(this.o.startView);
if (this.o.forceParse && this.inputField.val())
this.setValue();
@@ -528,21 +513,19 @@
return this;
},
- paste: function(evt){
+ paste: function(e){
var dateString;
- if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
- && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
- dateString = evt.originalEvent.clipboardData.getData('text/plain');
- }
- else if (window.clipboardData) {
+ if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.types
+ && $.inArray('text/plain', e.originalEvent.clipboardData.types) !== -1) {
+ dateString = e.originalEvent.clipboardData.getData('text/plain');
+ } else if (window.clipboardData) {
dateString = window.clipboardData.getData('Text');
- }
- else {
+ } else {
return;
}
this.setDate(dateString);
this.update();
- evt.preventDefault();
+ e.preventDefault();
},
_utc_to_local: function(utc){
@@ -555,7 +538,7 @@
return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
},
_zero_utc_time: function(utc){
- return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
+ return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
},
getDates: function(){
@@ -574,7 +557,7 @@
getUTCDate: function(){
var selected_date = this.dates.get(-1);
- if (typeof selected_date !== 'undefined') {
+ if (selected_date !== undefined) {
return new Date(selected_date);
} else {
return null;
@@ -582,10 +565,7 @@
},
clearDates: function(){
- if (this.inputField) {
- this.inputField.val('');
- }
-
+ this.inputField.val('');
this.update();
this._trigger('changeDate');
@@ -593,6 +573,7 @@
this.hide();
}
},
+
setDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
this.update.apply(this, args);
@@ -603,9 +584,7 @@
setUTCDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
- this.update.apply(this, $.map(args, this._utc_to_local));
- this._trigger('changeDate');
- this.setValue();
+ this.setDates.apply(this, $.map(args, this._utc_to_local));
return this;
},
@@ -654,7 +633,6 @@
setDaysOfWeekDisabled: function(daysOfWeekDisabled){
this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
this.update();
- this.updateNavArrows();
return this;
},
@@ -667,7 +645,6 @@
setDatesDisabled: function(datesDisabled){
this._process_options({datesDisabled: datesDisabled});
this.update();
- this.updateNavArrows();
return this;
},
@@ -772,8 +749,7 @@
dates.push(date);
}, this));
fromArgs = true;
- }
- else {
+ } else {
dates = this.isInput
? this.element.val()
: this.element.data('date') || this.inputField.val();
@@ -808,7 +784,7 @@
// setting date by clicking
this.setValue();
}
- else if (dates.length){
+ else if (this.dates.length){
// setting date by typing
if (String(oldDates) !== String(this.dates))
this._trigger('changeDate');
@@ -817,7 +793,7 @@
this._trigger('clearDate');
this.fill();
- this.element.change();
+ this.element.trigger('change');
return this;
},
@@ -825,15 +801,11 @@
var dowCnt = this.o.weekStart,
html = '
';
if (this.o.calendarWeeks){
- this.picker.find('.datepicker-days .datepicker-switch')
- .attr('colspan', function(i, val){
- return parseInt(val) + 1;
- });
html += '
';
}
while (dowCnt < this.o.weekStart + 7){
html += '
'+dates[this.o.language].daysMin[(dowCnt++)%7]+'
';
}
@@ -866,20 +838,16 @@
var cls = [],
year = this.viewDate.getUTCFullYear(),
month = this.viewDate.getUTCMonth(),
- today = new Date();
+ today = UTCToday();
if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
cls.push('old');
- }
- else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
+ } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
cls.push('new');
}
if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
cls.push('focused');
- // Compare internal UTC date with local today, not UTC today
- if (this.o.todayHighlight &&
- date.getUTCFullYear() === today.getFullYear() &&
- date.getUTCMonth() === today.getMonth() &&
- date.getUTCDate() === today.getDate()){
+ // Compare internal UTC date with UTC today, not local today
+ if (this.o.todayHighlight && isUTCEquals(date, today)) {
cls.push('today');
}
if (this.dates.contains(date) !== -1)
@@ -949,9 +917,9 @@
before = callback(new Date(thisYear, 0, 1));
if (before === undefined) {
before = {};
- } else if (typeof(before) === 'boolean') {
+ } else if (typeof before === 'boolean') {
before = {enabled: before};
- } else if (typeof(before) === 'string') {
+ } else if (typeof before === 'string') {
before = {classes: before};
}
if (before.enabled === false) {
@@ -999,9 +967,8 @@
.toggle(this.o.title !== '');
this.updateNavArrows();
this.fillMonths();
- var prevMonth = UTCDate(year, month-1, 28),
- day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
- prevMonth.setUTCDate(day);
+ var prevMonth = UTCDate(year, month, 0),
+ day = prevMonth.getUTCDate();
prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
var nextMonth = new Date(prevMonth);
if (prevMonth.getUTCFullYear() < 100){
@@ -1010,22 +977,23 @@
nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
nextMonth = nextMonth.valueOf();
var html = [];
- var clsName;
+ var weekDay, clsName;
while (prevMonth.valueOf() < nextMonth){
- if (prevMonth.getUTCDay() === this.o.weekStart){
+ weekDay = prevMonth.getUTCDay();
+ if (weekDay === this.o.weekStart){
html.push('
');
if (this.o.calendarWeeks){
// ISO 8601: First week contains first thursday.
// ISO also states week starts on Monday, but we can be more abstract here.
var
// Start of current week: based on weekstart/current date
- ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
+ ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),
// Thursday of this week
th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
// First Thursday of year, year from thursday
- yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
+ yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),
// Calendar week: ms between thursdays, div ms per day, div 7 days
- calWeek = (th - yth) / 864e5 / 7 + 1;
+ calWeek = (th - yth) / 864e5 / 7 + 1;
html.push('
'+ calWeek +'
');
}
}
@@ -1036,9 +1004,9 @@
before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
if (before === undefined)
before = {};
- else if (typeof(before) === 'boolean')
+ else if (typeof before === 'boolean')
before = {enabled: before};
- else if (typeof(before) === 'string')
+ else if (typeof before === 'string')
before = {classes: before};
if (before.enabled === false)
clsName.push('disabled');
@@ -1048,16 +1016,17 @@
tooltip = before.tooltip;
}
+ // $.unique is deprecated on jQuery 3.x
clsName = $.unique(clsName);
-
+
html.push('
'+prevMonth.getUTCDate() + '
');
tooltip = null;
- if (prevMonth.getUTCDay() === this.o.weekEnd){
+ if (weekDay === this.o.weekEnd){
html.push('
');
}
- prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
+ prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
}
- this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
+ this.picker.find('.datepicker-days tbody').html(html.join(''));
var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
var months = this.picker.find('.datepicker-months')
@@ -1088,9 +1057,9 @@
var before = that.o.beforeShowMonth(moDate);
if (before === undefined)
before = {};
- else if (typeof(before) === 'boolean')
+ else if (typeof before === 'boolean')
before = {enabled: before};
- else if (typeof(before) === 'string')
+ else if (typeof before === 'string')
before = {classes: before};
if (before.enabled === false && !$(month).hasClass('disabled'))
$(month).addClass('disabled');
@@ -1144,73 +1113,58 @@
var d = new Date(this.viewDate),
year = d.getUTCFullYear(),
- month = d.getUTCMonth();
+ month = d.getUTCMonth(),
+ prevState,
+ nextState;
switch (this.viewMode){
case 0:
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
- this.picker.find('.prev').addClass('disabled');
- }
- else {
- this.picker.find('.prev').removeClass('disabled');
- }
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
- this.picker.find('.next').addClass('disabled');
- }
- else {
- this.picker.find('.next').removeClass('disabled');
- }
+ prevState = (
+ this.o.startDate !== -Infinity &&
+ year <= this.o.startDate.getUTCFullYear() &&
+ month <= this.o.startDate.getUTCMonth()
+ );
+
+ nextState = (
+ this.o.endDate !== Infinity &&
+ year >= this.o.endDate.getUTCFullYear() &&
+ month >= this.o.endDate.getUTCMonth()
+ );
break;
case 1:
case 2:
case 3:
case 4:
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
- this.picker.find('.prev').addClass('disabled');
- }
- else {
- this.picker.find('.prev').removeClass('disabled');
- }
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
- this.picker.find('.next').addClass('disabled');
- }
- else {
- this.picker.find('.next').removeClass('disabled');
- }
+ prevState = (
+ this.o.startDate !== -Infinity &&
+ year <= this.o.startDate.getUTCFullYear()
+ );
+
+ nextState = (
+ this.o.endDate !== Infinity &&
+ year >= this.o.endDate.getUTCFullYear()
+ );
break;
}
+
+ this.picker.find('.prev').toggleClass('disabled', prevState);
+ this.picker.find('.next').toggleClass('disabled', nextState);
},
click: function(e){
e.preventDefault();
e.stopPropagation();
- var target, dir, day, year, month, monthChanged, yearChanged;
+ var target, dir, day, year, month;
target = $(e.target);
// Clicked on the switch
if (target.hasClass('datepicker-switch')){
- this.showMode(1);
- }
-
- // Clicked on prev or next
- var navArrow = target.closest('.prev, .next');
- if (navArrow.length > 0) {
- dir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1);
- if (this.viewMode === 0){
- this.viewDate = this.moveMonth(this.viewDate, dir);
- this._trigger('changeMonth', this.viewDate);
- } else {
- this.viewDate = this.moveYear(this.viewDate, dir);
- if (this.viewMode === 1){
- this._trigger('changeYear', this.viewDate);
- }
- }
- this.fill();
+ this.setViewMode(this.viewMode + 1);
}
// Clicked on today button
if (target.hasClass('today') && !target.hasClass('day')){
- this.showMode(-2);
+ this.setViewMode(0);
this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
}
@@ -1222,102 +1176,69 @@
if (!target.hasClass('disabled')){
// Clicked on a day
if (target.hasClass('day')){
- day = parseInt(target.text(), 10) || 1;
+ day = Number(target.text());
year = this.viewDate.getUTCFullYear();
month = this.viewDate.getUTCMonth();
- // From last month
- if (target.hasClass('old')){
- if (month === 0) {
- month = 11;
- year = year - 1;
- monthChanged = true;
- yearChanged = true;
- } else {
- month = month - 1;
- monthChanged = true;
- }
- }
-
- // From next month
- if (target.hasClass('new')) {
- if (month === 11){
- month = 0;
- year = year + 1;
- monthChanged = true;
- yearChanged = true;
- } else {
- month = month + 1;
- monthChanged = true;
- }
- }
- this._setDate(UTCDate(year, month, day));
- if (yearChanged) {
- this._trigger('changeYear', this.viewDate);
- }
- if (monthChanged) {
+ if (target.hasClass('old') || target.hasClass('new')){
+ dir = target.hasClass('old') ? -1 : 1;
+ month = (month + dir + 12) % 12;
+ if ((dir === -1 && month === 11) || (dir === 1 && month === 0)) {
+ year += dir;
+ this._trigger('changeYear', this.viewDate);
+ }
this._trigger('changeMonth', this.viewDate);
}
+ this._setDate(UTCDate(year, month, day));
}
- // Clicked on a month
- if (target.hasClass('month')) {
- this.viewDate.setUTCDate(1);
- day = 1;
- month = target.parent().find('span').index(target);
- year = this.viewDate.getUTCFullYear();
- this.viewDate.setUTCMonth(month);
- this._trigger('changeMonth', this.viewDate);
- if (this.o.minViewMode === 1){
- this._setDate(UTCDate(year, month, day));
- this.showMode();
- } else {
- this.showMode(-1);
- }
- this.fill();
- }
-
- // Clicked on a year
- if (target.hasClass('year')
+ // Clicked on a month, year, decade, century
+ if (target.hasClass('month')
+ || target.hasClass('year')
|| target.hasClass('decade')
|| target.hasClass('century')) {
this.viewDate.setUTCDate(1);
day = 1;
- month = 0;
- year = parseInt(target.text(), 10)||0;
- this.viewDate.setUTCFullYear(year);
-
- if (target.hasClass('year')){
- this._trigger('changeYear', this.viewDate);
- if (this.o.minViewMode === 2){
- this._setDate(UTCDate(year, month, day));
- }
- }
- if (target.hasClass('decade')){
- this._trigger('changeDecade', this.viewDate);
- if (this.o.minViewMode === 3){
- this._setDate(UTCDate(year, month, day));
- }
- }
- if (target.hasClass('century')){
- this._trigger('changeCentury', this.viewDate);
- if (this.o.minViewMode === 4){
- this._setDate(UTCDate(year, month, day));
- }
+ if (this.viewMode === 1){
+ month = target.parent().find('span').index(target);
+ year = this.viewDate.getUTCFullYear();
+ this.viewDate.setUTCMonth(month);
+ } else {
+ month = 0;
+ year = Number(target.text());
+ this.viewDate.setUTCFullYear(year);
}
- this.showMode(-1);
- this.fill();
+ this._trigger(DPGlobal.viewModes[this.viewMode - 1].e, this.viewDate);
+
+ if (this.viewMode === this.o.minViewMode){
+ this._setDate(UTCDate(year, month, day));
+ } else {
+ this.setViewMode(this.viewMode - 1);
+ this.fill();
+ }
}
}
if (this.picker.is(':visible') && this._focused_from){
- $(this._focused_from).focus();
+ this._focused_from.focus();
}
delete this._focused_from;
},
+ // Clicked on prev or next
+ navArrowsClick: function(e){
+ var target = $(e.target);
+ var dir = target.hasClass('prev') ? -1 : 1;
+ if (this.viewMode !== 0){
+ dir *= DPGlobal.viewModes[this.viewMode].navStep * 12;
+ }
+ this.viewDate = this.moveMonth(this.viewDate, dir);
+ this._trigger(DPGlobal.viewModes[this.viewMode].e, this.viewDate);
+ this.fill();
+ },
+
_toggle_multidate: function(date){
var ix = this.dates.contains(date);
if (!date){
@@ -1352,9 +1273,7 @@
if (!which || which !== 'view') {
this._trigger('changeDate');
}
- if (this.inputField){
- this.inputField.change();
- }
+ this.inputField.trigger('change');
if (this.o.autoclose && (!which || which === 'date')){
this.hide();
}
@@ -1397,8 +1316,7 @@
new_month = month + dir;
new_date.setUTCMonth(new_month);
// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
- if (new_month < 0 || new_month > 11)
- new_month = (new_month + 12) % 12;
+ new_month = (new_month + 12) % 12;
}
else {
// For magnitudes >1, move one month at a time...
@@ -1492,17 +1410,14 @@
if (newViewDate)
this._trigger('changeYear', this.viewDate);
- }
- else if (e.shiftKey){
+ } else if (e.shiftKey){
newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
if (newViewDate)
this._trigger('changeMonth', this.viewDate);
- }
- else if (e.keyCode === 37 || e.keyCode === 39){
+ } else if (e.keyCode === 37 || e.keyCode === 39){
newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
- }
- else if (!this.weekOfDateIsDisabled(focusDate)){
+ } else if (!this.weekOfDateIsDisabled(focusDate)){
newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
}
} else if (this.viewMode === 1) {
@@ -1554,27 +1469,23 @@
this._trigger('changeDate');
else
this._trigger('clearDate');
- if (this.inputField){
- this.inputField.change();
- }
+ this.inputField.trigger('change');
}
},
- showMode: function(dir){
- if (dir){
- this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
- }
+ setViewMode: function(viewMode){
+ this.viewMode = viewMode;
this.picker
.children('div')
.hide()
- .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
+ .filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName)
.show();
this.updateNavArrows();
}
};
var DateRangePicker = function(element, options){
- $(element).data('datepicker', this);
+ $.data(element, 'datepicker', this);
this.element = $(element);
this.inputs = $.map(options.inputs, function(i){
return i.jquery ? i[0] : i;
@@ -1588,7 +1499,7 @@
.on('changeDate', $.proxy(this.dateUpdated, this));
this.pickers = $.map(this.inputs, function(i){
- return $(i).data('datepicker');
+ return $.data(i, 'datepicker');
});
this.updateDates();
};
@@ -1615,9 +1526,9 @@
return;
this.updating = true;
- var dp = $(e.target).data('datepicker');
+ var dp = $.data(e.target, 'datepicker');
- if (typeof(dp) === "undefined") {
+ if (dp === undefined) {
return;
}
@@ -1640,8 +1551,7 @@
while (j >= 0 && new_date < this.dates[j]){
this.pickers[j--].setUTCDate(new_date);
}
- }
- else if (new_date > this.dates[k]){
+ } else if (new_date > this.dates[k]){
// Date being moved later/right
while (k < l && new_date > this.dates[k]){
this.pickers[k++].setUTCDate(new_date);
@@ -1651,10 +1561,11 @@
delete this.updating;
},
- remove: function(){
- $.map(this.pickers, function(p){ p.remove(); });
+ destroy: function(){
+ $.map(this.pickers, function(p){ p.destroy(); });
delete this.element.data().datepicker;
- }
+ },
+ remove: alias('destroy')
};
function opts_from_el(el, prefix){
@@ -1801,38 +1712,37 @@
};
var DPGlobal = {
- modes: [
+ viewModes: [
{
+ names: ['days', 'month'],
clsName: 'days',
- navFnc: 'Month',
- navStep: 1
+ e: 'changeMonth'
},
{
+ names: ['months', 'year'],
clsName: 'months',
- navFnc: 'FullYear',
+ e: 'changeYear',
navStep: 1
},
{
+ names: ['years', 'decade'],
clsName: 'years',
- navFnc: 'FullYear',
+ e: 'changeDecade',
navStep: 10
},
{
+ names: ['decades', 'century'],
clsName: 'decades',
- navFnc: 'FullDecade',
+ e: 'changeCentury',
navStep: 100
},
{
+ names: ['centuries', 'millennium'],
clsName: 'centuries',
- navFnc: 'FullCentury',
+ e: 'changeMillennium',
navStep: 1000
- }],
- isLeapYear: function(year){
- return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
- },
- getDaysInMonth: function(year, month){
- return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
- },
+ }
+ ],
validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
parseFormat: function(format){
@@ -1881,20 +1791,20 @@
return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
}
- if (typeof dateAliases[date] !== 'undefined') {
+ if (date in dateAliases) {
date = dateAliases[date];
parts = date.match(/([\-+]\d+)([dmwy])/g);
if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
date = new Date();
- for (i=0; i < parts.length; i++){
+ for (i=0; i < parts.length; i++){
part = part_re.exec(parts[i]);
dir = parseInt(part[1]);
fn = fn_map[part[2]];
date = Datepicker.prototype[fn](date, dir);
- }
+ }
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
+ return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
}
}
@@ -1923,9 +1833,6 @@
yyyy: function(d,v){
return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
},
- yy: function(d,v){
- return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
- },
m: function(d,v){
if (isNaN(d))
return d;
@@ -1942,6 +1849,7 @@
}
},
val, filtered;
+ setters_map['yy'] = setters_map['yyyy'];
setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
setters_map['dd'] = setters_map['d'];
date = UTCToday();
diff --git a/tests/suites/component.js b/tests/suites/component.js
index 0ee3c099e..40dc3cbb6 100644
--- a/tests/suites/component.js
+++ b/tests/suites/component.js
@@ -220,12 +220,12 @@ test('date and viewDate must be between startDate and endDate when setEndDate ca
});
test('picker should render fine when `$.fn.show` and `$.fn.hide` are overridden', patch_show_hide(function () {
- var viewModes = $.fn.datepicker.DPGlobal.modes,
+ var viewModes = $.fn.datepicker.DPGlobal.viewModes,
minViewMode = this.dp.o.minViewMode,
maxViewMode = this.dp.o.maxViewMode,
childDivs = this.picker.children('div');
- this.dp.showMode(minViewMode);
+ this.dp.setViewMode(minViewMode);
// Overwritten `$.fn.hide` method adds the `foo` class to its matched elements
var curDivShowing = childDivs.filter('.datepicker-' + viewModes[minViewMode].clsName);
diff --git a/tests/suites/options.js b/tests/suites/options.js
index eea59b4a2..4d594db9b 100644
--- a/tests/suites/options.js
+++ b/tests/suites/options.js
@@ -322,6 +322,27 @@ test('Today Button: moves to today\'s date', function(){
datesEqual(dp.dates[0], UTCDate(2012, 2, 5));
});
+test('Today Button: moves to days view', function(){
+ var viewModes = $.fn.datepicker.DPGlobal.viewModes;
+ var input = $('')
+ .appendTo('#qunit-fixture')
+ .val('2012-03-05')
+ .datepicker({
+ format: 'yyyy-mm-dd',
+ startView: viewModes.length - 1,
+ todayBtn: true
+ }),
+ dp = input.data('datepicker'),
+ picker = dp.picker,
+ target;
+
+ input.focus();
+ target = picker.find('tfoot .today').filter(':visible');
+
+ target.click();
+ ok(picker.find('.datepicker-days tfoot .today').is(':visible'), 'Today button visible');
+});
+
test('Today Button: "linked" selects today\'s date', function(){
var input = $('')
.appendTo('#qunit-fixture')