123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107 |
- /*!
- * Pikaday
- *
- * Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
- */
- var pickers = {};
- var clLangs = {
- ua: {
- previousMonth : 'Попередній місяць',
- nextMonth : 'Наступний місяць',
- months : ['Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'],
- weekdays : ['Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П’ятниця', 'Субота'],
- weekdaysShort : ['Нд', 'Пн', 'Вв', 'Ср', 'Чт', 'Пт', 'Сб']
- },
- ru: {
- previousMonth : 'Предыдущий месяц',
- nextMonth : 'Следующий месяц',
- months : ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
- weekdays : ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
- weekdaysShort : ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
- },
- en: {
- previousMonth : 'Previous Month',
- nextMonth : 'Next Month',
- months : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- weekdays : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- weekdaysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
- }
- };
- function getDateParamBySign(date,sign){
- sign = sign.toUpperCase();
- var param;
- switch(sign){
- case "YYYY":
- param = date.getFullYear().toString();
- break;
- case "YY":
- param = date.getFullYear().toString().substr(2, 2);
- break;
- case "MM":
- param = (date.getMonth() + 1);
- param = (param >= 10) ? param.toString() : ("0" + param.toString());
- break;
- case "DD":
- param = (date.getDate() >= 10) ? date.getDate().toString() : ("0"+date.getDate().toString());
- break;
- default:
- param = date.toDateString();
- }
- return param;
- }
- function formatter(date, format){
- date = date || new Date();
- format = format || "DD.MM.YYYY";
- var signs = format.match(/(Y{2,4})|(M{2})|(D{2})/g);
- var params = [];
- var reStr = '';
- for(var i=0; i < signs.length; ++i){
- params.push(getDateParamBySign(date,signs[i]));
- reStr += ((i+1) != signs.length) ? signs[i] + "(.)" : signs[i];
- }
- var re = new RegExp(reStr, 'g');
- var delimiters = re.exec(format);
- delimiters.splice(0, 1);
- var value = "";
- for(i = 0; i < params.length; i++){
- value += ((i+1) != params.length) ? (params[i] + delimiters[i]) : params[i];
- }
- return value;
- }
- function parser(str, format){
- format = format || "DD.MM.YYYY";
- var signs = format.match(/(Y{2,4})|(M{2})|(D{2})/g);
- var reStr = "(";
- for(var i = 0; i < signs.length; ++i){
- reStr += ".".repeat(signs[i].length) + (((i+1) != signs.length) ? ").(" : ")");
- }
- var re = new RegExp(reStr, 'g');
- var values = re.exec(str);
- var year, month, day;
- if(values && signs.length + 1 == values.length){
- values = values.slice(1);
- for(var i = 0; i < signs.length; ++i){
- switch(signs[i].slice(0, 1)){
- case "Y":
- year = values[i];
- break;
- case "M":
- month = values[i];
- break;
- case "D":
- day = values[i];
- break;
- }
- }
- const res = new Date(year, month - 1, day);
- return res;
- }
- return null;
- }
- //function parseDateFromInput(value){
- // if(isNaN(Date.parse(value))){
- // var res = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/.exec(value);
- // if(res && res.length == 4){
- // return new Date(res[3], (res[2] - 1), res[1]);
- // }else{
- // return null;
- // }
- // }else{
- // return new Date(Date.parse(value));
- // }
- //}
- (function(root, factory){
- 'use strict';
- var moment;
- if(typeof exports === 'object'){
- // CommonJS module
- // Load moment.js as an optional dependency
- try{
- moment = require('moment');
- }catch(e){}
- module.exports = factory(moment);
- }else if(typeof define === 'function' && define.amd){
- // AMD. Register as an anonymous module.
- define(function(req){
- // Load moment.js as an optional dependency
- var id = 'moment';
- try{ moment = req(id); }catch(e){}
- return factory(moment);
- });
- }else{
- root.Pikaday = factory(root.moment);
- }
- }(this, function(moment){
- 'use strict';
- /**
- * feature detection and helper functions
- */
- var hasMoment = typeof moment === 'function',
- hasEventListeners = !!window.addEventListener,
- document = window.document,
- sto = window.setTimeout,
- addEvent = function(el, e, callback, capture){
- if(hasEventListeners){
- el.addEventListener(e, callback, !!capture);
- }else{
- el.attachEvent('on' + e, callback);
- }
- },
- removeEvent = function(el, e, callback, capture){
- if(hasEventListeners){
- el.removeEventListener(e, callback, !!capture);
- }else{
- el.detachEvent('on' + e, callback);
- }
- },
- fireEvent = function(el, eventName, data){
- var ev;
- if(document.createEvent){
- ev = document.createEvent('HTMLEvents');
- ev.initEvent(eventName, true, false);
- ev = extend(ev, data);
- el.dispatchEvent(ev);
- }else if(document.createEventObject){
- ev = document.createEventObject();
- ev = extend(ev, data);
- el.fireEvent('on' + eventName, ev);
- }
- },
- trim = function(str){
- return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
- },
- hasClass = function(el, cn){
- return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
- },
- addClass = function(el, cn){
- if(!hasClass(el, cn)){
- el.className = (el.className === '') ? cn : el.className + ' ' + cn;
- }
- },
- removeClass = function(el, cn){
- el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
- },
- isArray = function(obj){
- return (/Array/).test(Object.prototype.toString.call(obj));
- },
- isDate = function(obj){
- return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
- },
- isWeekend = function(date){
- var day = date.getDay();
- return day === 0 || day === 6;
- },
- isLeapYear = function(year){
- // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
- return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
- },
- getDaysInMonth = function(year, month){
- return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
- },
- setToStartOfDay = function(date){
- if(isDate(date)) date.setHours(0, 0, 0, 0);
- },
- compareDates = function(a,b){
- // weak date comparison (use setToStartOfDay(date) to ensure correct result)
- return a.getTime() === b.getTime();
- },
- extend = function(to, from, overwrite){
- var prop, hasProp;
- for(prop in from){
- hasProp = to[prop] !== undefined;
- if(hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined){
- if(isDate(from[prop])){
- if(overwrite){
- to[prop] = new Date(from[prop].getTime());
- }
- }else if(isArray(from[prop])){
- if(overwrite){
- to[prop] = from[prop].slice(0);
- }
- }else{
- to[prop] = extend({}, from[prop], overwrite);
- }
- }else if(overwrite || !hasProp){
- to[prop] = from[prop];
- }
- }
- return to;
- },
- adjustCalendar = function(calendar){
- if(calendar.month < 0){
- calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
- calendar.month += 12;
- }
- if(calendar.month > 11){
- calendar.year += Math.floor(Math.abs(calendar.month)/12);
- calendar.month -= 12;
- }
- return calendar;
- },
- /**
- * defaults and localisation
- */
- defaults = {
- // bind the picker to a form field
- field: null,
- // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
- bound: undefined,
- // position of the datepicker, relative to the field (default to bottom & left)
- // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
- position: 'bottom left',
- // automatically fit in the viewport even if it means repositioning from the position option
- reposition: true,
- // the default output format for `.toString()` and `field` value
- format: 'DD.MM.YYYY',
- // the initial date to view when first opened
- defaultDate: null,
- // make the `defaultDate` the initial selected value
- setDefaultDate: false,
- // first day of week (0: Sunday, 1: Monday etc)
- firstDay: 0,
- // the minimum/earliest date that can be selected
- minDate: null,
- // the maximum/latest date that can be selected
- maxDate: null,
- // number of years either side, or array of upper/lower range
- yearRange: 10,
- // show week numbers at head of row
- showWeekNumber: false,
- // used internally (don't config outside)
- minYear: 0,
- maxYear: 9999,
- minMonth: undefined,
- maxMonth: undefined,
- startRange: null,
- endRange: null,
- isRTL: false,
- // Additional text to append to the year in the calendar title
- yearSuffix: '',
- // Render the month after year in the calendar title
- showMonthAfterYear: false,
- // how many months are visible
- numberOfMonths: 1,
- // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
- // only used for the first display or when a selected date is not visible
- mainCalendar: 'left',
- // Specify a DOM element to render the calendar in
- container: undefined,
- // internationalization
- i18n: clLangs.en,
- // Theme Classname
- theme: null,
- // callback function
- onSelect: null,
- onOpen: null,
- onClose: null,
- onDraw: null
- },
- /**
- * templating functions to abstract HTML rendering
- */
- renderDayName = function(opts, day, abbr){
- day += opts.firstDay;
- while(day >= 7){
- day -= 7;
- }
- return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
- },
- renderDay = function(opts){
- if(opts.isEmpty){
- return '<td class="is-empty"></td>';
- }
- var arr = [];
- if(opts.isDisabled){
- arr.push('is-disabled');
- }
- if(opts.isToday){
- arr.push('is-today');
- }
- if(opts.isSelected){
- arr.push('is-selected');
- }
- if(opts.isInRange){
- arr.push('is-inrange');
- }
- if(opts.isStartRange){
- arr.push('is-startrange');
- }
- if(opts.isEndRange){
- arr.push('is-endrange');
- }
- return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '">' +
- '<button class="pika-button pika-day" type="button" ' +
- 'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
- opts.day +
- '</button>' +
- '</td>';
- },
- renderWeek = function(d, m, y){
- // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
- var onejan = new Date(y, 0, 1),
- weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay() + 1) / 7);
- return '<td class="pika-week">' + weekNum + '</td>';
- },
- renderRow = function(days, isRTL){
- return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
- },
- renderBody = function(rows){
- return '<tbody>' + rows.join('') + '</tbody>';
- },
- renderHead = function(opts){
- var i, arr = [];
- if(opts.showWeekNumber){
- arr.push('<th></th>');
- }
- for(i = 0; i < 7; i++){
- arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
- }
- return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>';
- },
- renderTitle = function(instance, c, year, month, refYear){
- var i, j, arr,
- opts = instance._o,
- isMinYear = year === opts.minYear,
- isMaxYear = year === opts.maxYear,
- html = '<div class="pika-title">',
- monthHtml,
- yearHtml,
- prev = true,
- next = true;
- for(arr = [], i = 0; i < 12; i++){
- arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
- (i === month ? ' selected': '') +
- ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' +
- opts.i18n.months[i] + '</option>');
- }
- monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';
- if(isArray(opts.yearRange)){
- i = opts.yearRange[0];
- j = opts.yearRange[1] + 1;
- }else{
- i = year - opts.yearRange;
- j = 1 + year + opts.yearRange;
- }
- for(arr = []; i < j && i <= opts.maxYear; i++){
- if(i >= opts.minYear){
- arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>');
- }
- }
- yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';
- if(opts.showMonthAfterYear){
- html += yearHtml + monthHtml;
- }else{
- html += monthHtml + yearHtml;
- }
- if(isMinYear && (month === 0 || opts.minMonth >= month)){
- prev = false;
- }
- if(isMaxYear && (month === 11 || opts.maxMonth <= month)){
- next = false;
- }
- if(c === 0){
- html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
- }
- if(c === (instance._o.numberOfMonths - 1)){
- html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
- }
- return html += '</div>';
- },
- renderTable = function(opts, data){
- return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>';
- },
- /**
- * Pikaday constructor
- */
- Pikaday = function(options){
- var self = this,
- opts = self.config(options);
- self._onMouseDown = function(e){
- if(!self._v){
- return;
- }
- e = e || window.event;
- var target = e.target || e.srcElement;
- console.log(target);
- if(!target){
- return;
- }
- if(!hasClass(target.parentNode, 'is-disabled')){
- if(hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')){
- self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
- if(opts.bound){
- sto(function(){
- self.hide();
- if(opts.field){
- opts.field.blur();
- }
- }, 100);
- }
- }else if(hasClass(target, 'pika-prev')){
- self.prevMonth();
- }else if(hasClass(target, 'pika-next')){
- self.nextMonth();
- }
- }
- if(!hasClass(target, 'pika-select')){
- // if this is touch event prevent mouse events emulation
- if(e.preventDefault){
- e.preventDefault();
- }else{
- e.returnValue = false;
- return false;
- }
- }else{
- self._c = true;
- }
- };
- self._onChange = function(e){
- e = e || window.event;
- var target = e.target || e.srcElement;
- if(!target){
- return;
- }
- if(hasClass(target, 'pika-select-month')){
- self.gotoMonth(target.value);
- }else if(hasClass(target, 'pika-select-year')){
- self.gotoYear(target.value);
- }
- };
- self._onInputChange = function(e){
- var date;
- if(e.firedBy === self){
- return;
- }
- if(hasMoment){
- date = moment(opts.field.value, opts.format);
- date = (date && date.isValid()) ? date.toDate() : null;
- }else{
- //date = parseDateFromInput(opts.field.value);
- date = parser(opts.field.value, opts.format);
- }
- if(isDate(date)){
- self.setDate(date);
- }else{
- self.setDate(null);
- }
- if(!self._v){
- self.show();
- }
- };
- self._onInputFocus = function(){
- self.show();
- };
- self._onInputClick = function(){
- self.show();
- };
- self._onInputBlur = function(){
- // IE allows pika div to gain focus; catch blur the input field
- var pEl = document.activeElement;
- do{
- if(hasClass(pEl, 'pika-single')){
- return;
- }
- }while((pEl = pEl.parentNode));
- if(!self._c){
- self._b = sto(function(){
- self.hide();
- }, 50);
- }
- self._c = false;
- };
- self._onClick = function(e){
- e = e || window.event;
- var target = e.target || e.srcElement,
- pEl = target;
- if(!target){
- return;
- }
- if(!hasEventListeners && hasClass(target, 'pika-select')){
- if(!target.onchange){
- target.setAttribute('onchange', 'return;');
- addEvent(target, 'change', self._onChange);
- }
- }
- do{
- if(hasClass(pEl, 'pika-single') || pEl === opts.trigger){
- return;
- }
- }while((pEl = pEl.parentNode));
- if(self._v && target !== opts.trigger && pEl !== opts.trigger){
- self.hide();
- }
- };
- self.el = document.createElement('div');
- self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');
- addEvent(self.el, 'mousedown', self._onMouseDown, true);
- addEvent(self.el, 'touchend', self._onMouseDown, true);
- addEvent(self.el, 'change', self._onChange);
- if(opts.field){
- if(opts.container){
- opts.container.appendChild(self.el);
- }else if(opts.bound){
- document.body.appendChild(self.el);
- }else{
- opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
- }
- addEvent(opts.field, 'change', self._onInputChange);
- if(!opts.defaultDate){
- if(hasMoment && opts.field.value){
- opts.defaultDate = moment(opts.field.value, opts.format).toDate();
- }else{
- opts.defaultDate = new Date(Date.parse(opts.field.value));
- }
- opts.setDefaultDate = true;
- }
- }
- var defDate = opts.defaultDate;
- if(isDate(defDate)){
- if(opts.setDefaultDate){
- self.setDate(defDate, true);
- }else{
- self.gotoDate(defDate);
- }
- }else{
- self.gotoDate(new Date());
- }
- if(opts.bound){
- this.hide();
- self.el.className += ' is-bound';
- addEvent(opts.trigger, 'click', self._onInputClick);
- addEvent(opts.trigger, 'focus', self._onInputFocus);
- addEvent(opts.trigger, 'blur', self._onInputBlur);
- }else{
- this.show();
- }
- };
- /**
- * public Pikaday API
- */
- Pikaday.prototype = {
- /**
- * configure functionality
- */
- config: function(options){
- if(!this._o){
- this._o = extend({}, defaults, true);
- }
- var opts = extend(this._o, options, true);
- opts.isRTL = !!opts.isRTL;
- opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
- opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;
- opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
- opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;
- opts.disableWeekends = !!opts.disableWeekends;
- opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;
- var nom = parseInt(opts.numberOfMonths, 10) || 1;
- opts.numberOfMonths = nom > 4 ? 4 : nom;
- if(!isDate(opts.minDate)){
- opts.minDate = false;
- }
- if(!isDate(opts.maxDate)){
- opts.maxDate = false;
- }
- if((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate){
- opts.maxDate = opts.minDate = false;
- }
- if(opts.minDate){
- this.setMinDate(opts.minDate);
- }
- if(opts.maxDate){
- setToStartOfDay(opts.maxDate);
- opts.maxYear = opts.maxDate.getFullYear();
- opts.maxMonth = opts.maxDate.getMonth();
- }
- if(isArray(opts.yearRange)){
- var fallback = new Date().getFullYear() - 10;
- opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
- opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
- }else{
- opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
- if(opts.yearRange > 100){
- opts.yearRange = 100;
- }
- }
- return opts;
- },
- /**
- * return a formatted string of the current selection (using Moment.js if available or default formatter)
- */
- toString: function(format){
- return !isDate(this._d) ? '' : (hasMoment) ? moment(this._d).format(format || this._o.format) : formatter(this._d,this._o.format);
- },
- /**
- * return a Moment.js object of the current selection (if available)
- */
- getMoment: function(){
- return hasMoment ? moment(this._d) : null;
- },
- /**
- * set the current selection from a Moment.js object (if available)
- */
- setMoment: function(date, preventOnSelect){
- if(hasMoment && moment.isMoment(date)){
- this.setDate(date.toDate(), preventOnSelect);
- }
- },
- /**
- * return a Date object of the current selection
- */
- getDate: function(){
- return isDate(this._d) ? new Date(this._d.getTime()) : null;
- },
- /**
- * set the current selection
- */
- setDate: function(date, preventOnSelect){
- if(!date){
- this._d = null;
- if(this._o.field){
- this._o.field.value = '';
- fireEvent(this._o.field, 'change', { firedBy: this });
- }
- return this.draw();
- }
- if(typeof date === 'string'){
- date = new Date(Date.parse(date));
- }
- if(!isDate(date)){
- return;
- }
- var min = this._o.minDate,
- max = this._o.maxDate;
- if (isDate(min) && date < min){
- date = min;
- }else if(isDate(max) && date > max){
- date = max;
- }
- this._d = new Date(date.getTime());
- setToStartOfDay(this._d);
- this.gotoDate(this._d);
- if(this._o.field){
- this._o.field.value = this.toString();
- fireEvent(this._o.field, 'change', { firedBy: this });
- }
- if(!preventOnSelect && typeof this._o.onSelect === 'function'){
- this._o.onSelect.call(this, this.getDate());
- }
- },
- /**
- * change view to a specific date
- */
- gotoDate: function(date){
- var newCalendar = true;
- if(!isDate(date)){
- return;
- }
- if(this.calendars){
- var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
- lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
- visibleDate = date.getTime();
- // get the end of the month
- lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1);
- lastVisibleDate.setDate(lastVisibleDate.getDate() - 1);
- newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
- }
- if(newCalendar){
- this.calendars = [{
- month: date.getMonth(),
- year: date.getFullYear()
- }];
- if(this._o.mainCalendar === 'right'){
- this.calendars[0].month += 1 - this._o.numberOfMonths;
- }
- }
- this.adjustCalendars();
- },
- adjustCalendars: function(){
- this.calendars[0] = adjustCalendar(this.calendars[0]);
- for(var c = 1; c < this._o.numberOfMonths; c++){
- this.calendars[c] = adjustCalendar({
- month: this.calendars[0].month + c,
- year: this.calendars[0].year
- });
- }
- this.draw();
- },
- gotoToday: function(){
- this.gotoDate(new Date());
- },
- /**
- * change view to a specific month (zero-index, e.g. 0: January)
- */
- gotoMonth: function(month){
- if(!isNaN(month)){
- this.calendars[0].month = parseInt(month, 10);
- this.adjustCalendars();
- }
- },
- nextMonth: function(){
- this.calendars[0].month++;
- this.adjustCalendars();
- },
- prevMonth: function(){
- this.calendars[0].month--;
- this.adjustCalendars();
- },
- /**
- * change view to a specific full year (e.g. "2012")
- */
- gotoYear: function(year){
- if(!isNaN(year)){
- this.calendars[0].year = parseInt(year, 10);
- this.adjustCalendars();
- }
- },
- /**
- * change the minDate
- */
- setMinDate: function(value){
- setToStartOfDay(value);
- this._o.minDate = value;
- this._o.minYear = value.getFullYear();
- this._o.minMonth = value.getMonth();
- },
- /**
- * change the maxDate
- */
- setMaxDate: function(value){
- this._o.maxDate = value;
- },
- setStartRange: function(value){
- this._o.startRange = value;
- },
- setEndRange: function(value){
- this._o.endRange = value;
- },
- /**
- * refresh the HTML
- */
- draw: function(force){
- if(!this._v && !force){
- return;
- }
- var opts = this._o,
- minYear = opts.minYear,
- maxYear = opts.maxYear,
- minMonth = opts.minMonth,
- maxMonth = opts.maxMonth,
- html = '';
- if(this._y <= minYear){
- this._y = minYear;
- if(!isNaN(minMonth) && this._m < minMonth){
- this._m = minMonth;
- }
- }
- if(this._y >= maxYear){
- this._y = maxYear;
- if(!isNaN(maxMonth) && this._m > maxMonth){
- this._m = maxMonth;
- }
- }
- for(var c = 0; c < opts.numberOfMonths; c++){
- html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year) + this.render(this.calendars[c].year, this.calendars[c].month) + '</div>';
- }
- this.el.innerHTML = html;
- if(opts.bound){
- if(opts.field.type !== 'hidden'){
- sto(function(){
- opts.trigger.focus();
- }, 1);
- }
- }
- if(typeof this._o.onDraw === 'function'){
- var self = this;
- sto(function(){
- self._o.onDraw.call(self);
- }, 0);
- }
- },
- adjustPosition: function(){
- var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;
- if(this._o.container) return;
- this.el.style.position = 'absolute';
- field = this._o.trigger;
- pEl = field;
- width = this.el.offsetWidth;
- height = this.el.offsetHeight;
- viewportWidth = window.innerWidth || document.documentElement.clientWidth;
- viewportHeight = window.innerHeight || document.documentElement.clientHeight;
- scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
- if(typeof field.getBoundingClientRect === 'function'){
- clientRect = field.getBoundingClientRect();
- left = clientRect.left + window.pageXOffset;
- top = clientRect.bottom + window.pageYOffset;
- }else{
- left = pEl.offsetLeft;
- top = pEl.offsetTop + pEl.offsetHeight;
- while((pEl = pEl.offsetParent)){
- left += pEl.offsetLeft;
- top += pEl.offsetTop;
- }
- }
- // default position is bottom & left
- if((this._o.reposition && left + width > viewportWidth) ||
- (this._o.position.indexOf('right') > -1 &&
- left - width + field.offsetWidth > 0)){
- left = left - width + field.offsetWidth;
- }
- if((this._o.reposition && top + height > viewportHeight + scrollTop) ||
- (this._o.position.indexOf('top') > -1 &&
- top - height - field.offsetHeight > 0)){
- top = top - height - field.offsetHeight;
- }
- this.el.style.left = left + 'px';
- this.el.style.top = top + 'px';
- },
- /**
- * render HTML for a particular month
- */
- render: function(year, month){
- var opts = this._o,
- now = new Date(),
- days = getDaysInMonth(year, month),
- before = new Date(year, month, 1).getDay(),
- data = [],
- row = [];
- setToStartOfDay(now);
- if(opts.firstDay > 0){
- before -= opts.firstDay;
- if(before < 0){
- before += 7;
- }
- }
- var cells = days + before,
- after = cells;
- while(after > 7){
- after -= 7;
- }
- cells += 7 - after;
- for(var i = 0, r = 0; i < cells; i++){
- var day = new Date(year, month, 1 + (i - before)),
- isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
- isToday = compareDates(day, now),
- isEmpty = i < before || i >= (days + before),
- isStartRange = opts.startRange && compareDates(opts.startRange, day),
- isEndRange = opts.endRange && compareDates(opts.endRange, day),
- isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
- isDisabled = (opts.minDate && day < opts.minDate) ||
- (opts.maxDate && day > opts.maxDate) ||
- (opts.disableWeekends && isWeekend(day)) ||
- (opts.disableDayFn && opts.disableDayFn(day)),
- dayConfig = {
- day: 1 + (i - before),
- month: month,
- year: year,
- isSelected: isSelected,
- isToday: isToday,
- isDisabled: isDisabled,
- isEmpty: isEmpty,
- isStartRange: isStartRange,
- isEndRange: isEndRange,
- isInRange: isInRange
- };
- row.push(renderDay(dayConfig));
- if(++r === 7){
- if(opts.showWeekNumber){
- row.unshift(renderWeek(i - before, month, year));
- }
- data.push(renderRow(row, opts.isRTL));
- row = [];
- r = 0;
- }
- }
- return renderTable(opts, data);
- },
- isVisible: function(){
- return this._v;
- },
- show: function(){
- if(!this._v){
- removeClass(this.el, 'is-hidden');
- this._v = true;
- this.draw();
- if(this._o.bound){
- addEvent(document, 'click', this._onClick);
- this.adjustPosition();
- }
- if(typeof this._o.onOpen === 'function'){
- this._o.onOpen.call(this);
- }
- }
- },
- hide: function(){
- var v = this._v;
- if(v !== false){
- if(this._o.bound){
- removeEvent(document, 'click', this._onClick);
- }
- this.el.style.position = 'static'; // reset
- this.el.style.left = 'auto';
- this.el.style.top = 'auto';
- addClass(this.el, 'is-hidden');
- this._v = false;
- if(v !== undefined && typeof this._o.onClose === 'function'){
- this._o.onClose.call(this);
- }
- }
- },
- /**
- * GAME OVER
- */
- destroy: function(){
- this.hide();
- removeEvent(this.el, 'mousedown', this._onMouseDown, true);
- removeEvent(this.el, 'touchend', this._onMouseDown, true);
- removeEvent(this.el, 'change', this._onChange);
- if(this._o.field){
- removeEvent(this._o.field, 'change', this._onInputChange);
- if(this._o.bound){
- removeEvent(this._o.trigger, 'click', this._onInputClick);
- removeEvent(this._o.trigger, 'focus', this._onInputFocus);
- removeEvent(this._o.trigger, 'blur', this._onInputBlur);
- }
- }
- if(this.el.parentNode){
- this.el.parentNode.removeChild(this.el);
- }
- }
- };
- return Pikaday;
- }));
|