| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304 |
- /**
- * @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) {
- 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;
- 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';
- icon.addClass(this.timeIcon);
- }
- if (this.pickDate) {
- 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, options.pickDate, options.pickTime, options.pick12HourFormat, options.pickSeconds, options.collapse)).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[this.language].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[this.language].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[this.language].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 if (property === 'UTCYear') {
- rv = d.getUTCFullYear();
- rv = rv.toString().substr(2);
- } else {
- methodName = 'get' + property;
- rv = d[methodName]();
- }
- if (methodName === 'getUTCMonth') rv = rv + 1;
- 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
- };
- $.fn.datetimepicker.Constructor = DateTimePicker;
- var dpgId = 0;
- var dates = $.fn.datetimepicker.dates = {
- en: {
- 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, pickDate, pickTime, is12Hours, showSeconds, collapse) {
- if (pickDate && pickTime) {
- return (
- '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
- '<ul>' +
- '<li' + (collapse ? ' class="collapse in"' : '') + '>' +
- '<div class="datepicker">' +
- DPGlobal.template +
- '</div>' +
- '</li>' +
- '<li class="picker-switch accordion-toggle"><a><i class="' + timeIcon + '"></i></a></li>' +
- '<li' + (collapse ? ' class="collapse"' : '') + '>' +
- '<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)
|