1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306 |
- /**
- * @license
- * =========================================================
- * bootstrap-datetimepicker.js
- * http://www.eyecon.ro/bootstrap-datepicker
- * =========================================================
- * Copyright 2012 Stefan Petre
- *
- * Contributions:
- * - Andrew Rowls
- * - Thiago de Arruda
- *
- * 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 smartPhone = (window.orientation != undefined);
- var DateTimePicker = function(element, options) {
- this.id = dpgId++;
- this.init(element, options);
- };
- var dateToDate = function(dt) {
- if (typeof dt === 'string') {
- return new Date(dt);
- }
- return dt;
- };
- DateTimePicker.prototype = {
- constructor: DateTimePicker,
- init: function(element, options) {
-
- dates = $.fn.datetimepicker.dates;
-
- var icon;
- if (!(options.pickTime || options.pickDate))
- throw new Error('Must choose at least one picker');
- this.options = options;
- this.$element = $(element);
- this.language = options.language in dates ? options.language : 'en'
- this.pickDate = options.pickDate;
- this.pickTime = options.pickTime;
- this.isInput = this.$element.is('input');
- this.component = false;
- this.showTimeFirst = options.showTimeFirst;
- if (this.$element.find('.input-append') || this.$element.find('.input-prepend'))
- this.component = this.$element.find('.add-on');
- this.format = options.format;
- if (!this.format) {
- if (this.isInput) this.format = this.$element.data('format');
- else this.format = this.$element.find('input').data('format');
- if (!this.format) this.format = 'MM/dd/yyyy';
- }
- this._compileFormat();
- if (this.component) {
- icon = this.component.find('i');
- }
- if (this.pickTime) {
- if (icon && icon.length) this.timeIcon = icon.data('time-icon');
- if (!this.timeIcon) this.timeIcon = 'icon-time';
- if (!this.dateIcon) this.dateIcon = 'icon-calendar';
- icon.addClass(this.timeIcon);
- }
- if (this.pickDate && (!this.showTimeFirst)) {
- if (icon && icon.length) this.dateIcon = icon.data('date-icon');
- if (!this.dateIcon) this.dateIcon = 'icon-calendar';
- icon.removeClass(this.timeIcon);
- icon.addClass(this.dateIcon);
- }
- this.widget = $(getTemplate(this.timeIcon, this.dateIcon, options.pickDate, options.pickTime, options.pick12HourFormat, options.pickSeconds, options.collapse, options.showTimeFirst)).appendTo('body');
- 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.setStartDate(options.startDate || this.$element.data('date-startdate'));
- this.setEndDate(options.endDate || this.$element.data('date-enddate'));
- this.fillDow();
- this.fillMonths();
- this.fillHours();
- this.fillMinutes();
- this.fillSeconds();
- this.update();
- this.showMode();
- this._attachDatePickerEvents();
- },
- show: function(e) {
- this.widget.show();
- this.height = this.component ? this.component.outerHeight() : this.$element.outerHeight();
- this.place();
- this.$element.trigger({
- type: 'show',
- date: this._date
- });
- this._attachDatePickerGlobalEvents();
- if (e) {
- e.stopPropagation();
- e.preventDefault();
- }
- },
- disable: function(){
- this.$element.find('input').prop('disabled',true);
- this._detachDatePickerEvents();
- },
- enable: function(){
- this.$element.find('input').prop('disabled',false);
- this._attachDatePickerEvents();
- },
- hide: function() {
- // Ignore event if in the middle of a picker transition
- var collapse = this.widget.find('.collapse')
- for (var i = 0; i < collapse.length; i++) {
- var collapseData = collapse.eq(i).data('collapse');
- if (collapseData && collapseData.transitioning)
- return;
- }
- this.widget.hide();
- this.viewMode = this.startViewMode;
- this.showMode();
- this.set();
- this.$element.trigger({
- type: 'hide',
- date: this._date
- });
- this._detachDatePickerGlobalEvents();
- },
- set: function() {
- var formatted = '';
- if (!this._unset) formatted = this.formatDate(this._date);
- if (!this.isInput) {
- if (this.component){
- var input = this.$element.find('input');
- input.val(formatted);
- this._resetMaskPos(input);
- }
- this.$element.data('date', formatted);
- } else {
- this.$element.val(formatted);
- this._resetMaskPos(this.$element);
- }
- },
- setValue: function(newDate) {
- if (!newDate) {
- this._unset = true;
- } else {
- this._unset = false;
- }
- if (typeof newDate === 'string') {
- this._date = this.parseDate(newDate);
- } else if(newDate) {
- this._date = new Date(newDate);
- }
- this.set();
- this.viewDate = UTCDate(this._date.getUTCFullYear(), this._date.getUTCMonth(), 1, 0, 0, 0, 0);
- this.fillDate();
- this.fillTime();
- },
- getDate: function() {
- if (this._unset) return null;
- return new Date(this._date.valueOf());
- },
- setDate: function(date) {
- if (!date) this.setValue(null);
- else this.setValue(date.valueOf());
- },
- setStartDate: function(date) {
- if (date instanceof Date) {
- this.startDate = date;
- } else if (typeof date === 'string') {
- this.startDate = new UTCDate(date);
- if (! this.startDate.getUTCFullYear()) {
- this.startDate = -Infinity;
- }
- } else {
- this.startDate = -Infinity;
- }
- if (this.viewDate) {
- this.update();
- }
- },
- setEndDate: function(date) {
- if (date instanceof Date) {
- this.endDate = date;
- } else if (typeof date === 'string') {
- this.endDate = new UTCDate(date);
- if (! this.endDate.getUTCFullYear()) {
- this.endDate = Infinity;
- }
- } else {
- this.endDate = Infinity;
- }
- if (this.viewDate) {
- this.update();
- }
- },
- getLocalDate: function() {
- if (this._unset) return null;
- var d = this._date;
- return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(),
- d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
- },
- setLocalDate: function(localDate) {
- if (!localDate) this.setValue(null);
- else
- this.setValue(Date.UTC(
- localDate.getFullYear(),
- localDate.getMonth(),
- localDate.getDate(),
- localDate.getHours(),
- localDate.getMinutes(),
- localDate.getSeconds(),
- localDate.getMilliseconds()));
- },
- place: function(){
- var position = 'absolute';
- var offset = this.component ? this.component.offset() : this.$element.offset();
- this.width = this.component ? this.component.outerWidth() : this.$element.outerWidth();
- offset.top = offset.top + this.height;
- var $window = $(window);
-
- if ( this.options.width != undefined ) {
- this.widget.width( this.options.width );
- }
-
- if ( this.options.orientation == 'left' ) {
- this.widget.addClass( 'left-oriented' );
- offset.left = offset.left - this.widget.width() + 20;
- }
-
- if (this._isInFixed()) {
- position = 'fixed';
- offset.top -= $window.scrollTop();
- offset.left -= $window.scrollLeft();
- }
- if ($window.width() < offset.left + this.widget.outerWidth()) {
- offset.right = $window.width() - offset.left - this.width;
- offset.left = 'auto';
- this.widget.addClass('pull-right');
- } else {
- offset.right = 'auto';
- this.widget.removeClass('pull-right');
- }
- this.widget.css({
- position: position,
- top: offset.top,
- left: offset.left,
- right: offset.right
- });
- },
- notifyChange: function(){
- this.$element.trigger({
- type: 'changeDate',
- date: this.getDate(),
- localDate: this.getLocalDate()
- });
- },
- update: function(newDate){
- var dateStr = newDate;
- if (!dateStr) {
- if (this.isInput) {
- dateStr = this.$element.val();
- } else {
- dateStr = this.$element.find('input').val();
- }
- if (dateStr) {
- this._date = this.parseDate(dateStr);
- }
- if (!this._date) {
- var tmp = new Date()
- this._date = UTCDate(tmp.getFullYear(),
- tmp.getMonth(),
- tmp.getDate(),
- tmp.getHours(),
- tmp.getMinutes(),
- tmp.getSeconds(),
- tmp.getMilliseconds())
- }
- }
- this.viewDate = UTCDate(this._date.getUTCFullYear(), this._date.getUTCMonth(), 1, 0, 0, 0, 0);
- this.fillDate();
- this.fillTime();
- },
- fillDow: function() {
- var dowCnt = this.weekStart;
- var html = $('<tr>');
- while (dowCnt < this.weekStart + 7) {
- html.append('<th class="dow">' + dates.daysMin[(dowCnt++) % 7] + '</th>');
- }
- this.widget.find('.datepicker-days thead').append(html);
- },
- fillMonths: function() {
- var html = '';
- var i = 0
- while (i < 12) {
- html += '<span class="month">' + dates.monthsShort[i++] + '</span>';
- }
- this.widget.find('.datepicker-months td').append(html);
- },
- fillDate: function() {
- var year = this.viewDate.getUTCFullYear();
- var month = this.viewDate.getUTCMonth();
- var currentDate = UTCDate(
- this._date.getUTCFullYear(),
- this._date.getUTCMonth(),
- this._date.getUTCDate(),
- 0, 0, 0, 0
- );
- var startYear = typeof this.startDate === 'object' ? this.startDate.getUTCFullYear() : -Infinity;
- var startMonth = typeof this.startDate === 'object' ? this.startDate.getUTCMonth() : -1;
- var endYear = typeof this.endDate === 'object' ? this.endDate.getUTCFullYear() : Infinity;
- var endMonth = typeof this.endDate === 'object' ? this.endDate.getUTCMonth() : 12;
- this.widget.find('.datepicker-days').find('.disabled').removeClass('disabled');
- this.widget.find('.datepicker-months').find('.disabled').removeClass('disabled');
- this.widget.find('.datepicker-years').find('.disabled').removeClass('disabled');
- this.widget.find('.datepicker-days th:eq(1)').text(
- dates.months[month] + ' ' + year);
- var prevMonth = UTCDate(year, month-1, 28, 0, 0, 0, 0);
- var day = DPGlobal.getDaysInMonth(
- prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
- prevMonth.setUTCDate(day);
- prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7);
- if ((year == startYear && month <= startMonth) || year < startYear) {
- this.widget.find('.datepicker-days th:eq(0)').addClass('disabled');
- }
- if ((year == endYear && month >= endMonth) || year > endYear) {
- this.widget.find('.datepicker-days th:eq(2)').addClass('disabled');
- }
- var nextMonth = new Date(prevMonth.valueOf());
- nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
- nextMonth = nextMonth.valueOf();
- var html = [];
- var row;
- var clsName;
- while (prevMonth.valueOf() < nextMonth) {
- if (prevMonth.getUTCDay() === this.weekStart) {
- row = $('<tr>');
- html.push(row);
- }
- clsName = '';
- if (prevMonth.getUTCFullYear() < year ||
- (prevMonth.getUTCFullYear() == year &&
- prevMonth.getUTCMonth() < month)) {
- clsName += ' old';
- } else if (prevMonth.getUTCFullYear() > year ||
- (prevMonth.getUTCFullYear() == year &&
- prevMonth.getUTCMonth() > month)) {
- clsName += ' new';
- }
- if (prevMonth.valueOf() === currentDate.valueOf()) {
- clsName += ' active';
- }
- if ((prevMonth.valueOf() + 86400000) <= this.startDate) {
- clsName += ' disabled';
- }
- if (prevMonth.valueOf() > this.endDate) {
- clsName += ' disabled';
- }
- row.append('<td class="day' + clsName + '">' + prevMonth.getUTCDate() + '</td>');
- prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
- }
- this.widget.find('.datepicker-days tbody').empty().append(html);
- var currentYear = this._date.getUTCFullYear();
- var months = this.widget.find('.datepicker-months').find(
- 'th:eq(1)').text(year).end().find('span').removeClass('active');
- if (currentYear === year) {
- months.eq(this._date.getUTCMonth()).addClass('active');
- }
- if (currentYear - 1 < startYear) {
- this.widget.find('.datepicker-months th:eq(0)').addClass('disabled');
- }
- if (currentYear + 1 > endYear) {
- this.widget.find('.datepicker-months th:eq(2)').addClass('disabled');
- }
- for (var i = 0; i < 12; i++) {
- if ((year == startYear && startMonth > i) || (year < startYear)) {
- $(months[i]).addClass('disabled');
- } else if ((year == endYear && endMonth < i) || (year > endYear)) {
- $(months[i]).addClass('disabled');
- }
- }
- html = '';
- year = parseInt(year/10, 10) * 10;
- var yearCont = this.widget.find('.datepicker-years').find(
- 'th:eq(1)').text(year + '-' + (year + 9)).end().find('td');
- this.widget.find('.datepicker-years').find('th').removeClass('disabled');
- if (startYear > year) {
- this.widget.find('.datepicker-years').find('th:eq(0)').addClass('disabled');
- }
- if (endYear < year+9) {
- this.widget.find('.datepicker-years').find('th:eq(2)').addClass('disabled');
- }
- year -= 1;
- for (var i = -1; i < 11; i++) {
- html += '<span class="year' + (i === -1 || i === 10 ? ' old' : '') + (currentYear === year ? ' active' : '') + ((year < startYear || year > endYear) ? ' disabled' : '') + '">' + year + '</span>';
- year += 1;
- }
- yearCont.html(html);
- },
- fillHours: function() {
- var table = this.widget.find(
- '.timepicker .timepicker-hours table');
- table.parent().hide();
- var html = '';
- if (this.options.pick12HourFormat) {
- var current = 1;
- for (var i = 0; i < 3; i += 1) {
- html += '<tr>';
- for (var j = 0; j < 4; j += 1) {
- var c = current.toString();
- html += '<td class="hour">' + padLeft(c, 2, '0') + '</td>';
- current++;
- }
- html += '</tr>'
- }
- } else {
- var current = 0;
- for (var i = 0; i < 6; i += 1) {
- html += '<tr>';
- for (var j = 0; j < 4; j += 1) {
- var c = current.toString();
- html += '<td class="hour">' + padLeft(c, 2, '0') + '</td>';
- current++;
- }
- html += '</tr>'
- }
- }
- table.html(html);
- },
- fillMinutes: function() {
- var table = this.widget.find(
- '.timepicker .timepicker-minutes table');
- table.parent().hide();
- var html = '';
- var current = 0;
- for (var i = 0; i < 5; i++) {
- html += '<tr>';
- for (var j = 0; j < 4; j += 1) {
- var c = current.toString();
- html += '<td class="minute">' + padLeft(c, 2, '0') + '</td>';
- current += 3;
- }
- html += '</tr>';
- }
- table.html(html);
- },
- fillSeconds: function() {
- var table = this.widget.find(
- '.timepicker .timepicker-seconds table');
- table.parent().hide();
- var html = '';
- var current = 0;
- for (var i = 0; i < 5; i++) {
- html += '<tr>';
- for (var j = 0; j < 4; j += 1) {
- var c = current.toString();
- html += '<td class="second">' + padLeft(c, 2, '0') + '</td>';
- current += 3;
- }
- html += '</tr>';
- }
- table.html(html);
- },
- fillTime: function() {
- if (!this._date)
- return;
- var timeComponents = this.widget.find('.timepicker span[data-time-component]');
- var table = timeComponents.closest('table');
- var is12HourFormat = this.options.pick12HourFormat;
- var hour = this._date.getUTCHours();
- var period = 'AM';
- if (is12HourFormat) {
- if (hour >= 12) period = 'PM';
- if (hour === 0) hour = 12;
- else if (hour != 12) hour = hour % 12;
- this.widget.find(
- '.timepicker [data-action=togglePeriod]').text(period);
- }
- hour = padLeft(hour.toString(), 2, '0');
- var minute = padLeft(this._date.getUTCMinutes().toString(), 2, '0');
- var second = padLeft(this._date.getUTCSeconds().toString(), 2, '0');
- timeComponents.filter('[data-time-component=hours]').text(hour);
- timeComponents.filter('[data-time-component=minutes]').text(minute);
- timeComponents.filter('[data-time-component=seconds]').text(second);
- },
- click: function(e) {
- e.stopPropagation();
- e.preventDefault();
- this._unset = false;
- var target = $(e.target).closest('span, td, th');
- if (target.length === 1) {
- if (! target.is('.disabled')) {
- switch(target[0].nodeName.toLowerCase()) {
- case 'th':
- switch(target[0].className) {
- case 'switch':
- this.showMode(1);
- break;
- case 'prev':
- case 'next':
- var vd = this.viewDate;
- var navFnc = DPGlobal.modes[this.viewMode].navFnc;
- var step = DPGlobal.modes[this.viewMode].navStep;
- if (target[0].className === 'prev') step = step * -1;
- vd['set' + navFnc](vd['get' + navFnc]() + step);
- this.fillDate();
- this.set();
- break;
- }
- break;
- case 'span':
- if (target.is('.month')) {
- var month = target.parent().find('span').index(target);
- this.viewDate.setUTCMonth(month);
- } else {
- var year = parseInt(target.text(), 10) || 0;
- this.viewDate.setUTCFullYear(year);
- }
- if (this.viewMode !== 0) {
- this._date = UTCDate(
- this.viewDate.getUTCFullYear(),
- this.viewDate.getUTCMonth(),
- this.viewDate.getUTCDate(),
- this._date.getUTCHours(),
- this._date.getUTCMinutes(),
- this._date.getUTCSeconds(),
- this._date.getUTCMilliseconds()
- );
- this.notifyChange();
- }
- this.showMode(-1);
- this.fillDate();
- this.set();
- break;
- case 'td':
- if (target.is('.day')) {
- var day = parseInt(target.text(), 10) || 1;
- var month = this.viewDate.getUTCMonth();
- var year = this.viewDate.getUTCFullYear();
- if (target.is('.old')) {
- if (month === 0) {
- month = 11;
- year -= 1;
- } else {
- month -= 1;
- }
- } else if (target.is('.new')) {
- if (month == 11) {
- month = 0;
- year += 1;
- } else {
- month += 1;
- }
- }
- this._date = UTCDate(
- year, month, day,
- this._date.getUTCHours(),
- this._date.getUTCMinutes(),
- this._date.getUTCSeconds(),
- this._date.getUTCMilliseconds()
- );
- this.viewDate = UTCDate(
- year, month, Math.min(28, day) , 0, 0, 0, 0);
- this.fillDate();
- this.set();
- this.notifyChange();
- }
- break;
- }
- }
- }
- },
- actions: {
- incrementHours: function(e) {
- this._date.setUTCHours(this._date.getUTCHours() + 1);
- },
- incrementMinutes: function(e) {
- this._date.setUTCMinutes(this._date.getUTCMinutes() + 1);
- },
- incrementSeconds: function(e) {
- this._date.setUTCSeconds(this._date.getUTCSeconds() + 1);
- },
- decrementHours: function(e) {
- this._date.setUTCHours(this._date.getUTCHours() - 1);
- },
- decrementMinutes: function(e) {
- this._date.setUTCMinutes(this._date.getUTCMinutes() - 1);
- },
- decrementSeconds: function(e) {
- this._date.setUTCSeconds(this._date.getUTCSeconds() - 1);
- },
- togglePeriod: function(e) {
- var hour = this._date.getUTCHours();
- if (hour >= 12) hour -= 12;
- else hour += 12;
- this._date.setUTCHours(hour);
- },
- showPicker: function() {
- this.widget.find('.timepicker > div:not(.timepicker-picker)').hide();
- this.widget.find('.timepicker .timepicker-picker').show();
- },
- showHours: function() {
- this.widget.find('.timepicker .timepicker-picker').hide();
- this.widget.find('.timepicker .timepicker-hours').show();
- },
- showMinutes: function() {
- this.widget.find('.timepicker .timepicker-picker').hide();
- this.widget.find('.timepicker .timepicker-minutes').show();
- },
- showSeconds: function() {
- this.widget.find('.timepicker .timepicker-picker').hide();
- this.widget.find('.timepicker .timepicker-seconds').show();
- },
- selectHour: function(e) {
- var tgt = $(e.target);
- var value = parseInt(tgt.text(), 10);
- if (this.options.pick12HourFormat) {
- var current = this._date.getUTCHours();
- if (current >= 12) {
- if (value != 12) value = (value + 12) % 24;
- } else {
- if (value === 12) value = 0;
- else value = value % 12;
- }
- }
- this._date.setUTCHours(value);
- this.actions.showPicker.call(this);
- },
- selectMinute: function(e) {
- var tgt = $(e.target);
- var value = parseInt(tgt.text(), 10);
- this._date.setUTCMinutes(value);
- this.actions.showPicker.call(this);
- },
- selectSecond: function(e) {
- var tgt = $(e.target);
- var value = parseInt(tgt.text(), 10);
- this._date.setUTCSeconds(value);
- this.actions.showPicker.call(this);
- }
- },
- doAction: function(e) {
- e.stopPropagation();
- e.preventDefault();
- if (!this._date) this._date = UTCDate(1970, 0, 0, 0, 0, 0, 0);
- var action = $(e.currentTarget).data('action');
- var rv = this.actions[action].apply(this, arguments);
- this.set();
- this.fillTime();
- this.notifyChange();
- return rv;
- },
- stopEvent: function(e) {
- e.stopPropagation();
- e.preventDefault();
- },
- // part of the following code was taken from
- // http://cloud.github.com/downloads/digitalBush/jquery.maskedinput/jquery.maskedinput-1.3.js
- keydown: function(e) {
- var self = this, k = e.which, input = $(e.target);
- if (k == 8 || k == 46) {
- // backspace and delete cause the maskPosition
- // to be recalculated
- setTimeout(function() {
- self._resetMaskPos(input);
- });
- }
- },
- keypress: function(e) {
- var k = e.which;
- if (k == 8 || k == 46) {
- // For those browsers which will trigger
- // keypress on backspace/delete
- return;
- }
- var input = $(e.target);
- var c = String.fromCharCode(k);
- var val = input.val() || '';
- val += c;
- var mask = this._mask[this._maskPos];
- if (!mask) {
- return false;
- }
- if (mask.end != val.length) {
- return;
- }
- if (!mask.pattern.test(val.slice(mask.start))) {
- val = val.slice(0, val.length - 1);
- while ((mask = this._mask[this._maskPos]) && mask.character) {
- val += mask.character;
- // advance mask position past static
- // part
- this._maskPos++;
- }
- val += c;
- if (mask.end != val.length) {
- input.val(val);
- return false;
- } else {
- if (!mask.pattern.test(val.slice(mask.start))) {
- input.val(val.slice(0, mask.start));
- return false;
- } else {
- input.val(val);
- this._maskPos++;
- return false;
- }
- }
- } else {
- this._maskPos++;
- }
- },
- change: function(e) {
- var input = $(e.target);
- var val = input.val();
- if (this._formatPattern.test(val)) {
- this.update();
- this.setValue(this._date.getTime());
- this.notifyChange();
- this.set();
- } else if (val && val.trim()) {
- this.setValue(this._date.getTime());
- if (this._date) this.set();
- else input.val('');
- } else {
- if (this._date) {
- this.setValue(null);
- // unset the date when the input is
- // erased
- this.notifyChange();
- this._unset = true;
- }
- }
- this._resetMaskPos(input);
- },
- showMode: function(dir) {
- if (dir) {
- this.viewMode = Math.max(this.minViewMode, Math.min(
- 2, this.viewMode + dir));
- }
- this.widget.find('.datepicker > div').hide().filter(
- '.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
- },
- destroy: function() {
- this._detachDatePickerEvents();
- this._detachDatePickerGlobalEvents();
- this.widget.remove();
- this.$element.removeData('datetimepicker');
- this.component.removeData('datetimepicker');
- },
- formatDate: function(d) {
- return this.format.replace(formatReplacer, function(match) {
- var methodName, property, rv, len = match.length;
- if (match === 'ms')
- len = 1;
- property = dateFormatComponents[match].property
- if (property === 'Hours12') {
- rv = d.getUTCHours();
- if (rv === 0) rv = 12;
- else if (rv !== 12) rv = rv % 12;
- } else if (property === 'Period12') {
- if (d.getUTCHours() >= 12) return 'PM';
- else return 'AM';
- } else {
- methodName = 'get' + property;
- rv = d[methodName]();
- }
- if (methodName === 'getUTCMonth') rv = rv + 1;
- if (methodName === 'getUTCYear') rv = rv + 1900 - 2000;
- return padLeft(rv.toString(), len, '0');
- });
- },
- parseDate: function(str) {
- var match, i, property, methodName, value, parsed = {};
- if (!(match = this._formatPattern.exec(str)))
- return null;
- for (i = 1; i < match.length; i++) {
- property = this._propertiesByIndex[i];
- if (!property)
- continue;
- value = match[i];
- if (/^\d+$/.test(value))
- value = parseInt(value, 10);
- parsed[property] = value;
- }
- return this._finishParsingDate(parsed);
- },
- _resetMaskPos: function(input) {
- var val = input.val();
- for (var i = 0; i < this._mask.length; i++) {
- if (this._mask[i].end > val.length) {
- // If the mask has ended then jump to
- // the next
- this._maskPos = i;
- break;
- } else if (this._mask[i].end === val.length) {
- this._maskPos = i + 1;
- break;
- }
- }
- },
- _finishParsingDate: function(parsed) {
- var year, month, date, hours, minutes, seconds, milliseconds;
- year = parsed.UTCFullYear;
- if (parsed.UTCYear) year = 2000 + parsed.UTCYear;
- if (!year) year = 1970;
- if (parsed.UTCMonth) month = parsed.UTCMonth - 1;
- else month = 0;
- date = parsed.UTCDate || 1;
- hours = parsed.UTCHours || 0;
- minutes = parsed.UTCMinutes || 0;
- seconds = parsed.UTCSeconds || 0;
- milliseconds = parsed.UTCMilliseconds || 0;
- if (parsed.Hours12) {
- hours = parsed.Hours12;
- }
- if (parsed.Period12) {
- if (/pm/i.test(parsed.Period12)) {
- if (hours != 12) hours = (hours + 12) % 24;
- } else {
- hours = hours % 12;
- }
- }
- return UTCDate(year, month, date, hours, minutes, seconds, milliseconds);
- },
- _compileFormat: function () {
- var match, component, components = [], mask = [],
- str = this.format, propertiesByIndex = {}, i = 0, pos = 0;
- while (match = formatComponent.exec(str)) {
- component = match[0];
- if (component in dateFormatComponents) {
- i++;
- propertiesByIndex[i] = dateFormatComponents[component].property;
- components.push('\\s*' + dateFormatComponents[component].getPattern(
- this) + '\\s*');
- mask.push({
- pattern: new RegExp(dateFormatComponents[component].getPattern(
- this)),
- property: dateFormatComponents[component].property,
- start: pos,
- end: pos += component.length
- });
- }
- else {
- components.push(escapeRegExp(component));
- mask.push({
- pattern: new RegExp(escapeRegExp(component)),
- character: component,
- start: pos,
- end: ++pos
- });
- }
- str = str.slice(component.length);
- }
- this._mask = mask;
- this._maskPos = 0;
- this._formatPattern = new RegExp(
- '^\\s*' + components.join('') + '\\s*$');
- this._propertiesByIndex = propertiesByIndex;
- },
- _attachDatePickerEvents: function() {
- var self = this;
- // this handles date picker clicks
- this.widget.on('click', '.datepicker *', $.proxy(this.click, this));
- // this handles time picker clicks
- this.widget.on('click', '[data-action]', $.proxy(this.doAction, this));
- this.widget.on('mousedown', $.proxy(this.stopEvent, this));
- if (this.pickDate && this.pickTime) {
- this.widget.on('click.togglePicker', '.accordion-toggle', function(e) {
- e.stopPropagation();
- var $this = $(this);
- var $parent = $this.closest('ul');
- var expanded = $parent.find('.collapse.in');
- var closed = $parent.find('.collapse:not(.in)');
- if (expanded && expanded.length) {
- var collapseData = expanded.data('collapse');
- if (collapseData && collapseData.transitioning) return;
- expanded.collapse('hide');
- closed.collapse('show')
- $this.find('i').toggleClass(self.timeIcon + ' ' + self.dateIcon);
- self.$element.find('.add-on i').toggleClass(self.timeIcon + ' ' + self.dateIcon);
- }
- });
- }
- if (this.isInput) {
- this.$element.on({
- 'focus': $.proxy(this.show, this),
- 'change': $.proxy(this.change, this)
- });
- if (this.options.maskInput) {
- this.$element.on({
- 'keydown': $.proxy(this.keydown, this),
- 'keypress': $.proxy(this.keypress, this)
- });
- }
- } else {
- this.$element.on({
- 'change': $.proxy(this.change, this)
- }, 'input');
- if (this.options.maskInput) {
- this.$element.on({
- 'keydown': $.proxy(this.keydown, this),
- 'keypress': $.proxy(this.keypress, this)
- }, 'input');
- }
- if (this.component){
- this.component.on('click', $.proxy(this.show, this));
- } else {
- this.$element.on('click', $.proxy(this.show, this));
- }
- }
- },
- _attachDatePickerGlobalEvents: function() {
- $(window).on(
- 'resize.datetimepicker' + this.id, $.proxy(this.place, this));
- if (!this.isInput) {
- $(document).on(
- 'mousedown.datetimepicker' + this.id, $.proxy(this.hide, this));
- }
- },
- _detachDatePickerEvents: function() {
- this.widget.off('click', '.datepicker *', this.click);
- this.widget.off('click', '[data-action]');
- this.widget.off('mousedown', this.stopEvent);
- if (this.pickDate && this.pickTime) {
- this.widget.off('click.togglePicker');
- }
- if (this.isInput) {
- this.$element.off({
- 'focus': this.show,
- 'change': this.change
- });
- if (this.options.maskInput) {
- this.$element.off({
- 'keydown': this.keydown,
- 'keypress': this.keypress
- });
- }
- } else {
- this.$element.off({
- 'change': this.change
- }, 'input');
- if (this.options.maskInput) {
- this.$element.off({
- 'keydown': this.keydown,
- 'keypress': this.keypress
- }, 'input');
- }
- if (this.component){
- this.component.off('click', this.show);
- } else {
- this.$element.off('click', this.show);
- }
- }
- },
- _detachDatePickerGlobalEvents: function () {
- $(window).off('resize.datetimepicker' + this.id);
- if (!this.isInput) {
- $(document).off('mousedown.datetimepicker' + this.id);
- }
- },
- _isInFixed: function() {
- if (this.$element) {
- var parents = this.$element.parents();
- var inFixed = false;
- for (var i=0; i<parents.length; i++) {
- if ($(parents[i]).css('position') == 'fixed') {
- inFixed = true;
- break;
- }
- };
- return inFixed;
- } else {
- return false;
- }
- }
- };
- $.fn.datetimepicker = function ( option, val ) {
- return this.each(function () {
- var $this = $(this),
- data = $this.data('datetimepicker'),
- options = typeof option === 'object' && option;
- if (!data) {
- $this.data('datetimepicker', (data = new DateTimePicker(
- this, $.extend({}, $.fn.datetimepicker.defaults,options))));
- }
- if (typeof option === 'string') data[option](val);
- });
- };
- $.fn.datetimepicker.defaults = {
- maskInput: false,
- pickDate: true,
- pickTime: true,
- pick12HourFormat: false,
- pickSeconds: true,
- startDate: -Infinity,
- endDate: Infinity,
- collapse: true,
- showTimeFirst: false
- };
- $.fn.datetimepicker.Constructor = DateTimePicker;
- var dpgId = 0;
- var dates = $.fn.datetimepicker.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"]
- };
- var dateFormatComponents = {
- dd: {property: 'UTCDate', getPattern: function() { return '(0?[1-9]|[1-2][0-9]|3[0-1])\\b';}},
- MM: {property: 'UTCMonth', getPattern: function() {return '(0?[1-9]|1[0-2])\\b';}},
- yy: {property: 'UTCYear', getPattern: function() {return '(\\d{2})\\b'}},
- yyyy: {property: 'UTCFullYear', getPattern: function() {return '(\\d{4})\\b';}},
- hh: {property: 'UTCHours', getPattern: function() {return '(0?[0-9]|1[0-9]|2[0-3])\\b';}},
- mm: {property: 'UTCMinutes', getPattern: function() {return '(0?[0-9]|[1-5][0-9])\\b';}},
- ss: {property: 'UTCSeconds', getPattern: function() {return '(0?[0-9]|[1-5][0-9])\\b';}},
- ms: {property: 'UTCMilliseconds', getPattern: function() {return '([0-9]{1,3})\\b';}},
- HH: {property: 'Hours12', getPattern: function() {return '(0?[1-9]|1[0-2])\\b';}},
- PP: {property: 'Period12', getPattern: function() {return '(AM|PM|am|pm|Am|aM|Pm|pM)\\b';}}
- };
- var keys = [];
- for (var k in dateFormatComponents) keys.push(k);
- keys[keys.length - 1] += '\\b';
- keys.push('.');
- var formatComponent = new RegExp(keys.join('\\b|'));
- keys.pop();
- var formatReplacer = new RegExp(keys.join('\\b|'), 'g');
- function escapeRegExp(str) {
- // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
- return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
- }
- function padLeft(s, l, c) {
- if (l < s.length) return s;
- else return Array(l - s.length + 1).join(c || ' ') + s;
- }
- function getTemplate(timeIcon, dateIcon, pickDate, pickTime, is12Hours, showSeconds, collapse, showTimeFirst) {
- if (pickDate && pickTime) {
- return (
- '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
- '<ul>' +
- '<li' + (collapse ? ' class="collapse ' + (!showTimeFirst ? 'in' : '' ) + '"' : '') + '>' +
- '<div class="datepicker">' +
- DPGlobal.template +
- '</div>' +
- '</li>' +
- '<li class="picker-switch accordion-toggle"><a><i class="' + (showTimeFirst ? dateIcon : timeIcon) + '"></i></a></li>' +
- '<li' + (collapse ? ' class="collapse ' + (showTimeFirst ? 'in' : '' ) + '"' : '') + '>' +
- '<div class="timepicker">' +
- TPGlobal.getTemplate(is12Hours, showSeconds) +
- '</div>' +
- '</li>' +
- '</ul>' +
- '</div>'
- );
- } else if (pickTime) {
- return (
- '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
- '<div class="timepicker">' +
- TPGlobal.getTemplate(is12Hours, showSeconds) +
- '</div>' +
- '</div>'
- );
- } else {
- return (
- '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
- '<div class="datepicker">' +
- DPGlobal.template +
- '</div>' +
- '</div>'
- );
- }
- }
- function UTCDate() {
- return new Date(Date.UTC.apply(Date, arguments));
- }
- var DPGlobal = {
- modes: [
- {
- clsName: 'days',
- navFnc: 'UTCMonth',
- navStep: 1
- },
- {
- clsName: 'months',
- navFnc: 'UTCFullYear',
- navStep: 1
- },
- {
- clsName: 'years',
- navFnc: 'UTCFullYear',
- navStep: 10
- }],
- 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]
- },
- headTemplate:
- '<thead>' +
- '<tr>' +
- '<th class="prev">‹</th>' +
- '<th colspan="5" class="switch"></th>' +
- '<th class="next">›</th>' +
- '</tr>' +
- '</thead>',
- contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
- };
- DPGlobal.template =
- '<div class="datepicker-days">' +
- '<table class="table-condensed">' +
- DPGlobal.headTemplate +
- '<tbody></tbody>' +
- '</table>' +
- '</div>' +
- '<div class="datepicker-months">' +
- '<table class="table-condensed">' +
- DPGlobal.headTemplate +
- DPGlobal.contTemplate+
- '</table>'+
- '</div>'+
- '<div class="datepicker-years">'+
- '<table class="table-condensed">'+
- DPGlobal.headTemplate+
- DPGlobal.contTemplate+
- '</table>'+
- '</div>';
- var TPGlobal = {
- hourTemplate: '<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>',
- minuteTemplate: '<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>',
- secondTemplate: '<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>'
- };
- TPGlobal.getTemplate = function(is12Hours, showSeconds) {
- return (
- '<div class="timepicker-picker">' +
- '<table class="table-condensed"' +
- (is12Hours ? ' data-hour-format="12"' : '') +
- '>' +
- '<tr>' +
- '<td><a href="#" class="btn" data-action="incrementHours"><i class="icon-chevron-up"></i></a></td>' +
- '<td class="separator"></td>' +
- '<td><a href="#" class="btn" data-action="incrementMinutes"><i class="icon-chevron-up"></i></a></td>' +
- (showSeconds ?
- '<td class="separator"></td>' +
- '<td><a href="#" class="btn" data-action="incrementSeconds"><i class="icon-chevron-up"></i></a></td>': '')+
- (is12Hours ? '<td class="separator"></td>' : '') +
- '</tr>' +
- '<tr>' +
- '<td>' + TPGlobal.hourTemplate + '</td> ' +
- '<td class="separator">:</td>' +
- '<td>' + TPGlobal.minuteTemplate + '</td> ' +
- (showSeconds ?
- '<td class="separator">:</td>' +
- '<td>' + TPGlobal.secondTemplate + '</td>' : '') +
- (is12Hours ?
- '<td class="separator"></td>' +
- '<td>' +
- '<button type="button" class="btn btn-primary" data-action="togglePeriod"></button>' +
- '</td>' : '') +
- '</tr>' +
- '<tr>' +
- '<td><a href="#" class="btn" data-action="decrementHours"><i class="icon-chevron-down"></i></a></td>' +
- '<td class="separator"></td>' +
- '<td><a href="#" class="btn" data-action="decrementMinutes"><i class="icon-chevron-down"></i></a></td>' +
- (showSeconds ?
- '<td class="separator"></td>' +
- '<td><a href="#" class="btn" data-action="decrementSeconds"><i class="icon-chevron-down"></i></a></td>': '') +
- (is12Hours ? '<td class="separator"></td>' : '') +
- '</tr>' +
- '</table>' +
- '</div>' +
- '<div class="timepicker-hours" data-action="selectHour">' +
- '<table class="table-condensed">' +
- '</table>'+
- '</div>'+
- '<div class="timepicker-minutes" data-action="selectMinute">' +
- '<table class="table-condensed">' +
- '</table>'+
- '</div>'+
- (showSeconds ?
- '<div class="timepicker-seconds" data-action="selectSecond">' +
- '<table class="table-condensed">' +
- '</table>'+
- '</div>': '')
- );
- }
- })(window.jQuery)
|