/* =========================================================
* bootstrap-datepicker.js
* http://www.eyecon.ro/bootstrap-datepicker
* =========================================================
* copyright 2012 stefan petre
*
* licensed under the apache license, version 2.0 (the "license");
* you may not use this file except in compliance with the license.
* you may obtain a copy of the license at
*
* 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( $ ) {
// picker object
var datepicker = function(element, options){
this.element = $(element);
this.format = dpglobal.parseformat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
this.picker = $(dpglobal.template)
.appendto('body')
.on({
click: $.proxy(this.click, this)//,
//mousedown: $.proxy(this.mousedown, this)
});
this.isinput = this.element.is('input');
this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
if (this.isinput) {
this.element.on({
focus: $.proxy(this.show, this),
//blur: $.proxy(this.hide, this),
keyup: $.proxy(this.update, this)
});
} else {
if (this.component){
this.component.on('click', $.proxy(this.show, this));
} else {
this.element.on('click', $.proxy(this.show, this));
}
}
this.minviewmode = options.minviewmode||this.element.data('date-minviewmode')||0;
if (typeof this.minviewmode === 'string') {
switch (this.minviewmode) {
case 'months':
this.minviewmode = 1;
break;
case 'years':
this.minviewmode = 2;
break;
default:
this.minviewmode = 0;
break;
}
}
this.viewmode = options.viewmode||this.element.data('date-viewmode')||0;
if (typeof this.viewmode === 'string') {
switch (this.viewmode) {
case 'months':
this.viewmode = 1;
break;
case 'years':
this.viewmode = 2;
break;
default:
this.viewmode = 0;
break;
}
}
this.startviewmode = this.viewmode;
this.weekstart = options.weekstart||this.element.data('date-weekstart')||0;
this.weekend = this.weekstart === 0 ? 6 : this.weekstart - 1;
this.onrender = options.onrender;
this.filldow();
this.fillmonths();
this.update();
this.showmode();
};
datepicker.prototype = {
constructor: datepicker,
show: function(e) {
this.picker.show();
this.height = this.component ? this.component.outerheight() : this.element.outerheight();
this.place();
$(window).on('resize', $.proxy(this.place, this));
if (e ) {
e.stoppropagation();
e.preventdefault();
}
if (!this.isinput) {
}
var that = this;
$(document).on('mousedown', function(ev){
if ($(ev.target).closest('.datepicker').length == 0) {
that.hide();
}
});
this.element.trigger({
type: 'show',
date: this.date
});
},
hide: function(){
this.picker.hide();
$(window).off('resize', this.place);
this.viewmode = this.startviewmode;
this.showmode();
if (!this.isinput) {
$(document).off('mousedown', this.hide);
}
//this.set();
this.element.trigger({
type: 'hide',
date: this.date
});
},
set: function() {
var formated = dpglobal.formatdate(this.date, this.format);
if (!this.isinput) {
if (this.component){
this.element.find('input').prop('value', formated);
}
this.element.data('date', formated);
} else {
this.element.prop('value', formated);
}
},
setvalue: function(newdate) {
if (typeof newdate === 'string') {
this.date = dpglobal.parsedate(newdate, this.format);
} else {
this.date = new date(newdate);
}
this.set();
this.viewdate = new date(this.date.getfullyear(), this.date.getmonth(), 1, 0, 0, 0, 0);
this.fill();
},
place: function(){
var offset = this.component ? this.component.offset() : this.element.offset();
this.picker.css({
top: offset.top + this.height,
left: offset.left
});
},
update: function(newdate){
this.date = dpglobal.parsedate(
typeof newdate === 'string' ? newdate : (this.isinput ? this.element.prop('value') : this.element.data('date')),
this.format
);
this.viewdate = new date(this.date.getfullyear(), this.date.getmonth(), 1, 0, 0, 0, 0);
this.fill();
},
filldow: function(){
var dowcnt = this.weekstart;
var html = '
';
while (dowcnt < this.weekstart + 7) {
html += ''+dpglobal.dates.daysmin[(dowcnt++)%7]+' | ';
}
html += '
';
this.picker.find('.datepicker-days thead').append(html);
},
fillmonths: function(){
var html = '';
var i = 0
while (i < 12) {
html += ''+dpglobal.dates.monthsshort[i++]+'';
}
this.picker.find('.datepicker-months td').append(html);
},
fill: function() {
var d = new date(this.viewdate),
year = d.getfullyear(),
month = d.getmonth(),
currentdate = this.date.valueof();
this.picker.find('.datepicker-days th:eq(1)')
.text(dpglobal.dates.months[month]+' '+year);
var prevmonth = new date(year, month-1, 28,0,0,0,0),
day = dpglobal.getdaysinmonth(prevmonth.getfullyear(), prevmonth.getmonth());
prevmonth.setdate(day);
prevmonth.setdate(day - (prevmonth.getday() - this.weekstart + 7)%7);
var nextmonth = new date(prevmonth);
nextmonth.setdate(nextmonth.getdate() + 42);
nextmonth = nextmonth.valueof();
var html = [];
var clsname,
prevy,
prevm;
while(prevmonth.valueof() < nextmonth) {
if (prevmonth.getday() === this.weekstart) {
html.push('');
}
clsname = this.onrender(prevmonth);
prevy = prevmonth.getfullyear();
prevm = prevmonth.getmonth();
if ((prevm < month && prevy === year) || prevy < year) {
clsname += ' old';
} else if ((prevm > month && prevy === year) || prevy > year) {
clsname += ' new';
}
if (prevmonth.valueof() === currentdate) {
clsname += ' active';
}
html.push(''+prevmonth.getdate() + ' | ');
if (prevmonth.getday() === this.weekend) {
html.push('
');
}
prevmonth.setdate(prevmonth.getdate()+1);
}
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
var currentyear = this.date.getfullyear();
var months = this.picker.find('.datepicker-months')
.find('th:eq(1)')
.text(year)
.end()
.find('span').removeclass('active');
if (currentyear === year) {
months.eq(this.date.getmonth()).addclass('active');
}
html = '';
year = parseint(year/10, 10) * 10;
var yearcont = this.picker.find('.datepicker-years')
.find('th:eq(1)')
.text(year + '-' + (year + 9))
.end()
.find('td');
year -= 1;
for (var i = -1; i < 11; i++) {
html += ''+year+'';
year += 1;
}
yearcont.html(html);
},
click: function(e) {
e.stoppropagation();
e.preventdefault();
var target = $(e.target).closest('span, td, th');
if (target.length === 1) {
switch(target[0].nodename.tolowercase()) {
case 'th':
switch(target[0].classname) {
case 'switch':
this.showmode(1);
break;
case 'prev':
case 'next':
this.viewdate['set'+dpglobal.modes[this.viewmode].navfnc].call(
this.viewdate,
this.viewdate['get'+dpglobal.modes[this.viewmode].navfnc].call(this.viewdate) +
dpglobal.modes[this.viewmode].navstep * (target[0].classname === 'prev' ? -1 : 1)
);
this.fill();
this.set();
break;
}
break;
case 'span':
if (target.is('.month')) {
var month = target.parent().find('span').index(target);
this.viewdate.setmonth(month);
} else {
var year = parseint(target.text(), 10)||0;
this.viewdate.setfullyear(year);
}
if (this.viewmode !== 0) {
this.date = new date(this.viewdate);
this.element.trigger({
type: 'changedate',
date: this.date,
viewmode: dpglobal.modes[this.viewmode].clsname
});
}
this.showmode(-1);
this.fill();
this.set();
break;
case 'td':
if (target.is('.day') && !target.is('.disabled')){
var day = parseint(target.text(), 10)||1;
var month = this.viewdate.getmonth();
if (target.is('.old')) {
month -= 1;
} else if (target.is('.new')) {
month += 1;
}
var year = this.viewdate.getfullyear();
this.date = new date(year, month, day,0,0,0,0);
this.viewdate = new date(year, month, math.min(28, day),0,0,0,0);
this.fill();
this.set();
this.element.trigger({
type: 'changedate',
date: this.date,
viewmode: dpglobal.modes[this.viewmode].clsname
});
}
break;
}
}
},
mousedown: function(e){
e.stoppropagation();
e.preventdefault();
},
showmode: function(dir) {
if (dir) {
this.viewmode = math.max(this.minviewmode, math.min(2, this.viewmode + dir));
}
this.picker.find('>div').hide().filter('.datepicker-'+dpglobal.modes[this.viewmode].clsname).show();
}
};
$.fn.datepicker = function ( option, val ) {
return this.each(function () {
var $this = $(this),
data = $this.data('datepicker'),
options = typeof option === 'object' && option;
if (!data) {
$this.data('datepicker', (data = new datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
}
if (typeof option === 'string') data[option](val);
});
};
$.fn.datepicker.defaults = {
onrender: function(date) {
return '';
}
};
$.fn.datepicker.constructor = datepicker;
var dpglobal = {
modes: [
{
clsname: 'days',
navfnc: 'month',
navstep: 1
},
{
clsname: 'months',
navfnc: 'fullyear',
navstep: 1
},
{
clsname: 'years',
navfnc: 'fullyear',
navstep: 10
}],
dates:{
days: ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"],
daysshort: ["sun", "mon", "tue", "wed", "thu", "fri", "sat", "sun"],
daysmin: ["su", "mo", "tu", "we", "th", "fr", "sa", "su"],
months: ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"],
monthsshort: ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"]
},
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]
},
parseformat: function(format){
var separator = format.match(/[.\/\-\s].*?/),
parts = format.split(/\w+/);
if (!separator || !parts || parts.length === 0){
throw new error("invalid date format.");
}
return {separator: separator, parts: parts};
},
parsedate: function(date, format) {
var parts = date.split(format.separator),
date = new date(),
val;
date.sethours(0);
date.setminutes(0);
date.setseconds(0);
date.setmilliseconds(0);
if (parts.length === format.parts.length) {
var year = date.getfullyear(), day = date.getdate(), month = date.getmonth();
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
val = parseint(parts[i], 10)||1;
switch(format.parts[i]) {
case 'dd':
case 'd':
day = val;
date.setdate(val);
break;
case 'mm':
case 'm':
month = val - 1;
date.setmonth(val - 1);
break;
case 'yy':
year = 2000 + val;
date.setfullyear(2000 + val);
break;
case 'yyyy':
year = val;
date.setfullyear(val);
break;
}
}
date = new date(year, month, day, 0 ,0 ,0);
}
return date;
},
formatdate: function(date, format){
var val = {
d: date.getdate(),
m: date.getmonth() + 1,
yy: date.getfullyear().tostring().substring(2),
yyyy: date.getfullyear()
};
val.dd = (val.d < 10 ? '0' : '') + val.d;
val.mm = (val.m < 10 ? '0' : '') + val.m;
var date = [];
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
date.push(val[format.parts[i]]);
}
return date.join(format.separator);
},
headtemplate: ''+
''+
'‹ | '+
' | '+
'› | '+
'
'+
'',
conttemplate: ' |
'
};
dpglobal.template = '';
}( window.jquery );