Commit 2431285e authored by Michal Čihař's avatar Michal Čihař

Update datepicker

Signed-off-by: default avatarMichal Čihař <michal@cihar.com>
parent 5a681647
/*! /*!
* Datepicker for Bootstrap * Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker)
* *
* Copyright 2012 Stefan Petre * Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls * Improvements by Andrew Rowls
* Licensed under the Apache License v2.0 * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* http://www.apache.org/licenses/LICENSE-2.0
*
*/ */
.datepicker { .datepicker {
padding: 4px;
border-radius: 4px; border-radius: 4px;
direction: ltr; direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
} }
.datepicker-inline { .datepicker-inline {
width: 220px; width: 220px;
...@@ -78,13 +72,9 @@ ...@@ -78,13 +72,9 @@
.datepicker > div { .datepicker > div {
display: none; display: none;
} }
.datepicker.days div.datepicker-days { .datepicker.days .datepicker-days,
display: block; .datepicker.months .datepicker-months,
} .datepicker.years .datepicker-years {
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block; display: block;
} }
.datepicker table { .datepicker table {
...@@ -708,7 +698,7 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { ...@@ -708,7 +698,7 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
.datepicker table tr td span.new { .datepicker table tr td span.new {
color: #999999; color: #999999;
} }
.datepicker th.datepicker-switch { .datepicker .datepicker-switch {
width: 145px; width: 145px;
} }
.datepicker thead tr:first-child th, .datepicker thead tr:first-child th,
...@@ -725,14 +715,15 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { ...@@ -725,14 +715,15 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
padding: 0 2px 0 5px; padding: 0 2px 0 5px;
vertical-align: middle; vertical-align: middle;
} }
.datepicker thead tr:first-child th.cw { .datepicker thead tr:first-child .cw {
cursor: default; cursor: default;
background-color: transparent; background-color: transparent;
} }
.input-group.date .input-group-addon i { .input-group.date .input-group-addon {
cursor: pointer; cursor: pointer;
width: 16px; }
height: 16px; .input-daterange {
width: 100%;
} }
.input-daterange input { .input-daterange input {
text-align: center; text-align: center;
...@@ -748,7 +739,7 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { ...@@ -748,7 +739,7 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
min-width: 16px; min-width: 16px;
padding: 4px 5px; padding: 4px 5px;
font-weight: normal; font-weight: normal;
line-height: 1.428571429; line-height: 1.42857143;
text-align: center; text-align: center;
text-shadow: 0 1px 0 #fff; text-shadow: 0 1px 0 #fff;
vertical-align: middle; vertical-align: middle;
...@@ -758,35 +749,3 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { ...@@ -758,35 +749,3 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
margin-left: -5px; margin-left: -5px;
margin-right: -5px; margin-right: -5px;
} }
.datepicker.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
float: left;
display: none;
min-width: 160px;
list-style: none;
background-color: #ffffff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 5px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
*border-right-width: 2px;
*border-bottom-width: 2px;
color: #333333;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
line-height: 1.428571429;
}
.datepicker.dropdown-menu th,
.datepicker.datepicker-inline th,
.datepicker.dropdown-menu td,
.datepicker.datepicker-inline td {
padding: 0px 5px;
}
/* ========================================================= /*!
* bootstrap-datepicker.js * Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker)
* Repo: https://github.com/eternicode/bootstrap-datepicker/
* Demo: http://eternicode.github.io/bootstrap-datepicker/
* Docs: http://bootstrap-datepicker.readthedocs.org/
* Forked from http://www.eyecon.ro/bootstrap-datepicker
* =========================================================
* Started by Stefan Petre; improvements by Andrew Rowls + contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Copyright 2012 Stefan Petre
* you may not use this file except in compliance with the License. * Improvements by Andrew Rowls
* You may obtain a copy of the License at * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* */(function($, undefined){
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================= */
(function($, undefined){
var $window = $(window);
function UTCDate(){ function UTCDate(){
return new Date(Date.UTC.apply(Date, arguments)); return new Date(Date.UTC.apply(Date, arguments));
...@@ -31,6 +13,13 @@ ...@@ -31,6 +13,13 @@
var today = new Date(); var today = new Date();
return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
} }
function isUTCEquals(date1, date2) {
return (
date1.getUTCFullYear() === date2.getUTCFullYear() &&
date1.getUTCMonth() === date2.getUTCMonth() &&
date1.getUTCDate() === date2.getUTCDate()
);
}
function alias(method){ function alias(method){
return function(){ return function(){
return this[method].apply(this, arguments); return this[method].apply(this, arguments);
...@@ -84,16 +73,16 @@ ...@@ -84,16 +73,16 @@
// Picker object // Picker object
var Datepicker = function(element, options){ var Datepicker = function(element, options){
this._process_options(options);
this.dates = new DateArray(); this.dates = new DateArray();
this.viewDate = UTCToday(); this.viewDate = this.o.defaultViewDate;
this.focusDate = null; this.focusDate = null;
this._process_options(options);
this.element = $(element); this.element = $(element);
this.isInline = false; this.isInline = false;
this.isInput = this.element.is('input'); this.isInput = this.element.is('input');
this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
this.hasInput = this.component && this.element.find('input').length; this.hasInput = this.component && this.element.find('input').length;
if (this.component && this.component.length === 0) if (this.component && this.component.length === 0)
this.component = false; this.component = false;
...@@ -116,7 +105,7 @@ ...@@ -116,7 +105,7 @@
this.viewMode = this.o.startView; this.viewMode = this.o.startView;
if (this.o.calendarWeeks) if (this.o.calendarWeeks)
this.picker.find('tfoot th.today') this.picker.find('tfoot .today, tfoot .clear')
.attr('colspan', function(i, val){ .attr('colspan', function(i, val){
return parseInt(val) + 1; return parseInt(val) + 1;
}); });
...@@ -126,6 +115,7 @@ ...@@ -126,6 +115,7 @@
this.setStartDate(this._o.startDate); this.setStartDate(this._o.startDate);
this.setEndDate(this._o.endDate); this.setEndDate(this._o.endDate);
this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
this.setDatesDisabled(this.o.datesDisabled);
this.fillDow(); this.fillDow();
this.fillMonths(); this.fillMonths();
...@@ -192,8 +182,6 @@ ...@@ -192,8 +182,6 @@
o.multidate = Number(o.multidate) || false; o.multidate = Number(o.multidate) || false;
if (o.multidate !== false) if (o.multidate !== false)
o.multidate = Math.max(0, o.multidate); o.multidate = Math.max(0, o.multidate);
else
o.multidate = 1;
} }
o.multidateSeparator = String(o.multidateSeparator); o.multidateSeparator = String(o.multidateSeparator);
...@@ -231,10 +219,20 @@ ...@@ -231,10 +219,20 @@
return parseInt(d, 10); return parseInt(d, 10);
}); });
o.datesDisabled = o.datesDisabled||[];
if (!$.isArray(o.datesDisabled)) {
var datesDisabled = [];
datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language));
o.datesDisabled = datesDisabled;
}
o.datesDisabled = $.map(o.datesDisabled,function(d){
return DPGlobal.parseDate(d, format, o.language);
});
var plc = String(o.orientation).toLowerCase().split(/\s+/g), var plc = String(o.orientation).toLowerCase().split(/\s+/g),
_plc = o.orientation.toLowerCase(); _plc = o.orientation.toLowerCase();
plc = $.grep(plc, function(word){ plc = $.grep(plc, function(word){
return (/^auto|left|right|top|bottom$/).test(word); return /^auto|left|right|top|bottom$/.test(word);
}); });
o.orientation = {x: 'auto', y: 'auto'}; o.orientation = {x: 'auto', y: 'auto'};
if (!_plc || _plc === 'auto') if (!_plc || _plc === 'auto')
...@@ -253,15 +251,24 @@ ...@@ -253,15 +251,24 @@
} }
else { else {
_plc = $.grep(plc, function(word){ _plc = $.grep(plc, function(word){
return (/^left|right$/).test(word); return /^left|right$/.test(word);
}); });
o.orientation.x = _plc[0] || 'auto'; o.orientation.x = _plc[0] || 'auto';
_plc = $.grep(plc, function(word){ _plc = $.grep(plc, function(word){
return (/^top|bottom$/).test(word); return /^top|bottom$/.test(word);
}); });
o.orientation.y = _plc[0] || 'auto'; o.orientation.y = _plc[0] || 'auto';
} }
if (o.defaultViewDate) {
var year = o.defaultViewDate.year || new Date().getFullYear();
var month = o.defaultViewDate.month || 0;
var day = o.defaultViewDate.day || 1;
o.defaultViewDate = UTCDate(year, month, day);
} else {
o.defaultViewDate = UTCToday();
}
o.showOnFocus = o.showOnFocus !== undefined ? o.showOnFocus : true;
}, },
_events: [], _events: [],
_secondaryEvents: [], _secondaryEvents: [],
...@@ -294,34 +301,33 @@ ...@@ -294,34 +301,33 @@
} }
}, },
_buildEvents: function(){ _buildEvents: function(){
if (this.isInput){ // single input var events = {
this._events = [ keyup: $.proxy(function(e){
[this.element, { if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
focus: $.proxy(this.show, this), this.update();
keyup: $.proxy(function(e){ }, this),
if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) keydown: $.proxy(this.keydown, this),
this.update(); paste: $.proxy(this.paste, this)
}, this), };
keydown: $.proxy(this.keydown, this)
}] if (this.o.showOnFocus === true) {
]; events.focus = $.proxy(this.show, this);
} }
else if (this.component && this.hasInput){ // component: input + button
this._events = [ if (this.isInput) { // single input
// For components that are not readonly, allow keyboard nav this._events = [
[this.element.find('input'), { [this.element, events]
focus: $.proxy(this.show, this), ];
keyup: $.proxy(function(e){ }
if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) else if (this.component && this.hasInput) { // component: input + button
this.update(); this._events = [
}, this), // For components that are not readonly, allow keyboard nav
keydown: $.proxy(this.keydown, this) [this.element.find('input'), events],
}], [this.component, {
[this.component, { click: $.proxy(this.show, this)
click: $.proxy(this.show, this) }]
}] ];
]; }
}
else if (this.element.is('div')){ // inline datepicker else if (this.element.is('div')){ // inline datepicker
this.isInline = true; this.isInline = true;
} }
...@@ -347,6 +353,15 @@ ...@@ -347,6 +353,15 @@
}] }]
); );
if (this.o.immediateUpdates) {
// Trigger input updates immediately on changed year/month
this._events.push([this.element, {
'changeYear changeMonth': $.proxy(function(e){
this.update(e.date);
}, this)
}]);
}
this._secondaryEvents = [ this._secondaryEvents = [
[this.picker, { [this.picker, {
click: $.proxy(this.click, this) click: $.proxy(this.click, this)
...@@ -355,7 +370,7 @@ ...@@ -355,7 +370,7 @@
resize: $.proxy(this.place, this) resize: $.proxy(this.place, this)
}], }],
[$(document), { [$(document), {
'mousedown touchstart': $.proxy(function(e){ mousedown: $.proxy(function(e){
// Clicked outside the datepicker, hide it // Clicked outside the datepicker, hide it
if (!( if (!(
this.element.is(e.target) || this.element.is(e.target) ||
...@@ -363,7 +378,7 @@ ...@@ -363,7 +378,7 @@
this.picker.is(e.target) || this.picker.is(e.target) ||
this.picker.find(e.target).length this.picker.find(e.target).length
)){ )){
this.hide(); $(this.picker).hide();
} }
}, this) }, this)
}] }]
...@@ -408,19 +423,25 @@ ...@@ -408,19 +423,25 @@
}, },
show: function(){ show: function(){
if (this.element.attr('readonly') && this.o.enableOnReadonly === false)
return;
if (!this.isInline) if (!this.isInline)
this.picker.appendTo('body'); this.picker.appendTo(this.o.container);
this.picker.show();
this.place(); this.place();
this.picker.show();
this._attachSecondaryEvents(); this._attachSecondaryEvents();
this._trigger('show'); this._trigger('show');
if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
$(this.element).blur();
}
return this;
}, },
hide: function(){ hide: function(){
if (this.isInline) if (this.isInline)
return; return this;
if (!this.picker.is(':visible')) if (!this.picker.is(':visible'))
return; return this;
this.focusDate = null; this.focusDate = null;
this.picker.hide().detach(); this.picker.hide().detach();
this._detachSecondaryEvents(); this._detachSecondaryEvents();
...@@ -436,6 +457,7 @@ ...@@ -436,6 +457,7 @@
) )
this.setValue(); this.setValue();
this._trigger('hide'); this._trigger('hide');
return this;
}, },
remove: function(){ remove: function(){
...@@ -447,6 +469,24 @@ ...@@ -447,6 +469,24 @@
if (!this.isInput){ if (!this.isInput){
delete this.element.data().date; delete this.element.data().date;
} }
return this;
},
paste: function(evt){
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) {
dateString = window.clipboardData.getData('Text');
}
else {
return;
}
this.setDate(dateString);
this.update();
evt.preventDefault();
}, },
_utc_to_local: function(utc){ _utc_to_local: function(utc){
...@@ -477,14 +517,39 @@ ...@@ -477,14 +517,39 @@
}, },
getUTCDate: function(){ getUTCDate: function(){
return new Date(this.dates.get(-1)); var selected_date = this.dates.get(-1);
if (typeof selected_date !== 'undefined') {
return new Date(selected_date);
} else {
return null;
}
}, },
clearDates: function(){
var element;
if (this.isInput) {
element = this.element;
} else if (this.component) {
element = this.element.find('input');
}
if (element) {
element.val('').change();
}
this.update();
this._trigger('changeDate');
if (this.o.autoclose) {
this.hide();
}
},
setDates: function(){ setDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments; var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
this.update.apply(this, args); this.update.apply(this, args);
this._trigger('changeDate'); this._trigger('changeDate');
this.setValue(); this.setValue();
return this;
}, },
setUTCDates: function(){ setUTCDates: function(){
...@@ -492,6 +557,7 @@ ...@@ -492,6 +557,7 @@
this.update.apply(this, $.map(args, this._utc_to_local)); this.update.apply(this, $.map(args, this._utc_to_local));
this._trigger('changeDate'); this._trigger('changeDate');
this.setValue(); this.setValue();
return this;
}, },
setDate: alias('setDates'), setDate: alias('setDates'),
...@@ -507,6 +573,7 @@ ...@@ -507,6 +573,7 @@
else { else {
this.element.val(formatted).change(); this.element.val(formatted).change();
} }
return this;
}, },
getFormattedDate: function(format){ getFormattedDate: function(format){
...@@ -523,38 +590,51 @@ ...@@ -523,38 +590,51 @@
this._process_options({startDate: startDate}); this._process_options({startDate: startDate});
this.update(); this.update();
this.updateNavArrows(); this.updateNavArrows();
return this;
}, },
setEndDate: function(endDate){ setEndDate: function(endDate){
this._process_options({endDate: endDate}); this._process_options({endDate: endDate});
this.update(); this.update();
this.updateNavArrows(); this.updateNavArrows();
return this;
}, },
setDaysOfWeekDisabled: function(daysOfWeekDisabled){ setDaysOfWeekDisabled: function(daysOfWeekDisabled){
this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
this.update(); this.update();
this.updateNavArrows(); this.updateNavArrows();
return this;
},
setDatesDisabled: function(datesDisabled){
this._process_options({datesDisabled: datesDisabled});
this.update();
this.updateNavArrows();
}, },
place: function(){ place: function(){
if (this.isInline) if (this.isInline)
return; return this;
var calendarWidth = this.picker.outerWidth(), var calendarWidth = this.picker.outerWidth(),
calendarHeight = this.picker.outerHeight(), calendarHeight = this.picker.outerHeight(),
visualPadding = 10, visualPadding = 10,
windowWidth = $window.width(), windowWidth = $(this.o.container).width(),
windowHeight = $window.height(), windowHeight = $(this.o.container).height(),
scrollTop = $window.scrollTop(); scrollTop = $(this.o.container).scrollTop(),
appendOffset = $(this.o.container).offset();
var zIndex = parseInt(this.element.parents().filter(function(){
return $(this).css('z-index') !== 'auto'; var parentsZindex = [];
}).first().css('z-index'))+10; this.element.parents().each(function(){
var itemZIndex = $(this).css('z-index');
if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
});
var zIndex = Math.max.apply(Math, parentsZindex) + 10;
var offset = this.component ? this.component.parent().offset() : this.element.offset(); var offset = this.component ? this.component.parent().offset() : this.element.offset();
var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
var left = offset.left, var left = offset.left - appendOffset.left,
top = offset.top; top = offset.top - appendOffset.top;
this.picker.removeClass( this.picker.removeClass(
'datepicker-orient-top datepicker-orient-bottom '+ 'datepicker-orient-top datepicker-orient-bottom '+
...@@ -569,12 +649,18 @@ ...@@ -569,12 +649,18 @@
// auto x orientation is best-placement: if it crosses a window // auto x orientation is best-placement: if it crosses a window
// edge, fudge it sideways // edge, fudge it sideways
else { else {
// Default to left if (offset.left < 0) {
this.picker.addClass('datepicker-orient-left'); // component is outside the window on the left side. Move it into visible range
if (offset.left < 0) this.picker.addClass('datepicker-orient-left');
left -= offset.left - visualPadding; left -= offset.left - visualPadding;
else if (offset.left + calendarWidth > windowWidth) } else if (left + calendarWidth > windowWidth) {
left = windowWidth - calendarWidth - visualPadding; // the calendar passes the widow right edge. Align it to component right side
this.picker.addClass('datepicker-orient-right');
left = offset.left + width - calendarWidth;
} else {
// Default to left
this.picker.addClass('datepicker-orient-left');
}
} }
// auto y orientation is best-situation: top or bottom, no fudging, // auto y orientation is best-situation: top or bottom, no fudging,
...@@ -582,8 +668,8 @@ ...@@ -582,8 +668,8 @@
var yorient = this.o.orientation.y, var yorient = this.o.orientation.y,
top_overflow, bottom_overflow; top_overflow, bottom_overflow;
if (yorient === 'auto'){ if (yorient === 'auto'){
top_overflow = -scrollTop + offset.top - calendarHeight; top_overflow = -scrollTop + top - calendarHeight;
bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight); bottom_overflow = scrollTop + windowHeight - (top + height + calendarHeight);
if (Math.max(top_overflow, bottom_overflow) === bottom_overflow) if (Math.max(top_overflow, bottom_overflow) === bottom_overflow)
yorient = 'top'; yorient = 'top';
else else
...@@ -595,17 +681,27 @@ ...@@ -595,17 +681,27 @@
else else
top -= calendarHeight + parseInt(this.picker.css('padding-top')); top -= calendarHeight + parseInt(this.picker.css('padding-top'));
this.picker.css({ if (this.o.rtl) {
top: top, var right = windowWidth - (left + width);
left: left, this.picker.css({
zIndex: zIndex top: top,
}); right: right,
zIndex: zIndex
});
} else {
this.picker.css({
top: top,
left: left,
zIndex: zIndex
});
}
return this;
}, },
_allow_update: true, _allow_update: true,
update: function(){ update: function(){
if (!this._allow_update) if (!this._allow_update)
return; return this;
var oldDates = this.dates.copy(), var oldDates = this.dates.copy(),
dates = [], dates = [],
...@@ -661,15 +757,19 @@ ...@@ -661,15 +757,19 @@
this._trigger('clearDate'); this._trigger('clearDate');
this.fill(); this.fill();
return this;
}, },
fillDow: function(){ fillDow: function(){
var dowCnt = this.o.weekStart, var dowCnt = this.o.weekStart,
html = '<tr>'; html = '<tr>';
if (this.o.calendarWeeks){ if (this.o.calendarWeeks){
var cell = '<th class="cw">&nbsp;</th>'; this.picker.find('.datepicker-days thead tr:first-child .datepicker-switch')
.attr('colspan', function(i, val){
return parseInt(val) + 1;
});
var cell = '<th class="cw">&#160;</th>';
html += cell; html += cell;
this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
} }
while (dowCnt < this.o.weekStart + 7){ while (dowCnt < this.o.weekStart + 7){
html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>'; html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
...@@ -723,6 +823,12 @@ ...@@ -723,6 +823,12 @@
$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){ $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){
cls.push('disabled'); cls.push('disabled');
} }
if (this.o.datesDisabled.length > 0 &&
$.grep(this.o.datesDisabled, function(d){
return isUTCEquals(date, d); }).length > 0) {
cls.push('disabled', 'disabled-date');
}
if (this.range){ if (this.range){
if (date > this.range[0] && date < this.range[this.range.length-1]){ if (date > this.range[0] && date < this.range[this.range.length-1]){
cls.push('range'); cls.push('range');
...@@ -745,12 +851,14 @@ ...@@ -745,12 +851,14 @@
todaytxt = dates[this.o.language].today || dates['en'].today || '', todaytxt = dates[this.o.language].today || dates['en'].today || '',
cleartxt = dates[this.o.language].clear || dates['en'].clear || '', cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
tooltip; tooltip;
this.picker.find('.datepicker-days thead th.datepicker-switch') if (isNaN(year) || isNaN(month))
return;
this.picker.find('.datepicker-days thead .datepicker-switch')
.text(dates[this.o.language].months[month]+' '+year); .text(dates[this.o.language].months[month]+' '+year);
this.picker.find('tfoot th.today') this.picker.find('tfoot .today')
.text(todaytxt) .text(todaytxt)
.toggle(this.o.todayBtn !== false); .toggle(this.o.todayBtn !== false);
this.picker.find('tfoot th.clear') this.picker.find('tfoot .clear')
.text(cleartxt) .text(cleartxt)
.toggle(this.o.clearBtn !== false); .toggle(this.o.clearBtn !== false);
this.updateNavArrows(); this.updateNavArrows();
...@@ -804,6 +912,7 @@ ...@@ -804,6 +912,7 @@
clsName = $.unique(clsName); clsName = $.unique(clsName);
html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>'); html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
tooltip = null;
if (prevMonth.getUTCDay() === this.o.weekEnd){ if (prevMonth.getUTCDay() === this.o.weekEnd){
html.push('</tr>'); html.push('</tr>');
} }
...@@ -832,6 +941,18 @@ ...@@ -832,6 +941,18 @@
months.slice(endMonth+1).addClass('disabled'); months.slice(endMonth+1).addClass('disabled');
} }
if (this.o.beforeShowMonth !== $.noop){
var that = this;
$.each(months, function(i, month){
if (!$(month).hasClass('disabled')) {
var moDate = new Date(year, i, 1);
var before = that.o.beforeShowMonth(moDate);
if (before === false)
$(month).addClass('disabled');
}
});
}
html = ''; html = '';
year = parseInt(year/10, 10) * 10; year = parseInt(year/10, 10) * 10;
var yearCont = this.picker.find('.datepicker-years') var yearCont = this.picker.find('.datepicker-years')
...@@ -854,7 +975,7 @@ ...@@ -854,7 +975,7 @@
classes.push('active'); classes.push('active');
if (year < startYear || year > endYear) if (year < startYear || year > endYear)
classes.push('disabled'); classes.push('disabled');
html += '<span class="' + classes.join(' ') + '">'+year+'</span>'; html += '<span class="' + classes.join(' ') + '">' + year + '</span>';
year += 1; year += 1;
} }
yearCont.html(html); yearCont.html(html);
...@@ -937,24 +1058,14 @@ ...@@ -937,24 +1058,14 @@
this._setDate(date, which); this._setDate(date, which);
break; break;
case 'clear': case 'clear':
var element; this.clearDates();
if (this.isInput)
element = this.element;
else if (this.component)
element = this.element.find('input');
if (element)
element.val("").change();
this.update();
this._trigger('changeDate');
if (this.o.autoclose)
this.hide();
break; break;
} }
break; break;
case 'span': case 'span':
if (!target.is('.disabled')){ if (!target.hasClass('disabled')){
this.viewDate.setUTCDate(1); this.viewDate.setUTCDate(1);
if (target.is('.month')){ if (target.hasClass('month')){
day = 1; day = 1;
month = target.parent().find('span').index(target); month = target.parent().find('span').index(target);
year = this.viewDate.getUTCFullYear(); year = this.viewDate.getUTCFullYear();
...@@ -962,6 +1073,9 @@ ...@@ -962,6 +1073,9 @@
this._trigger('changeMonth', this.viewDate); this._trigger('changeMonth', this.viewDate);
if (this.o.minViewMode === 1){ if (this.o.minViewMode === 1){
this._setDate(UTCDate(year, month, day)); this._setDate(UTCDate(year, month, day));
this.showMode();
} else {
this.showMode(-1);
} }
} }
else { else {
...@@ -973,17 +1087,17 @@ ...@@ -973,17 +1087,17 @@
if (this.o.minViewMode === 2){ if (this.o.minViewMode === 2){
this._setDate(UTCDate(year, month, day)); this._setDate(UTCDate(year, month, day));
} }
this.showMode(-1);
} }
this.showMode(-1);
this.fill(); this.fill();
} }
break; break;
case 'td': case 'td':
if (target.is('.day') && !target.is('.disabled')){ if (target.hasClass('day') && !target.hasClass('disabled')){
day = parseInt(target.text(), 10)||1; day = parseInt(target.text(), 10)||1;
year = this.viewDate.getUTCFullYear(); year = this.viewDate.getUTCFullYear();
month = this.viewDate.getUTCMonth(); month = this.viewDate.getUTCMonth();
if (target.is('.old')){ if (target.hasClass('old')){
if (month === 0){ if (month === 0){
month = 11; month = 11;
year -= 1; year -= 1;
...@@ -992,7 +1106,7 @@ ...@@ -992,7 +1106,7 @@
month -= 1; month -= 1;
} }
} }
else if (target.is('.new')){ else if (target.hasClass('new')){
if (month === 11){ if (month === 11){
month = 0; month = 0;
year += 1; year += 1;
...@@ -1017,12 +1131,19 @@ ...@@ -1017,12 +1131,19 @@
if (!date){ if (!date){
this.dates.clear(); this.dates.clear();
} }
else if (ix !== -1){
this.dates.remove(ix); if (ix !== -1){
if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){
this.dates.remove(ix);
}
} else if (this.o.multidate === false) {
this.dates.clear();
this.dates.push(date);
} }
else { else {
this.dates.push(date); this.dates.push(date);
} }
if (typeof this.o.multidate === 'number') if (typeof this.o.multidate === 'number')
while (this.dates.length > this.o.multidate) while (this.dates.length > this.o.multidate)
this.dates.remove(0); this.dates.remove(0);
...@@ -1036,7 +1157,9 @@ ...@@ -1036,7 +1157,9 @@
this.fill(); this.fill();
this.setValue(); this.setValue();
this._trigger('changeDate'); if (!which || which !== 'view') {
this._trigger('changeDate');
}
var element; var element;
if (this.isInput){ if (this.isInput){
element = this.element; element = this.element;
...@@ -1111,8 +1234,8 @@ ...@@ -1111,8 +1234,8 @@
}, },
keydown: function(e){ keydown: function(e){
if (this.picker.is(':not(:visible)')){ if (!this.picker.is(':visible')){
if (e.keyCode === 27) // allow escape to hide and re-show picker if (e.keyCode === 40 || e.keyCode === 27) // allow down to re-show picker
this.show(); this.show();
return; return;
} }
...@@ -1151,7 +1274,7 @@ ...@@ -1151,7 +1274,7 @@
newViewDate = new Date(focusDate); newViewDate = new Date(focusDate);
newViewDate.setUTCDate(focusDate.getUTCDate() + dir); newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
} }
if (this.dateWithinRange(newDate)){ if (this.dateWithinRange(newViewDate)){
this.focusDate = this.viewDate = newViewDate; this.focusDate = this.viewDate = newViewDate;
this.setValue(); this.setValue();
this.fill(); this.fill();
...@@ -1179,7 +1302,7 @@ ...@@ -1179,7 +1302,7 @@
newViewDate = new Date(focusDate); newViewDate = new Date(focusDate);
newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7); newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
} }
if (this.dateWithinRange(newDate)){ if (this.dateWithinRange(newViewDate)){
this.focusDate = this.viewDate = newViewDate; this.focusDate = this.viewDate = newViewDate;
this.setValue(); this.setValue();
this.fill(); this.fill();
...@@ -1192,14 +1315,21 @@ ...@@ -1192,14 +1315,21 @@
break; break;
case 13: // enter case 13: // enter
focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
this._toggle_multidate(focusDate); if (this.o.keyboardNavigation) {
dateChanged = true; this._toggle_multidate(focusDate);
dateChanged = true;
}
this.focusDate = null; this.focusDate = null;
this.viewDate = this.dates.get(-1) || this.viewDate; this.viewDate = this.dates.get(-1) || this.viewDate;
this.setValue(); this.setValue();
this.fill(); this.fill();
if (this.picker.is(':visible')){ if (this.picker.is(':visible')){
e.preventDefault(); e.preventDefault();
if (typeof e.stopPropagation === 'function') {
e.stopPropagation(); // All modern browsers, IE9+
} else {
e.cancelBubble = true; // IE6,7,8 ignore "stopPropagation"
}
if (this.o.autoclose) if (this.o.autoclose)
this.hide(); this.hide();
} }
...@@ -1234,9 +1364,9 @@ ...@@ -1234,9 +1364,9 @@
this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir)); this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
} }
this.picker this.picker
.find('>div') .children('div')
.hide() .hide()
.filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName) .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
.css('display', 'block'); .css('display', 'block');
this.updateNavArrows(); this.updateNavArrows();
} }
...@@ -1249,9 +1379,8 @@ ...@@ -1249,9 +1379,8 @@
}); });
delete options.inputs; delete options.inputs;
$(this.inputs) datepickerPlugin.call($(this.inputs), options)
.datepicker(options) .on('changeDate', $.proxy(this.dateUpdated, this));
.bind('changeDate', $.proxy(this.dateUpdated, this));
this.pickers = $.map(this.inputs, function(i){ this.pickers = $.map(this.inputs, function(i){
return $(i).data('datepicker'); return $(i).data('datepicker');
...@@ -1284,6 +1413,8 @@ ...@@ -1284,6 +1413,8 @@
var dp = $(e.target).data('datepicker'), var dp = $(e.target).data('datepicker'),
new_date = dp.getUTCDate(), new_date = dp.getUTCDate(),
i = $.inArray(e.target, this.inputs), i = $.inArray(e.target, this.inputs),
j = i - 1,
k = i + 1,
l = this.inputs.length; l = this.inputs.length;
if (i === -1) if (i === -1)
return; return;
...@@ -1293,16 +1424,16 @@ ...@@ -1293,16 +1424,16 @@
p.setUTCDate(new_date); p.setUTCDate(new_date);
}); });
if (new_date < this.dates[i]){ if (new_date < this.dates[j]){
// Date being moved earlier/left // Date being moved earlier/left
while (i >= 0 && new_date < this.dates[i]){ while (j >= 0 && new_date < this.dates[j]){
this.pickers[i--].setUTCDate(new_date); this.pickers[j--].setUTCDate(new_date);
} }
} }
else if (new_date > this.dates[i]){ else if (new_date > this.dates[k]){
// Date being moved later/right // Date being moved later/right
while (i < l && new_date > this.dates[i]){ while (k < l && new_date > this.dates[k]){
this.pickers[i++].setUTCDate(new_date); this.pickers[k++].setUTCDate(new_date);
} }
} }
this.updateDates(); this.updateDates();
...@@ -1351,7 +1482,7 @@ ...@@ -1351,7 +1482,7 @@
} }
var old = $.fn.datepicker; var old = $.fn.datepicker;
$.fn.datepicker = function(option){ var datepickerPlugin = function(option){
var args = Array.apply(null, arguments); var args = Array.apply(null, arguments);
args.shift(); args.shift();
var internal_return; var internal_return;
...@@ -1366,7 +1497,7 @@ ...@@ -1366,7 +1497,7 @@
locopts = opts_from_locale(xopts.language), locopts = opts_from_locale(xopts.language),
// Options priority: js args, data-attrs, locales, defaults // Options priority: js args, data-attrs, locales, defaults
opts = $.extend({}, defaults, locopts, elopts, options); opts = $.extend({}, defaults, locopts, elopts, options);
if ($this.is('.input-daterange') || opts.inputs){ if ($this.hasClass('input-daterange') || opts.inputs){
var ropts = { var ropts = {
inputs: opts.inputs || $this.find('input').toArray() inputs: opts.inputs || $this.find('input').toArray()
}; };
...@@ -1387,13 +1518,17 @@ ...@@ -1387,13 +1518,17 @@
else else
return this; return this;
}; };
$.fn.datepicker = datepickerPlugin;
var defaults = $.fn.datepicker.defaults = { var defaults = $.fn.datepicker.defaults = {
autoclose: false, autoclose: false,
beforeShowDay: $.noop, beforeShowDay: $.noop,
beforeShowMonth: $.noop,
calendarWeeks: false, calendarWeeks: false,
clearBtn: false, clearBtn: false,
toggleActive: false,
daysOfWeekDisabled: [], daysOfWeekDisabled: [],
datesDisabled: [],
endDate: Infinity, endDate: Infinity,
forceParse: true, forceParse: true,
format: 'mm/dd/yyyy', format: 'mm/dd/yyyy',
...@@ -1408,7 +1543,11 @@ ...@@ -1408,7 +1543,11 @@
startView: 0, startView: 0,
todayBtn: false, todayBtn: false,
todayHighlight: false, todayHighlight: false,
weekStart: 0 weekStart: 0,
disableTouchKeyboard: false,
enableOnReadonly: true,
container: 'body',
immediateUpdates: false
}; };
var locale_opts = $.fn.datepicker.locale_opts = [ var locale_opts = $.fn.datepicker.locale_opts = [
'format', 'format',
...@@ -1536,7 +1675,7 @@ ...@@ -1536,7 +1675,7 @@
function match_part(){ function match_part(){
var m = this.slice(0, parts[i].length), var m = this.slice(0, parts[i].length),
p = parts[i].slice(0, m.length); p = parts[i].slice(0, m.length);
return m === p; return m.toLowerCase() === p.toLowerCase();
} }
if (parts.length === fparts.length){ if (parts.length === fparts.length){
var cnt; var cnt;
...@@ -1598,9 +1737,9 @@ ...@@ -1598,9 +1737,9 @@
}, },
headTemplate: '<thead>'+ headTemplate: '<thead>'+
'<tr>'+ '<tr>'+
'<th class="prev">&laquo;</th>'+ '<th class="prev">&#171;</th>'+
'<th colspan="5" class="datepicker-switch"></th>'+ '<th colspan="5" class="datepicker-switch"></th>'+
'<th class="next">&raquo;</th>'+ '<th class="next">&#187;</th>'+
'</tr>'+ '</tr>'+
'</thead>', '</thead>',
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>', contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
...@@ -1648,6 +1787,9 @@ ...@@ -1648,6 +1787,9 @@
return this; return this;
}; };
/* DATEPICKER VERSION
* =================== */
$.fn.datepicker.version = "1.4.1-dev";
/* DATEPICKER DATA-API /* DATEPICKER DATA-API
* ================== */ * ================== */
...@@ -1661,11 +1803,11 @@ ...@@ -1661,11 +1803,11 @@
return; return;
e.preventDefault(); e.preventDefault();
// component click requires us to explicitly show it // component click requires us to explicitly show it
$this.datepicker('show'); datepickerPlugin.call($this, 'show');
} }
); );
$(function(){ $(function(){
$('[data-provide="datepicker-inline"]').datepicker(); datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
}); });
}(window.jQuery)); }(window.jQuery));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment