1
(function($){$.ui.timepicker=$.ui.timepicker||{};if($.ui.timepicker.version){return}$.extend($.ui,{timepicker:{version:"1.1.1"}});function Timepicker(){this.regional=[];this.regional[""]={currentText:"Now",closeText:"Done",amNames:["AM","A"],pmNames:["PM","P"],timeFormat:"HH:mm",timeSuffix:"",timeOnlyTitle:"Choose Time",timeText:"Time",hourText:"Hour",minuteText:"Minute",secondText:"Second",millisecText:"Millisecond",timezoneText:"Time Zone",isRTL:false};this._defaults={showButtonPanel:true,timeOnly:false,showHour:true,showMinute:true,showSecond:false,showMillisec:false,showTimezone:false,showTime:true,stepHour:1,stepMinute:1,stepSecond:1,stepMillisec:1,hour:0,minute:0,second:0,millisec:0,timezone:null,useLocalTimezone:false,defaultTimezone:"+0000",hourMin:0,minuteMin:0,secondMin:0,millisecMin:0,hourMax:23,minuteMax:59,secondMax:59,millisecMax:999,minDateTime:null,maxDateTime:null,onSelect:null,hourGrid:0,minuteGrid:0,secondGrid:0,millisecGrid:0,alwaysSetTime:true,separator:" ",altFieldTimeOnly:true,altTimeFormat:null,altSeparator:null,altTimeSuffix:null,pickerTimeFormat:null,pickerTimeSuffix:null,showTimepicker:true,timezoneIso8601:false,timezoneList:null,addSliderAccess:false,sliderAccessArgs:null,controlType:"slider",defaultValue:null,parse:"strict"};$.extend(this._defaults,this.regional[""])}$.extend(Timepicker.prototype,{$input:null,$altInput:null,$timeObj:null,inst:null,hour_slider:null,minute_slider:null,second_slider:null,millisec_slider:null,timezone_select:null,hour:0,minute:0,second:0,millisec:0,timezone:null,defaultTimezone:"+0000",hourMinOriginal:null,minuteMinOriginal:null,secondMinOriginal:null,millisecMinOriginal:null,hourMaxOriginal:null,minuteMaxOriginal:null,secondMaxOriginal:null,millisecMaxOriginal:null,ampm:"",formattedDate:"",formattedTime:"",formattedDateTime:"",timezoneList:null,units:["hour","minute","second","millisec"],control:null,setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_newInst:function($input,o){var tp_inst=new Timepicker(),inlineSettings={},fns={},overrides,i;for(var attrName in this._defaults){if(this._defaults.hasOwnProperty(attrName)){var attrValue=$input.attr("time:"+attrName);if(attrValue){try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}}overrides={beforeShow:function(input,dp_inst){if($.isFunction(tp_inst._defaults.evnts.beforeShow)){return tp_inst._defaults.evnts.beforeShow.call($input[0],input,dp_inst,tp_inst)}},onChangeMonthYear:function(year,month,dp_inst){tp_inst._updateDateTime(dp_inst);if($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)){tp_inst._defaults.evnts.onChangeMonthYear.call($input[0],year,month,dp_inst,tp_inst)}},onClose:function(dateText,dp_inst){if(tp_inst.timeDefined===true&&$input.val()!==""){tp_inst._updateDateTime(dp_inst)}if($.isFunction(tp_inst._defaults.evnts.onClose)){tp_inst._defaults.evnts.onClose.call($input[0],dateText,dp_inst,tp_inst)}}};for(i in overrides){if(overrides.hasOwnProperty(i)){fns[i]=o[i]||null}}tp_inst._defaults=$.extend({},this._defaults,inlineSettings,o,overrides,{evnts:fns,timepicker:tp_inst});tp_inst.amNames=$.map(tp_inst._defaults.amNames,function(val){return val.toUpperCase()});tp_inst.pmNames=$.map(tp_inst._defaults.pmNames,function(val){return val.toUpperCase()});if(typeof(tp_inst._defaults.controlType)==="string"){if($.fn[tp_inst._defaults.controlType]===undefined){tp_inst._defaults.controlType="select"}tp_inst.control=tp_inst._controls[tp_inst._defaults.controlType]}else{tp_inst.control=tp_inst._defaults.controlType}if(tp_inst._defaults.timezoneList===null){var timezoneList=["-1200","-1100","-1000","-0930","-0900","-0800","-0700","-0600","-0500","-0430","-0400","-0330","-0300","-0200","-0100","+0000","+0100","+0200","+0300","+0330","+0400","+0430","+0500","+0530","+0545","+0600","+0630","+0700","+0800","+0845","+0900","+0930","+1000","+1030","+1100","+1130","+1200","+1245","+1300","+1400"];if(tp_inst._defaults.timezoneIso8601){timezoneList=$.map(timezoneList,function(val){return val=="+0000"?"Z":(val.substring(0,3)+":"+val.substring(3))})}tp_inst._defaults.timezoneList=timezoneList}tp_inst.timezone=tp_inst._defaults.timezone;tp_inst.hour=tp_inst._defaults.hour;tp_inst.minute=tp_inst._defaults.minute;tp_inst.second=tp_inst._defaults.second;tp_inst.millisec=tp_inst._defaults.millisec;tp_inst.ampm="";tp_inst.$input=$input;if(o.altField){tp_inst.$altInput=$(o.altField).css({cursor:"pointer"}).focus(function(){$input.trigger("focus")})}if(tp_inst._defaults.minDate===0||tp_inst._defaults.minDateTime===0){tp_inst._defaults.minDate=new Date()}if(tp_inst._defaults.maxDate===0||tp_inst._defaults.maxDateTime===0){tp_inst._defaults.maxDate=new Date()}if(tp_inst._defaults.minDate!==undefined&&tp_inst._defaults.minDate instanceof Date){tp_inst._defaults.minDateTime=new Date(tp_inst._defaults.minDate.getTime())}if(tp_inst._defaults.minDateTime!==undefined&&tp_inst._defaults.minDateTime instanceof Date){tp_inst._defaults.minDate=new Date(tp_inst._defaults.minDateTime.getTime())}if(tp_inst._defaults.maxDate!==undefined&&tp_inst._defaults.maxDate instanceof Date){tp_inst._defaults.maxDateTime=new Date(tp_inst._defaults.maxDate.getTime())}if(tp_inst._defaults.maxDateTime!==undefined&&tp_inst._defaults.maxDateTime instanceof Date){tp_inst._defaults.maxDate=new Date(tp_inst._defaults.maxDateTime.getTime())}tp_inst.$input.bind("focus",function(){tp_inst._onFocus()});return tp_inst},_addTimePicker:function(dp_inst){var currDT=(this.$altInput&&this._defaults.altFieldTimeOnly)?this.$input.val()+" "+this.$altInput.val():this.$input.val();this.timeDefined=this._parseTime(currDT);this._limitMinMaxDateTime(dp_inst,false);this._injectTimePicker()},_parseTime:function(timeString,withDate){if(!this.inst){this.inst=$.datepicker._getInst(this.$input[0])}if(withDate||!this._defaults.timeOnly){var dp_dateFormat=$.datepicker._get(this.inst,"dateFormat");try{var parseRes=parseDateTimeInternal(dp_dateFormat,this._defaults.timeFormat,timeString,$.datepicker._getFormatConfig(this.inst),this._defaults);if(!parseRes.timeObj){return false}$.extend(this,parseRes.timeObj)}catch(err){$.datepicker.log("Error parsing the date/time string: "+err+"\ndate/time string = "+timeString+"\ntimeFormat = "+this._defaults.timeFormat+"\ndateFormat = "+dp_dateFormat);return false}return true}else{var timeObj=$.datepicker.parseTime(this._defaults.timeFormat,timeString,this._defaults);if(!timeObj){return false}$.extend(this,timeObj);return true}},_injectTimePicker:function(){var $dp=this.inst.dpDiv,o=this.inst.settings,tp_inst=this,litem="",uitem="",max={},gridSize={},size=null;if($dp.find("div.ui-timepicker-div").length===0&&o.showTimepicker){var noDisplay=' style="display:none;"',html='<div class="ui-timepicker-div'+(o.isRTL?" ui-timepicker-rtl":"")+'"><dl><dt class="ui_tpicker_time_label"'+((o.showTime)?"":noDisplay)+">"+o.timeText+'</dt><dd class="ui_tpicker_time"'+((o.showTime)?"":noDisplay)+"></dd>";for(var i=0,l=this.units.length;i<l;i++){litem=this.units[i];uitem=litem.substr(0,1).toUpperCase()+litem.substr(1);max[litem]=parseInt((o[litem+"Max"]-((o[litem+"Max"]-o[litem+"Min"])%o["step"+uitem])),10);gridSize[litem]=0;html+='<dt class="ui_tpicker_'+litem+'_label"'+((o["show"+uitem])?"":noDisplay)+">"+o[litem+"Text"]+'</dt><dd class="ui_tpicker_'+litem+'"><div class="ui_tpicker_'+litem+'_slider"'+((o["show"+uitem])?"":noDisplay)+"></div>";if(o["show"+uitem]&&o[litem+"Grid"]>0){html+='<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';if(litem=="hour"){for(var h=o[litem+"Min"];h<=max[litem];h+=parseInt(o[litem+"Grid"],10)){gridSize[litem]++;var tmph=$.datepicker.formatTime(useAmpm(o.pickerTimeFormat||o.timeFormat)?"hht":"HH",{hour:h},o);html+='<td data-for="'+litem+'">'+tmph+"</td>"}}else{for(var m=o[litem+"Min"];m<=max[litem];m+=parseInt(o[litem+"Grid"],10)){gridSize[litem]++;html+='<td data-for="'+litem+'">'+((m<10)?"0":"")+m+"</td>"}}html+="</tr></table></div>"}html+="</dd>"}html+='<dt class="ui_tpicker_timezone_label"'+((o.showTimezone)?"":noDisplay)+">"+o.timezoneText+"</dt>";html+='<dd class="ui_tpicker_timezone" '+((o.showTimezone)?"":noDisplay)+"></dd>";html+="</dl></div>";var $tp=$(html);if(o.timeOnly===true){$tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all"><div class="ui-datepicker-title">'+o.timeOnlyTitle+"</div></div>");$dp.find(".ui-datepicker-header, .ui-datepicker-calendar").hide()}for(var i=0,l=tp_inst.units.length;i<l;i++){litem=tp_inst.units[i];uitem=litem.substr(0,1).toUpperCase()+litem.substr(1);tp_inst[litem+"_slider"]=tp_inst.control.create(tp_inst,$tp.find(".ui_tpicker_"+litem+"_slider"),litem,tp_inst[litem],o[litem+"Min"],max[litem],o["step"+uitem]);if(o["show"+uitem]&&o[litem+"Grid"]>0){size=100*gridSize[litem]*o[litem+"Grid"]/(max[litem]-o[litem+"Min"]);$tp.find(".ui_tpicker_"+litem+" table").css({width:size+"%",marginLeft:o.isRTL?"0":((size/(-2*gridSize[litem]))+"%"),marginRight:o.isRTL?((size/(-2*gridSize[litem]))+"%"):"0",borderCollapse:"collapse"}).find("td").click(function(e){var $t=$(this),h=$t.html(),n=parseInt(h.replace(/[^0-9]/g),10),ap=h.replace(/[^apm]/ig),f=$t.data("for");if(f=="hour"){if(ap.indexOf("p")!==-1&&n<12){n+=12}else{if(ap.indexOf("a")!==-1&&n===12){n=0}}}tp_inst.control.value(tp_inst,tp_inst[f+"_slider"],litem,n);tp_inst._onTimeChange();tp_inst._onSelectHandler()}).css({cursor:"pointer",width:(100/gridSize[litem])+"%",textAlign:"center",overflow:"hidden"})}}this.timezone_select=$tp.find(".ui_tpicker_timezone").append("<select></select>").find("select");$.fn.append.apply(this.timezone_select,$.map(o.timezoneList,function(val,idx){return $("<option />").val(typeof val=="object"?val.value:val).text(typeof val=="object"?val.label:val)}));if(typeof(this.timezone)!="undefined"&&this.timezone!==null&&this.timezone!==""){var local_date=new Date(this.inst.selectedYear,this.inst.selectedMonth,this.inst.selectedDay,12);var local_timezone=$.timepicker.timeZoneOffsetString(local_date);if(local_timezone==this.timezone){selectLocalTimeZone(tp_inst)}else{this.timezone_select.val(this.timezone)}}else{if(typeof(this.hour)!="undefined"&&this.hour!==null&&this.hour!==""){this.timezone_select.val(o.defaultTimezone)}else{selectLocalTimeZone(tp_inst)}}this.timezone_select.change(function(){tp_inst._defaults.useLocalTimezone=false;tp_inst._onTimeChange()});var $buttonPanel=$dp.find(".ui-datepicker-buttonpane");if($buttonPanel.length){$buttonPanel.before($tp)}else{$dp.append($tp)}this.$timeObj=$tp.find(".ui_tpicker_time");if(this.inst!==null){var timeDefined=this.timeDefined;this._onTimeChange();this.timeDefined=timeDefined}if(this._defaults.addSliderAccess){var sliderAccessArgs=this._defaults.sliderAccessArgs,rtl=this._defaults.isRTL;sliderAccessArgs.isRTL=rtl;setTimeout(function(){if($tp.find(".ui-slider-access").length===0){$tp.find(".ui-slider:visible").sliderAccess(sliderAccessArgs);var sliderAccessWidth=$tp.find(".ui-slider-access:eq(0)").outerWidth(true);if(sliderAccessWidth){$tp.find("table:visible").each(function(){var $g=$(this),oldWidth=$g.outerWidth(),oldMarginLeft=$g.css(rtl?"marginRight":"marginLeft").toString().replace("%",""),newWidth=oldWidth-sliderAccessWidth,newMarginLeft=((oldMarginLeft*newWidth)/oldWidth)+"%",css={width:newWidth,marginRight:0,marginLeft:0};css[rtl?"marginRight":"marginLeft"]=newMarginLeft;$g.css(css)})}}},10)}}},_limitMinMaxDateTime:function(dp_inst,adjustSliders){var o=this._defaults,dp_date=new Date(dp_inst.selectedYear,dp_inst.selectedMonth,dp_inst.selectedDay);if(!this._defaults.showTimepicker){return}if($.datepicker._get(dp_inst,"minDateTime")!==null&&$.datepicker._get(dp_inst,"minDateTime")!==undefined&&dp_date){var minDateTime=$.datepicker._get(dp_inst,"minDateTime"),minDateTimeDate=new Date(minDateTime.getFullYear(),minDateTime.getMonth(),minDateTime.getDate(),0,0,0,0);if(this.hourMinOriginal===null||this.minuteMinOriginal===null||this.secondMinOriginal===null||this.millisecMinOriginal===null){this.hourMinOriginal=o.hourMin;this.minuteMinOriginal=o.minuteMin;this.secondMinOriginal=o.secondMin;this.millisecMinOriginal=o.millisecMin}if(dp_inst.settings.timeOnly||minDateTimeDate.getTime()==dp_date.getTime()){this._defaults.hourMin=minDateTime.getHours();if(this.hour<=this._defaults.hourMin){this.hour=this._defaults.hourMin;this._defaults.minuteMin=minDateTime.getMinutes();if(this.minute<=this._defaults.minuteMin){this.minute=this._defaults.minuteMin;this._defaults.secondMin=minDateTime.getSeconds();if(this.second<=this._defaults.secondMin){this.second=this._defaults.secondMin;this._defaults.millisecMin=minDateTime.getMilliseconds()}else{if(this.millisec<this._defaults.millisecMin){this.millisec=this._defaults.millisecMin}this._defaults.millisecMin=this.millisecMinOriginal}}else{this._defaults.secondMin=this.secondMinOriginal;this._defaults.millisecMin=this.millisecMinOriginal}}else{this._defaults.minuteMin=this.minuteMinOriginal;this._defaults.secondMin=this.secondMinOriginal;this._defaults.millisecMin=this.millisecMinOriginal}}else{this._defaults.hourMin=this.hourMinOriginal;this._defaults.minuteMin=this.minuteMinOriginal;this._defaults.secondMin=this.secondMinOriginal;this._defaults.millisecMin=this.millisecMinOriginal}}if($.datepicker._get(dp_inst,"maxDateTime")!==null&&$.datepicker._get(dp_inst,"maxDateTime")!==undefined&&dp_date){var maxDateTime=$.datepicker._get(dp_inst,"maxDateTime"),maxDateTimeDate=new Date(maxDateTime.getFullYear(),maxDateTime.getMonth(),maxDateTime.getDate(),0,0,0,0);if(this.hourMaxOriginal===null||this.minuteMaxOriginal===null||this.secondMaxOriginal===null){this.hourMaxOriginal=o.hourMax;this.minuteMaxOriginal=o.minuteMax;this.secondMaxOriginal=o.secondMax;this.millisecMaxOriginal=o.millisecMax}if(dp_inst.settings.timeOnly||maxDateTimeDate.getTime()==dp_date.getTime()){this._defaults.hourMax=maxDateTime.getHours();if(this.hour>=this._defaults.hourMax){this.hour=this._defaults.hourMax;this._defaults.minuteMax=maxDateTime.getMinutes();if(this.minute>=this._defaults.minuteMax){this.minute=this._defaults.minuteMax;this._defaults.secondMax=maxDateTime.getSeconds()}else{if(this.second>=this._defaults.secondMax){this.second=this._defaults.secondMax;this._defaults.millisecMax=maxDateTime.getMilliseconds()}else{if(this.millisec>this._defaults.millisecMax){this.millisec=this._defaults.millisecMax}this._defaults.millisecMax=this.millisecMaxOriginal}}}else{this._defaults.minuteMax=this.minuteMaxOriginal;this._defaults.secondMax=this.secondMaxOriginal;this._defaults.millisecMax=this.millisecMaxOriginal}}else{this._defaults.hourMax=this.hourMaxOriginal;this._defaults.minuteMax=this.minuteMaxOriginal;this._defaults.secondMax=this.secondMaxOriginal;this._defaults.millisecMax=this.millisecMaxOriginal}}if(adjustSliders!==undefined&&adjustSliders===true){var hourMax=parseInt((this._defaults.hourMax-((this._defaults.hourMax-this._defaults.hourMin)%this._defaults.stepHour)),10),minMax=parseInt((this._defaults.minuteMax-((this._defaults.minuteMax-this._defaults.minuteMin)%this._defaults.stepMinute)),10),secMax=parseInt((this._defaults.secondMax-((this._defaults.secondMax-this._defaults.secondMin)%this._defaults.stepSecond)),10),millisecMax=parseInt((this._defaults.millisecMax-((this._defaults.millisecMax-this._defaults.millisecMin)%this._defaults.stepMillisec)),10);if(this.hour_slider){this.control.options(this,this.hour_slider,"hour",{min:this._defaults.hourMin,max:hourMax});this.control.value(this,this.hour_slider,"hour",this.hour)}if(this.minute_slider){this.control.options(this,this.minute_slider,"minute",{min:this._defaults.minuteMin,max:minMax});this.control.value(this,this.minute_slider,"minute",this.minute)}if(this.second_slider){this.control.options(this,this.second_slider,"second",{min:this._defaults.secondMin,max:secMax});this.control.value(this,this.second_slider,"second",this.second)}if(this.millisec_slider){this.control.options(this,this.millisec_slider,"millisec",{min:this._defaults.millisecMin,max:millisecMax});this.control.value(this,this.millisec_slider,"millisec",this.millisec)}}},_onTimeChange:function(){var hour=(this.hour_slider)?this.control.value(this,this.hour_slider,"hour"):false,minute=(this.minute_slider)?this.control.value(this,this.minute_slider,"minute"):false,second=(this.second_slider)?this.control.value(this,this.second_slider,"second"):false,millisec=(this.millisec_slider)?this.control.value(this,this.millisec_slider,"millisec"):false,timezone=(this.timezone_select)?this.timezone_select.val():false,o=this._defaults,pickerTimeFormat=o.pickerTimeFormat||o.timeFormat,pickerTimeSuffix=o.pickerTimeSuffix||o.timeSuffix;if(typeof(hour)=="object"){hour=false}if(typeof(minute)=="object"){minute=false}if(typeof(second)=="object"){second=false}if(typeof(millisec)=="object"){millisec=false}if(typeof(timezone)=="object"){timezone=false}if(hour!==false){hour=parseInt(hour,10)}if(minute!==false){minute=parseInt(minute,10)}if(second!==false){second=parseInt(second,10)}if(millisec!==false){millisec=parseInt(millisec,10)}var ampm=o[hour<12?"amNames":"pmNames"][0];var hasChanged=(hour!=this.hour||minute!=this.minute||second!=this.second||millisec!=this.millisec||(this.ampm.length>0&&(hour<12)!=($.inArray(this.ampm.toUpperCase(),this.amNames)!==-1))||((this.timezone===null&&timezone!=this.defaultTimezone)||(this.timezone!==null&&timezone!=this.timezone)));if(hasChanged){if(hour!==false){this.hour=hour}if(minute!==false){this.minute=minute}if(second!==false){this.second=second}if(millisec!==false){this.millisec=millisec}if(timezone!==false){this.timezone=timezone}if(!this.inst){this.inst=$.datepicker._getInst(this.$input[0])}this._limitMinMaxDateTime(this.inst,true)}if(useAmpm(o.timeFormat)){this.ampm=ampm}this.formattedTime=$.datepicker.formatTime(o.timeFormat,this,o);if(this.$timeObj){if(pickerTimeFormat===o.timeFormat){this.$timeObj.text(this.formattedTime+pickerTimeSuffix)}else{this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat,this,o)+pickerTimeSuffix)}}this.timeDefined=true;if(hasChanged){this._updateDateTime()}},_onSelectHandler:function(){var onSelect=this._defaults.onSelect||this.inst.settings.onSelect;var inputEl=this.$input?this.$input[0]:null;if(onSelect&&inputEl){onSelect.apply(inputEl,[this.formattedDateTime,this])}},_updateDateTime:function(dp_inst){dp_inst=this.inst||dp_inst;var dt=$.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear,dp_inst.selectedMonth,dp_inst.selectedDay)),dateFmt=$.datepicker._get(dp_inst,"dateFormat"),formatCfg=$.datepicker._getFormatConfig(dp_inst),timeAvailable=dt!==null&&this.timeDefined;this.formattedDate=$.datepicker.formatDate(dateFmt,(dt===null?new Date():dt),formatCfg);var formattedDateTime=this.formattedDate;if(this._defaults.timeOnly===true){formattedDateTime=this.formattedTime}else{if(this._defaults.timeOnly!==true&&(this._defaults.alwaysSetTime||timeAvailable)){formattedDateTime+=this._defaults.separator+this.formattedTime+this._defaults.timeSuffix}}this.formattedDateTime=formattedDateTime;if(!this._defaults.showTimepicker){this.$input.val(this.formattedDate)}else{if(this.$altInput&&this._defaults.altFieldTimeOnly===true){this.$altInput.val(this.formattedTime);this.$input.val(this.formattedDate)}else{if(this.$altInput){this.$input.val(formattedDateTime);var altFormattedDateTime="",altSeparator=this._defaults.altSeparator?this._defaults.altSeparator:this._defaults.separator,altTimeSuffix=this._defaults.altTimeSuffix?this._defaults.altTimeSuffix:this._defaults.timeSuffix;if(this._defaults.altFormat){altFormattedDateTime=$.datepicker.formatDate(this._defaults.altFormat,(dt===null?new Date():dt),formatCfg)}else{altFormattedDateTime=this.formattedDate}if(altFormattedDateTime){altFormattedDateTime+=altSeparator}if(this._defaults.altTimeFormat){altFormattedDateTime+=$.datepicker.formatTime(this._defaults.altTimeFormat,this,this._defaults)+altTimeSuffix}else{altFormattedDateTime+=this.formattedTime+altTimeSuffix}this.$altInput.val(altFormattedDateTime)}else{this.$input.val(formattedDateTime)}}}this.$input.trigger("change")},_onFocus:function(){if(!this.$input.val()&&this._defaults.defaultValue){this.$input.val(this._defaults.defaultValue);var inst=$.datepicker._getInst(this.$input.get(0)),tp_inst=$.datepicker._get(inst,"timepicker");if(tp_inst){if(tp_inst._defaults.timeOnly&&(inst.input.val()!=inst.lastVal)){try{$.datepicker._updateDatepicker(inst)}catch(err){$.datepicker.log(err)}}}}},_controls:{slider:{create:function(tp_inst,obj,unit,val,min,max,step){var rtl=tp_inst._defaults.isRTL;return obj.prop("slide",null).slider({orientation:"horizontal",value:rtl?val*-1:val,min:rtl?max*-1:min,max:rtl?min*-1:max,step:step,slide:function(event,ui){tp_inst.control.value(tp_inst,$(this),unit,rtl?ui.value*-1:ui.value);tp_inst._onTimeChange()},stop:function(event,ui){tp_inst._onSelectHandler()}})},options:function(tp_inst,obj,unit,opts,val){if(tp_inst._defaults.isRTL){if(typeof(opts)=="string"){if(opts=="min"||opts=="max"){if(val!==undefined){return obj.slider(opts,val*-1)}return Math.abs(obj.slider(opts))}return obj.slider(opts)}var min=opts.min,max=opts.max;opts.min=opts.max=null;if(min!==undefined){opts.max=min*-1}if(max!==undefined){opts.min=max*-1}return obj.slider(opts)}if(typeof(opts)=="string"&&val!==undefined){return obj.slider(opts,val)}return obj.slider(opts)},value:function(tp_inst,obj,unit,val){if(tp_inst._defaults.isRTL){if(val!==undefined){return obj.slider("value",val*-1)}return Math.abs(obj.slider("value"))}if(val!==undefined){return obj.slider("value",val)}return obj.slider("value")}},select:{create:function(tp_inst,obj,unit,val,min,max,step){var sel='<select class="ui-timepicker-select" data-unit="'+unit+'" data-min="'+min+'" data-max="'+max+'" data-step="'+step+'">',ul=tp_inst._defaults.timeFormat.indexOf("t")!==-1?"toLowerCase":"toUpperCase",m=0;for(var i=min;i<=max;i+=step){sel+='<option value="'+i+'"'+(i==val?" selected":"")+">";if(unit=="hour"&&useAmpm(tp_inst._defaults.pickerTimeFormat||tp_inst._defaults.timeFormat)){sel+=$.datepicker.formatTime("hh TT",{hour:i},tp_inst._defaults)}else{if(unit=="millisec"||i>=10){sel+=i}else{sel+="0"+i.toString()}}sel+="</option>"}sel+="</select>";obj.children("select").remove();$(sel).appendTo(obj).change(function(e){tp_inst._onTimeChange();tp_inst._onSelectHandler()});return obj},options:function(tp_inst,obj,unit,opts,val){var o={},$t=obj.children("select");if(typeof(opts)=="string"){if(val===undefined){return $t.data(opts)}o[opts]=val}else{o=opts}return tp_inst.control.create(tp_inst,obj,$t.data("unit"),$t.val(),o.min||$t.data("min"),o.max||$t.data("max"),o.step||$t.data("step"))},value:function(tp_inst,obj,unit,val){var $t=obj.children("select");if(val!==undefined){return $t.val(val)}return $t.val()}}}});$.fn.extend({timepicker:function(o){o=o||{};var tmp_args=Array.prototype.slice.call(arguments);if(typeof o=="object"){tmp_args[0]=$.extend(o,{timeOnly:true})}return $(this).each(function(){$.fn.datetimepicker.apply($(this),tmp_args)})},datetimepicker:function(o){o=o||{};var tmp_args=arguments;if(typeof(o)=="string"){if(o=="getDate"){return $.fn.datepicker.apply($(this[0]),tmp_args)}else{return this.each(function(){var $t=$(this);$t.datepicker.apply($t,tmp_args)})}}else{return this.each(function(){var $t=$(this);$t.datepicker($.timepicker._newInst($t,o)._defaults)})}}});$.datepicker.parseDateTime=function(dateFormat,timeFormat,dateTimeString,dateSettings,timeSettings){var parseRes=parseDateTimeInternal(dateFormat,timeFormat,dateTimeString,dateSettings,timeSettings);if(parseRes.timeObj){var t=parseRes.timeObj;parseRes.date.setHours(t.hour,t.minute,t.second,t.millisec)}return parseRes.date};$.datepicker.parseTime=function(timeFormat,timeString,options){var o=extendRemove(extendRemove({},$.timepicker._defaults),options||{});var strictParse=function(f,s,o){var getPatternAmpm=function(amNames,pmNames){var markers=[];if(amNames){$.merge(markers,amNames)}if(pmNames){$.merge(markers,pmNames)}markers=$.map(markers,function(val){return val.replace(/[.*+?|()\[\]{}\\]/g,"\\$&")});return"("+markers.join("|")+")?"};var getFormatPositions=function(timeFormat){var finds=timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z|'.*?')/g),orders={h:-1,m:-1,s:-1,l:-1,t:-1,z:-1};if(finds){for(var i=0;i<finds.length;i++){if(orders[finds[i].toString().charAt(0)]==-1){orders[finds[i].toString().charAt(0)]=i+1}}}return orders};var regstr="^"+f.toString().replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[lz]|'.*?')/g,function(match){switch(match.charAt(0).toLowerCase()){case"h":return"(\\d?\\d)";case"m":return"(\\d?\\d)";case"s":return"(\\d?\\d)";case"l":return"(\\d?\\d?\\d)";case"z":return"(z|[-+]\\d\\d:?\\d\\d|\\S+)?";case"t":return getPatternAmpm(o.amNames,o.pmNames);default:return"("+match.replace(/\'/g,"").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g,function(m){return"\\"+m})+")?"}}).replace(/\s/g,"\\s?")+o.timeSuffix+"$",order=getFormatPositions(f),ampm="",treg;treg=s.match(new RegExp(regstr,"i"));var resTime={hour:0,minute:0,second:0,millisec:0};if(treg){if(order.t!==-1){if(treg[order.t]===undefined||treg[order.t].length===0){ampm="";resTime.ampm=""}else{ampm=$.inArray(treg[order.t].toUpperCase(),o.amNames)!==-1?"AM":"PM";resTime.ampm=o[ampm=="AM"?"amNames":"pmNames"][0]}}if(order.h!==-1){if(ampm=="AM"&&treg[order.h]=="12"){resTime.hour=0}else{if(ampm=="PM"&&treg[order.h]!="12"){resTime.hour=parseInt(treg[order.h],10)+12}else{resTime.hour=Number(treg[order.h])}}}if(order.m!==-1){resTime.minute=Number(treg[order.m])}if(order.s!==-1){resTime.second=Number(treg[order.s])}if(order.l!==-1){resTime.millisec=Number(treg[order.l])}if(order.z!==-1&&treg[order.z]!==undefined){var tz=treg[order.z].toUpperCase();switch(tz.length){case 1:tz=o.timezoneIso8601?"Z":"+0000";break;case 5:if(o.timezoneIso8601){tz=tz.substring(1)=="0000"?"Z":tz.substring(0,3)+":"+tz.substring(3)}break;case 6:if(!o.timezoneIso8601){tz=tz=="Z"||tz.substring(1)=="00:00"?"+0000":tz.replace(/:/,"")}else{if(tz.substring(1)=="00:00"){tz="Z"}}break}resTime.timezone=tz}return resTime}return false};var looseParse=function(f,s,o){try{var d=new Date("2012-01-01 "+s);return{hour:d.getHours(),minutes:d.getMinutes(),seconds:d.getSeconds(),millisec:d.getMilliseconds(),timezone:$.timepicker.timeZoneOffsetString(d)}}catch(err){try{return strictParse(f,s,o)}catch(err2){$.datepicker.log("Unable to parse \ntimeString: "+s+"\ntimeFormat: "+f)}}return false};if(typeof o.parse==="function"){return o.parse(timeFormat,timeString,o)}if(o.parse==="loose"){return looseParse(timeFormat,timeString,o)}return strictParse(timeFormat,timeString,o)};$.datepicker.formatTime=function(format,time,options){options=options||{};options=$.extend({},$.timepicker._defaults,options);time=$.extend({hour:0,minute:0,second:0,millisec:0,timezone:"+0000"},time);var tmptime=format,ampmName=options.amNames[0],hour=parseInt(time.hour,10);if(hour>11){ampmName=options.pmNames[0]}tmptime=tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[lz]|('.*?'|".*?"))/g,function(match){switch(match){case"HH":return("0"+hour).slice(-2);case"H":return hour;case"hh":return("0"+convert24to12(hour)).slice(-2);case"h":return convert24to12(hour);case"mm":return("0"+time.minute).slice(-2);case"m":return time.minute;case"ss":return("0"+time.second).slice(-2);case"s":return time.second;case"l":return("00"+time.millisec).slice(-3);case"z":return time.timezone===null?options.defaultTimezone:time.timezone;case"T":return ampmName.charAt(0).toUpperCase();case"TT":return ampmName.toUpperCase();case"t":return ampmName.charAt(0).toLowerCase();case"tt":return ampmName.toLowerCase();default:return match.replace(/\'/g,"")||"'"}});tmptime=$.trim(tmptime);return tmptime};$.datepicker._base_selectDate=$.datepicker._selectDate;$.datepicker._selectDate=function(id,dateStr){var inst=this._getInst($(id)[0]),tp_inst=this._get(inst,"timepicker");if(tp_inst){tp_inst._limitMinMaxDateTime(inst,true);inst.inline=inst.stay_open=true;this._base_selectDate(id,dateStr);inst.inline=inst.stay_open=false;this._notifyChange(inst);this._updateDatepicker(inst)}else{this._base_selectDate(id,dateStr)}};$.datepicker._base_updateDatepicker=$.datepicker._updateDatepicker;$.datepicker._updateDatepicker=function(inst){var input=inst.input[0];if($.datepicker._curInst&&$.datepicker._curInst!=inst&&$.datepicker._datepickerShowing&&$.datepicker._lastInput!=input){return}if(typeof(inst.stay_open)!=="boolean"||inst.stay_open===false){this._base_updateDatepicker(inst);var tp_inst=this._get(inst,"timepicker");if(tp_inst){tp_inst._addTimePicker(inst);if(tp_inst._defaults.useLocalTimezone){var date=new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay,12);selectLocalTimeZone(tp_inst,date);tp_inst._onTimeChange()}}}};$.datepicker._base_doKeyPress=$.datepicker._doKeyPress;$.datepicker._doKeyPress=function(event){var inst=$.datepicker._getInst(event.target),tp_inst=$.datepicker._get(inst,"timepicker");if(tp_inst){if($.datepicker._get(inst,"constrainInput")){var ampm=useAmpm(tp_inst._defaults.timeFormat),dateChars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat")),datetimeChars=tp_inst._defaults.timeFormat.toString().replace(/[hms]/g,"").replace(/TT/g,ampm?"APM":"").replace(/Tt/g,ampm?"AaPpMm":"").replace(/tT/g,ampm?"AaPpMm":"").replace(/T/g,ampm?"AP":"").replace(/tt/g,ampm?"apm":"").replace(/t/g,ampm?"ap":"")+" "+tp_inst._defaults.separator+tp_inst._defaults.timeSuffix+(tp_inst._defaults.showTimezone?tp_inst._defaults.timezoneList.join(""):"")+(tp_inst._defaults.amNames.join(""))+(tp_inst._defaults.pmNames.join(""))+dateChars,chr=String.fromCharCode(event.charCode===undefined?event.keyCode:event.charCode);return event.ctrlKey||(chr<" "||!dateChars||datetimeChars.indexOf(chr)>-1)}}return $.datepicker._base_doKeyPress(event)};$.datepicker._base_updateAlternate=$.datepicker._updateAlternate;$.datepicker._updateAlternate=function(inst){var tp_inst=this._get(inst,"timepicker");if(tp_inst){var altField=tp_inst._defaults.altField;if(altField){var altFormat=tp_inst._defaults.altFormat||tp_inst._defaults.dateFormat,date=this._getDate(inst),formatCfg=$.datepicker._getFormatConfig(inst),altFormattedDateTime="",altSeparator=tp_inst._defaults.altSeparator?tp_inst._defaults.altSeparator:tp_inst._defaults.separator,altTimeSuffix=tp_inst._defaults.altTimeSuffix?tp_inst._defaults.altTimeSuffix:tp_inst._defaults.timeSuffix,altTimeFormat=tp_inst._defaults.altTimeFormat!==null?tp_inst._defaults.altTimeFormat:tp_inst._defaults.timeFormat;altFormattedDateTime+=$.datepicker.formatTime(altTimeFormat,tp_inst,tp_inst._defaults)+altTimeSuffix;if(!tp_inst._defaults.timeOnly&&!tp_inst._defaults.altFieldTimeOnly){if(tp_inst._defaults.altFormat){altFormattedDateTime=$.datepicker.formatDate(tp_inst._defaults.altFormat,(date===null?new Date():date),formatCfg)+altSeparator+altFormattedDateTime}else{altFormattedDateTime=tp_inst.formattedDate+altSeparator+altFormattedDateTime}}$(altField).val(altFormattedDateTime)}}else{$.datepicker._base_updateAlternate(inst)}};$.datepicker._base_doKeyUp=$.datepicker._doKeyUp;$.datepicker._doKeyUp=function(event){var inst=$.datepicker._getInst(event.target),tp_inst=$.datepicker._get(inst,"timepicker");if(tp_inst){if(tp_inst._defaults.timeOnly&&(inst.input.val()!=inst.lastVal)){try{$.datepicker._updateDatepicker(inst)}catch(err){$.datepicker.log(err)}}}return $.datepicker._base_doKeyUp(event)};$.datepicker._base_gotoToday=$.datepicker._gotoToday;$.datepicker._gotoToday=function(id){var inst=this._getInst($(id)[0]),$dp=inst.dpDiv;this._base_gotoToday(id);var tp_inst=this._get(inst,"timepicker");selectLocalTimeZone(tp_inst);var now=new Date();this._setTime(inst,now);$(".ui-datepicker-today",$dp).click()};$.datepicker._disableTimepickerDatepicker=function(target){var inst=this._getInst(target);if(!inst){return}var tp_inst=this._get(inst,"timepicker");$(target).datepicker("getDate");if(tp_inst){tp_inst._defaults.showTimepicker=false;tp_inst._updateDateTime(inst)}};$.datepicker._enableTimepickerDatepicker=function(target){var inst=this._getInst(target);if(!inst){return}var tp_inst=this._get(inst,"timepicker");$(target).datepicker("getDate");if(tp_inst){tp_inst._defaults.showTimepicker=true;tp_inst._addTimePicker(inst);tp_inst._updateDateTime(inst)}};$.datepicker._setTime=function(inst,date){var tp_inst=this._get(inst,"timepicker");if(tp_inst){var defaults=tp_inst._defaults;tp_inst.hour=date?date.getHours():defaults.hour;tp_inst.minute=date?date.getMinutes():defaults.minute;tp_inst.second=date?date.getSeconds():defaults.second;tp_inst.millisec=date?date.getMilliseconds():defaults.millisec;tp_inst._limitMinMaxDateTime(inst,true);tp_inst._onTimeChange();tp_inst._updateDateTime(inst)}};$.datepicker._setTimeDatepicker=function(target,date,withDate){var inst=this._getInst(target);if(!inst){return}var tp_inst=this._get(inst,"timepicker");if(tp_inst){this._setDateFromField(inst);var tp_date;if(date){if(typeof date=="string"){tp_inst._parseTime(date,withDate);tp_date=new Date();tp_date.setHours(tp_inst.hour,tp_inst.minute,tp_inst.second,tp_inst.millisec)}else{tp_date=new Date(date.getTime())}if(tp_date.toString()=="Invalid Date"){tp_date=undefined}this._setTime(inst,tp_date)}}};$.datepicker._base_setDateDatepicker=$.datepicker._setDateDatepicker;$.datepicker._setDateDatepicker=function(target,date){var inst=this._getInst(target);if(!inst){return}var tp_date=(date instanceof Date)?new Date(date.getTime()):date;this._updateDatepicker(inst);this._base_setDateDatepicker.apply(this,arguments);this._setTimeDatepicker(target,tp_date,true)};$.datepicker._base_getDateDatepicker=$.datepicker._getDateDatepicker;$.datepicker._getDateDatepicker=function(target,noDefault){var inst=this._getInst(target);if(!inst){return}var tp_inst=this._get(inst,"timepicker");if(tp_inst){if(inst.lastVal===undefined){this._setDateFromField(inst,noDefault)}var date=this._getDate(inst);if(date&&tp_inst._parseTime($(target).val(),tp_inst.timeOnly)){date.setHours(tp_inst.hour,tp_inst.minute,tp_inst.second,tp_inst.millisec)}return date}return this._base_getDateDatepicker(target,noDefault)};$.datepicker._base_parseDate=$.datepicker.parseDate;$.datepicker.parseDate=function(format,value,settings){var date;try{date=this._base_parseDate(format,value,settings)}catch(err){date=this._base_parseDate(format,value.substring(0,value.length-(err.length-err.indexOf(":")-2)),settings);$.datepicker.log("Error parsing the date string: "+err+"\ndate string = "+value+"\ndate format = "+format)}return date};$.datepicker._base_formatDate=$.datepicker._formatDate;$.datepicker._formatDate=function(inst,day,month,year){var tp_inst=this._get(inst,"timepicker");if(tp_inst){tp_inst._updateDateTime(inst);return tp_inst.$input.val()}return this._base_formatDate(inst)};$.datepicker._base_optionDatepicker=$.datepicker._optionDatepicker;$.datepicker._optionDatepicker=function(target,name,value){var inst=this._getInst(target),name_clone;if(!inst){return null}var tp_inst=this._get(inst,"timepicker");if(tp_inst){var min=null,max=null,onselect=null,overrides=tp_inst._defaults.evnts,fns={},prop;if(typeof name=="string"){if(name==="minDate"||name==="minDateTime"){min=value}else{if(name==="maxDate"||name==="maxDateTime"){max=value}else{if(name==="onSelect"){onselect=value}else{if(overrides.hasOwnProperty(name)){if(typeof(value)==="undefined"){return overrides[name]}fns[name]=value;name_clone={}}}}}}else{if(typeof name=="object"){if(name.minDate){min=name.minDate}else{if(name.minDateTime){min=name.minDateTime}else{if(name.maxDate){max=name.maxDate}else{if(name.maxDateTime){max=name.maxDateTime}}}}for(prop in overrides){if(overrides.hasOwnProperty(prop)&&name[prop]){fns[prop]=name[prop]}}}}for(prop in fns){if(fns.hasOwnProperty(prop)){overrides[prop]=fns[prop];if(!name_clone){name_clone=$.extend({},name)}delete name_clone[prop]}}if(name_clone&&isEmptyObject(name_clone)){return}if(min){if(min===0){min=new Date()}else{min=new Date(min)}tp_inst._defaults.minDate=min;tp_inst._defaults.minDateTime=min}else{if(max){if(max===0){max=new Date()}else{max=new Date(max)}tp_inst._defaults.maxDate=max;tp_inst._defaults.maxDateTime=max}else{if(onselect){tp_inst._defaults.onSelect=onselect}}}}if(value===undefined){return this._base_optionDatepicker.call($.datepicker,target,name)}return this._base_optionDatepicker.call($.datepicker,target,name_clone||name,value)};var isEmptyObject=function(obj){var prop;for(prop in obj){if(obj.hasOwnProperty(obj)){return false}}return true};var extendRemove=function(target,props){$.extend(target,props);for(var name in props){if(props[name]===null||props[name]===undefined){target[name]=props[name]}}return target};var useAmpm=function(timeFormat){return(timeFormat.indexOf("t")!==-1&&timeFormat.indexOf("h")!==-1)};var convert24to12=function(hour){if(hour>12){hour=hour-12}if(hour==0){hour=12}return String(hour)};var splitDateTime=function(dateFormat,dateTimeString,dateSettings,timeSettings){try{var separator=timeSettings&&timeSettings.separator?timeSettings.separator:$.timepicker._defaults.separator,format=timeSettings&&timeSettings.timeFormat?timeSettings.timeFormat:$.timepicker._defaults.timeFormat,timeParts=format.split(separator),timePartsLen=timeParts.length,allParts=dateTimeString.split(separator),allPartsLen=allParts.length;if(allPartsLen>1){return[allParts.splice(0,allPartsLen-timePartsLen).join(separator),allParts.splice(0,timePartsLen).join(separator)]}}catch(err){$.datepicker.log("Could not split the date from the time. Please check the following datetimepicker options\nthrown error: "+err+"\ndateTimeString"+dateTimeString+"\ndateFormat = "+dateFormat+"\nseparator = "+timeSettings.separator+"\ntimeFormat = "+timeSettings.timeFormat);if(err.indexOf(":")>=0){var dateStringLength=dateTimeString.length-(err.length-err.indexOf(":")-2),timeString=dateTimeString.substring(dateStringLength);return[$.trim(dateTimeString.substring(0,dateStringLength)),$.trim(dateTimeString.substring(dateStringLength))]}else{throw err}}return[dateTimeString,""]};var parseDateTimeInternal=function(dateFormat,timeFormat,dateTimeString,dateSettings,timeSettings){var date;var splitRes=splitDateTime(dateFormat,dateTimeString,dateSettings,timeSettings);date=$.datepicker._base_parseDate(dateFormat,splitRes[0],dateSettings);if(splitRes[1]!==""){var timeString=splitRes[1],parsedTime=$.datepicker.parseTime(timeFormat,timeString,timeSettings);if(parsedTime===null){throw"Wrong time format"}return{date:date,timeObj:parsedTime}}else{return{date:date}}};var selectLocalTimeZone=function(tp_inst,date){if(tp_inst&&tp_inst.timezone_select){tp_inst._defaults.useLocalTimezone=true;var now=typeof date!=="undefined"?date:new Date();var tzoffset=$.timepicker.timeZoneOffsetString(now);if(tp_inst._defaults.timezoneIso8601){tzoffset=tzoffset.substring(0,3)+":"+tzoffset.substring(3)}tp_inst.timezone_select.val(tzoffset)}};$.timepicker=new Timepicker();$.timepicker.timeZoneOffsetString=function(date){var off=date.getTimezoneOffset()*-1,minutes=off%60,hours=(off-minutes)/60;return(off>=0?"+":"-")+("0"+(hours*101).toString()).substr(-2)+("0"+(minutes*101).toString()).substr(-2)};$.timepicker.timeRange=function(startTime,endTime,options){return $.timepicker.handleRange("timepicker",startTime,endTime,options)};$.timepicker.dateTimeRange=function(startTime,endTime,options){$.timepicker.dateRange(startTime,endTime,options,"datetimepicker")};$.timepicker.dateRange=function(startTime,endTime,options,method){method=method||"datepicker";$.timepicker.handleRange(method,startTime,endTime,options)};$.timepicker.handleRange=function(method,startTime,endTime,options){$.fn[method].call(startTime,$.extend({onClose:function(dateText,inst){checkDates(this,endTime,dateText)},onSelect:function(selectedDateTime){selected(this,endTime,"minDate")}},options,options.start));$.fn[method].call(endTime,$.extend({onClose:function(dateText,inst){checkDates(this,startTime,dateText)},onSelect:function(selectedDateTime){selected(this,startTime,"maxDate")}},options,options.end));if(method!="timepicker"&&options.reformat){$([startTime,endTime]).each(function(){var format=$(this)[method].call($(this),"option","dateFormat"),date=new Date($(this).val());if($(this).val()&&date){$(this).val($.datepicker.formatDate(format,date))}})}checkDates(startTime,endTime,startTime.val());function checkDates(changed,other,dateText){if(other.val()&&(new Date(startTime.val())>new Date(endTime.val()))){other.val(dateText)}}selected(startTime,endTime,"minDate");selected(endTime,startTime,"maxDate");function selected(changed,other,option){if(!$(changed).val()){return}var date=$(changed)[method].call($(changed),"getDate");if(date.getTime){$(other)[method].call($(other),"option",option,date)}}return $([startTime.get(0),endTime.get(0)])};$.timepicker.version="1.1.1"})(jQuery);
b'\\ No newline at end of file'
2
* jQuery timepicker addon
3
* By: Trent Richardson [http://trentrichardson.com]
5
* Last Modified: 11/07/2012
7
* Copyright 2012 Trent Richardson
8
* You may use this project under MIT or GPL licenses.
9
* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
10
* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
13
/*jslint evil: true, white: false, undef: false, nomen: false */
18
* Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded"
20
$.ui.timepicker = $.ui.timepicker || {};
21
if ($.ui.timepicker.version) {
26
* Extend jQueryUI, get it started with our version number
36
* Use the singleton instance of this class, $.timepicker, to interact with the time picker.
37
* Settings for (groups of) time pickers are maintained in an instance object,
38
* allowing multiple different settings on the same page.
40
function Timepicker() {
41
this.regional = []; // Available regional settings, indexed by language code
42
this.regional[''] = { // Default regional settings
49
timeOnlyTitle: 'Choose Time',
54
millisecText: 'Millisecond',
55
timezoneText: 'Time Zone',
58
this._defaults = { // Global defaults for all the datetime picker instances
59
showButtonPanel: true,
76
useLocalTimezone: false,
77
defaultTimezone: "+0000",
95
altFieldTimeOnly: true,
99
pickerTimeFormat: null,
100
pickerTimeSuffix: null,
101
showTimepicker: true,
102
timezoneIso8601: false,
104
addSliderAccess: false,
105
sliderAccessArgs: null,
106
controlType: 'slider',
110
$.extend(this._defaults, this.regional['']);
113
$.extend(Timepicker.prototype, {
121
millisec_slider: null,
122
timezone_select: null,
128
defaultTimezone: "+0000",
129
hourMinOriginal: null,
130
minuteMinOriginal: null,
131
secondMinOriginal: null,
132
millisecMinOriginal: null,
133
hourMaxOriginal: null,
134
minuteMaxOriginal: null,
135
secondMaxOriginal: null,
136
millisecMaxOriginal: null,
140
formattedDateTime: '',
142
units: ['hour','minute','second','millisec'],
146
* Override the default settings for all instances of the time picker.
147
* @param settings object - the new settings to use as defaults (anonymous object)
148
* @return the manager object
150
setDefaults: function(settings) {
151
extendRemove(this._defaults, settings || {});
156
* Create a new Timepicker instance
158
_newInst: function($input, o) {
159
var tp_inst = new Timepicker(),
164
for (var attrName in this._defaults) {
165
if(this._defaults.hasOwnProperty(attrName)){
166
var attrValue = $input.attr('time:' + attrName);
169
inlineSettings[attrName] = eval(attrValue);
171
inlineSettings[attrName] = attrValue;
177
beforeShow: function (input, dp_inst) {
178
if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {
179
return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);
182
onChangeMonthYear: function (year, month, dp_inst) {
183
// Update the time as well : this prevents the time from disappearing from the $input field.
184
tp_inst._updateDateTime(dp_inst);
185
if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {
186
tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);
189
onClose: function (dateText, dp_inst) {
190
if (tp_inst.timeDefined === true && $input.val() !== '') {
191
tp_inst._updateDateTime(dp_inst);
193
if ($.isFunction(tp_inst._defaults.evnts.onClose)) {
194
tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);
198
for (i in overrides) {
199
if (overrides.hasOwnProperty(i)) {
200
fns[i] = o[i] || null;
203
tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, overrides, {
205
timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
207
tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) {
208
return val.toUpperCase();
210
tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) {
211
return val.toUpperCase();
214
// controlType is string - key to our this._controls
215
if(typeof(tp_inst._defaults.controlType) === 'string'){
216
if($.fn[tp_inst._defaults.controlType] === undefined){
217
tp_inst._defaults.controlType = 'select';
219
tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];
221
// controlType is an object and must implement create, options, value methods
223
tp_inst.control = tp_inst._defaults.controlType;
226
if (tp_inst._defaults.timezoneList === null) {
227
var timezoneList = ['-1200', '-1100', '-1000', '-0930', '-0900', '-0800', '-0700', '-0600', '-0500', '-0430', '-0400', '-0330', '-0300', '-0200', '-0100', '+0000',
228
'+0100', '+0200', '+0300', '+0330', '+0400', '+0430', '+0500', '+0530', '+0545', '+0600', '+0630', '+0700', '+0800', '+0845', '+0900', '+0930',
229
'+1000', '+1030', '+1100', '+1130', '+1200', '+1245', '+1300', '+1400'];
231
if (tp_inst._defaults.timezoneIso8601) {
232
timezoneList = $.map(timezoneList, function(val) {
233
return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3));
236
tp_inst._defaults.timezoneList = timezoneList;
239
tp_inst.timezone = tp_inst._defaults.timezone;
240
tp_inst.hour = tp_inst._defaults.hour;
241
tp_inst.minute = tp_inst._defaults.minute;
242
tp_inst.second = tp_inst._defaults.second;
243
tp_inst.millisec = tp_inst._defaults.millisec;
245
tp_inst.$input = $input;
248
tp_inst.$altInput = $(o.altField).css({
250
}).focus(function() {
251
$input.trigger("focus");
255
if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {
256
tp_inst._defaults.minDate = new Date();
258
if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {
259
tp_inst._defaults.maxDate = new Date();
262
// datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..
263
if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {
264
tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());
266
if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {
267
tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());
269
if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {
270
tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());
272
if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {
273
tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());
275
tp_inst.$input.bind('focus', function() {
283
* add our sliders to the calendar
285
_addTimePicker: function(dp_inst) {
286
var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val();
288
this.timeDefined = this._parseTime(currDT);
289
this._limitMinMaxDateTime(dp_inst, false);
290
this._injectTimePicker();
294
* parse the time string from input value or _setTime
296
_parseTime: function(timeString, withDate) {
298
this.inst = $.datepicker._getInst(this.$input[0]);
301
if (withDate || !this._defaults.timeOnly) {
302
var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
304
var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);
305
if (!parseRes.timeObj) {
308
$.extend(this, parseRes.timeObj);
310
$.datepicker.log("Error parsing the date/time string: " + err +
311
"\ndate/time string = " + timeString +
312
"\ntimeFormat = " + this._defaults.timeFormat +
313
"\ndateFormat = " + dp_dateFormat);
318
var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);
322
$.extend(this, timeObj);
328
* generate and inject html for timepicker into ui datepicker
330
_injectTimePicker: function() {
331
var $dp = this.inst.dpDiv,
332
o = this.inst.settings,
340
// Prevent displaying twice
341
if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) {
342
var noDisplay = ' style="display:none;"',
343
html = '<div class="ui-timepicker-div'+ (o.isRTL? ' ui-timepicker-rtl' : '') +'"><dl>' + '<dt class="ui_tpicker_time_label"' + ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +
344
'<dd class="ui_tpicker_time"' + ((o.showTime) ? '' : noDisplay) + '></dd>';
347
for(var i=0,l=this.units.length; i<l; i++){
348
litem = this.units[i];
349
uitem = litem.substr(0,1).toUpperCase() + litem.substr(1);
350
// Added by Peter Medeiros:
351
// - Figure out what the hour/minute/second max should be based on the step values.
352
// - Example: if stepMinute is 15, then minMax is 45.
353
max[litem] = parseInt((o[litem+'Max'] - ((o[litem+'Max'] - o[litem+'Min']) % o['step'+uitem])), 10);
356
html += '<dt class="ui_tpicker_'+ litem +'_label"' + ((o['show'+uitem]) ? '' : noDisplay) + '>' + o[litem +'Text'] + '</dt>' +
357
'<dd class="ui_tpicker_'+ litem +'"><div class="ui_tpicker_'+ litem +'_slider"' + ((o['show'+uitem]) ? '' : noDisplay) + '></div>';
359
if (o['show'+uitem] && o[litem+'Grid'] > 0) {
360
html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';
363
for (var h = o[litem+'Min']; h <= max[litem]; h += parseInt(o[litem+'Grid'], 10)) {
365
var tmph = $.datepicker.formatTime(useAmpm(o.pickerTimeFormat || o.timeFormat)? 'hht':'HH', {hour:h}, o);
366
html += '<td data-for="'+litem+'">' + tmph + '</td>';
370
for (var m = o[litem+'Min']; m <= max[litem]; m += parseInt(o[litem+'Grid'], 10)) {
372
html += '<td data-for="'+litem+'">' + ((m < 10) ? '0' : '') + m + '</td>';
376
html += '</tr></table></div>';
382
html += '<dt class="ui_tpicker_timezone_label"' + ((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>';
383
html += '<dd class="ui_tpicker_timezone" ' + ((o.showTimezone) ? '' : noDisplay) + '></dd>';
385
// Create the elements from string
386
html += '</dl></div>';
389
// if we only want time picker...
390
if (o.timeOnly === true) {
391
$tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>');
392
$dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();
395
// add sliders, adjust grids, add events
396
for(var i=0,l=tp_inst.units.length; i<l; i++){
397
litem = tp_inst.units[i];
398
uitem = litem.substr(0,1).toUpperCase() + litem.substr(1);
401
tp_inst[litem+'_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_'+litem+'_slider'), litem, tp_inst[litem], o[litem+'Min'], max[litem], o['step'+uitem]);
403
// adjust the grid and add click event
404
if (o['show'+uitem] && o[litem+'Grid'] > 0) {
405
size = 100 * gridSize[litem] * o[litem+'Grid'] / (max[litem] - o[litem+'Min']);
406
$tp.find('.ui_tpicker_'+litem+' table').css({
408
marginLeft: o.isRTL? '0' : ((size / (-2 * gridSize[litem])) + "%"),
409
marginRight: o.isRTL? ((size / (-2 * gridSize[litem])) + "%") : '0',
410
borderCollapse: 'collapse'
411
}).find("td").click(function(e){
414
n = parseInt(h.replace(/[^0-9]/g),10),
415
ap = h.replace(/[^apm]/ig),
416
f = $t.data('for'); // loses scope, so we use data-for
419
if(ap.indexOf('p') !== -1 && n < 12){
423
if(ap.indexOf('a') !== -1 && n === 12){
429
tp_inst.control.value(tp_inst, tp_inst[f+'_slider'], litem, n);
431
tp_inst._onTimeChange();
432
tp_inst._onSelectHandler();
436
width: (100 / gridSize[litem]) + '%',
443
// Add timezone options
444
this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select");
445
$.fn.append.apply(this.timezone_select,
446
$.map(o.timezoneList, function(val, idx) {
447
return $("<option />").val(typeof val == "object" ? val.value : val).text(typeof val == "object" ? val.label : val);
449
if (typeof(this.timezone) != "undefined" && this.timezone !== null && this.timezone !== "") {
450
var local_date = new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12);
451
var local_timezone = $.timepicker.timeZoneOffsetString(local_date);
452
if (local_timezone == this.timezone) {
453
selectLocalTimeZone(tp_inst);
455
this.timezone_select.val(this.timezone);
458
if (typeof(this.hour) != "undefined" && this.hour !== null && this.hour !== "") {
459
this.timezone_select.val(o.defaultTimezone);
461
selectLocalTimeZone(tp_inst);
464
this.timezone_select.change(function() {
465
tp_inst._defaults.useLocalTimezone = false;
466
tp_inst._onTimeChange();
468
// End timezone options
470
// inject timepicker into datepicker
471
var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');
472
if ($buttonPanel.length) {
473
$buttonPanel.before($tp);
478
this.$timeObj = $tp.find('.ui_tpicker_time');
480
if (this.inst !== null) {
481
var timeDefined = this.timeDefined;
482
this._onTimeChange();
483
this.timeDefined = timeDefined;
486
// slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/
487
if (this._defaults.addSliderAccess) {
488
var sliderAccessArgs = this._defaults.sliderAccessArgs,
489
rtl = this._defaults.isRTL;
490
sliderAccessArgs.isRTL = rtl;
492
setTimeout(function() { // fix for inline mode
493
if ($tp.find('.ui-slider-access').length === 0) {
494
$tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);
496
// fix any grids since sliders are shorter
497
var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);
498
if (sliderAccessWidth) {
499
$tp.find('table:visible').each(function() {
501
oldWidth = $g.outerWidth(),
502
oldMarginLeft = $g.css(rtl? 'marginRight':'marginLeft').toString().replace('%', ''),
503
newWidth = oldWidth - sliderAccessWidth,
504
newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',
505
css = { width: newWidth, marginRight: 0, marginLeft: 0 };
506
css[rtl? 'marginRight':'marginLeft'] = newMarginLeft;
513
// end slideAccess integration
519
* This function tries to limit the ability to go outside the
522
_limitMinMaxDateTime: function(dp_inst, adjustSliders) {
523
var o = this._defaults,
524
dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);
526
if (!this._defaults.showTimepicker) {
528
} // No time so nothing to check here
530
if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {
531
var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),
532
minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);
534
if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null) {
535
this.hourMinOriginal = o.hourMin;
536
this.minuteMinOriginal = o.minuteMin;
537
this.secondMinOriginal = o.secondMin;
538
this.millisecMinOriginal = o.millisecMin;
541
if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) {
542
this._defaults.hourMin = minDateTime.getHours();
543
if (this.hour <= this._defaults.hourMin) {
544
this.hour = this._defaults.hourMin;
545
this._defaults.minuteMin = minDateTime.getMinutes();
546
if (this.minute <= this._defaults.minuteMin) {
547
this.minute = this._defaults.minuteMin;
548
this._defaults.secondMin = minDateTime.getSeconds();
549
if (this.second <= this._defaults.secondMin) {
550
this.second = this._defaults.secondMin;
551
this._defaults.millisecMin = minDateTime.getMilliseconds();
553
if (this.millisec < this._defaults.millisecMin) {
554
this.millisec = this._defaults.millisecMin;
556
this._defaults.millisecMin = this.millisecMinOriginal;
559
this._defaults.secondMin = this.secondMinOriginal;
560
this._defaults.millisecMin = this.millisecMinOriginal;
563
this._defaults.minuteMin = this.minuteMinOriginal;
564
this._defaults.secondMin = this.secondMinOriginal;
565
this._defaults.millisecMin = this.millisecMinOriginal;
568
this._defaults.hourMin = this.hourMinOriginal;
569
this._defaults.minuteMin = this.minuteMinOriginal;
570
this._defaults.secondMin = this.secondMinOriginal;
571
this._defaults.millisecMin = this.millisecMinOriginal;
575
if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {
576
var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),
577
maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);
579
if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null) {
580
this.hourMaxOriginal = o.hourMax;
581
this.minuteMaxOriginal = o.minuteMax;
582
this.secondMaxOriginal = o.secondMax;
583
this.millisecMaxOriginal = o.millisecMax;
586
if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()) {
587
this._defaults.hourMax = maxDateTime.getHours();
588
if (this.hour >= this._defaults.hourMax) {
589
this.hour = this._defaults.hourMax;
590
this._defaults.minuteMax = maxDateTime.getMinutes();
591
if (this.minute >= this._defaults.minuteMax) {
592
this.minute = this._defaults.minuteMax;
593
this._defaults.secondMax = maxDateTime.getSeconds();
594
} else if (this.second >= this._defaults.secondMax) {
595
this.second = this._defaults.secondMax;
596
this._defaults.millisecMax = maxDateTime.getMilliseconds();
598
if (this.millisec > this._defaults.millisecMax) {
599
this.millisec = this._defaults.millisecMax;
601
this._defaults.millisecMax = this.millisecMaxOriginal;
604
this._defaults.minuteMax = this.minuteMaxOriginal;
605
this._defaults.secondMax = this.secondMaxOriginal;
606
this._defaults.millisecMax = this.millisecMaxOriginal;
609
this._defaults.hourMax = this.hourMaxOriginal;
610
this._defaults.minuteMax = this.minuteMaxOriginal;
611
this._defaults.secondMax = this.secondMaxOriginal;
612
this._defaults.millisecMax = this.millisecMaxOriginal;
616
if (adjustSliders !== undefined && adjustSliders === true) {
617
var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),
618
minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),
619
secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),
620
millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10);
622
if (this.hour_slider) {
623
this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax });
624
this.control.value(this, this.hour_slider, 'hour', this.hour);
626
if (this.minute_slider) {
627
this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax });
628
this.control.value(this, this.minute_slider, 'minute', this.minute);
630
if (this.second_slider) {
631
this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax });
632
this.control.value(this, this.second_slider, 'second', this.second);
634
if (this.millisec_slider) {
635
this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax });
636
this.control.value(this, this.millisec_slider, 'millisec', this.millisec);
643
* when a slider moves, set the internal time...
644
* on time change is also called when the time is updated in the text field
646
_onTimeChange: function() {
647
var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,
648
minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,
649
second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,
650
millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,
651
timezone = (this.timezone_select) ? this.timezone_select.val() : false,
653
pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,
654
pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;
656
if (typeof(hour) == 'object') {
659
if (typeof(minute) == 'object') {
662
if (typeof(second) == 'object') {
665
if (typeof(millisec) == 'object') {
668
if (typeof(timezone) == 'object') {
672
if (hour !== false) {
673
hour = parseInt(hour, 10);
675
if (minute !== false) {
676
minute = parseInt(minute, 10);
678
if (second !== false) {
679
second = parseInt(second, 10);
681
if (millisec !== false) {
682
millisec = parseInt(millisec, 10);
685
var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];
687
// If the update was done in the input field, the input field should not be updated.
688
// If the update was done using the sliders, update the input field.
689
var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || millisec != this.millisec
690
|| (this.ampm.length > 0 && (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1))
691
|| ((this.timezone === null && timezone != this.defaultTimezone) || (this.timezone !== null && timezone != this.timezone)));
695
if (hour !== false) {
698
if (minute !== false) {
699
this.minute = minute;
701
if (second !== false) {
702
this.second = second;
704
if (millisec !== false) {
705
this.millisec = millisec;
707
if (timezone !== false) {
708
this.timezone = timezone;
712
this.inst = $.datepicker._getInst(this.$input[0]);
715
this._limitMinMaxDateTime(this.inst, true);
717
if (useAmpm(o.timeFormat)) {
721
// Updates the time within the timepicker
722
this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);
724
if(pickerTimeFormat === o.timeFormat){
725
this.$timeObj.text(this.formattedTime + pickerTimeSuffix);
728
this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);
732
this.timeDefined = true;
734
this._updateDateTime();
739
* call custom onSelect.
740
* bind to sliders slidestop, and grid click.
742
_onSelectHandler: function() {
743
var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;
744
var inputEl = this.$input ? this.$input[0] : null;
745
if (onSelect && inputEl) {
746
onSelect.apply(inputEl, [this.formattedDateTime, this]);
751
* update our input with the new date time..
753
_updateDateTime: function(dp_inst) {
754
dp_inst = this.inst || dp_inst;
755
var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),
756
dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),
757
formatCfg = $.datepicker._getFormatConfig(dp_inst),
758
timeAvailable = dt !== null && this.timeDefined;
759
this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);
760
var formattedDateTime = this.formattedDate;
763
* remove following lines to force every changes in date picker to change the input value
764
* Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.
765
* If the user manually empty the value in the input field, the date picker will never change selected value.
767
//if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {
771
if (this._defaults.timeOnly === true) {
772
formattedDateTime = this.formattedTime;
773
} else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {
774
formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;
777
this.formattedDateTime = formattedDateTime;
779
if (!this._defaults.showTimepicker) {
780
this.$input.val(this.formattedDate);
781
} else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {
782
this.$altInput.val(this.formattedTime);
783
this.$input.val(this.formattedDate);
784
} else if (this.$altInput) {
785
this.$input.val(formattedDateTime);
786
var altFormattedDateTime = '',
787
altSeparator = this._defaults.altSeparator ? this._defaults.altSeparator : this._defaults.separator,
788
altTimeSuffix = this._defaults.altTimeSuffix ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;
790
if (this._defaults.altFormat) altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);
791
else altFormattedDateTime = this.formattedDate;
792
if (altFormattedDateTime) altFormattedDateTime += altSeparator;
793
if (this._defaults.altTimeFormat) altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;
794
else altFormattedDateTime += this.formattedTime + altTimeSuffix;
795
this.$altInput.val(altFormattedDateTime);
797
this.$input.val(formattedDateTime);
800
this.$input.trigger("change");
803
_onFocus: function() {
804
if (!this.$input.val() && this._defaults.defaultValue) {
805
this.$input.val(this._defaults.defaultValue);
806
var inst = $.datepicker._getInst(this.$input.get(0)),
807
tp_inst = $.datepicker._get(inst, 'timepicker');
809
if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {
811
$.datepicker._updateDatepicker(inst);
813
$.datepicker.log(err);
821
* Small abstraction to control types
822
* We can add more, just be sure to follow the pattern: create, options, value
827
create: function(tp_inst, obj, unit, val, min, max, step){
828
var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60
829
return obj.prop('slide', null).slider({
830
orientation: "horizontal",
831
value: rtl? val*-1 : val,
832
min: rtl? max*-1 : min,
833
max: rtl? min*-1 : max,
835
slide: function(event, ui) {
836
tp_inst.control.value(tp_inst, $(this), unit, rtl? ui.value*-1:ui.value);
837
tp_inst._onTimeChange();
839
stop: function(event, ui) {
840
tp_inst._onSelectHandler();
844
options: function(tp_inst, obj, unit, opts, val){
845
if(tp_inst._defaults.isRTL){
846
if(typeof(opts) == 'string'){
847
if(opts == 'min' || opts == 'max'){
848
if(val !== undefined)
849
return obj.slider(opts, val*-1);
850
return Math.abs(obj.slider(opts));
852
return obj.slider(opts);
856
opts.min = opts.max = null;
857
if(min !== undefined)
859
if(max !== undefined)
861
return obj.slider(opts);
863
if(typeof(opts) == 'string' && val !== undefined)
864
return obj.slider(opts, val);
865
return obj.slider(opts);
867
value: function(tp_inst, obj, unit, val){
868
if(tp_inst._defaults.isRTL){
869
if(val !== undefined)
870
return obj.slider('value', val*-1);
871
return Math.abs(obj.slider('value'));
873
if(val !== undefined)
874
return obj.slider('value', val);
875
return obj.slider('value');
880
create: function(tp_inst, obj, unit, val, min, max, step){
881
var sel = '<select class="ui-timepicker-select" data-unit="'+ unit +'" data-min="'+ min +'" data-max="'+ max +'" data-step="'+ step +'">',
882
ul = tp_inst._defaults.timeFormat.indexOf('t') !== -1? 'toLowerCase':'toUpperCase',
885
for(var i=min; i<=max; i+=step){
886
sel += '<option value="'+ i +'"'+ (i==val? ' selected':'') +'>';
887
if(unit == 'hour' && useAmpm(tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat))
888
sel += $.datepicker.formatTime("hh TT", {hour:i}, tp_inst._defaults);
889
else if(unit == 'millisec' || i >= 10) sel += i;
890
else sel += '0'+ i.toString();
895
obj.children('select').remove();
897
$(sel).appendTo(obj).change(function(e){
898
tp_inst._onTimeChange();
899
tp_inst._onSelectHandler();
904
options: function(tp_inst, obj, unit, opts, val){
906
$t = obj.children('select');
907
if(typeof(opts) == 'string'){
908
if(val === undefined)
909
return $t.data(opts);
913
return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min || $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));
915
value: function(tp_inst, obj, unit, val){
916
var $t = obj.children('select');
917
if(val !== undefined)
928
* shorthand just to use timepicker..
930
timepicker: function(o) {
932
var tmp_args = Array.prototype.slice.call(arguments);
934
if (typeof o == 'object') {
935
tmp_args[0] = $.extend(o, {
940
return $(this).each(function() {
941
$.fn.datetimepicker.apply($(this), tmp_args);
946
* extend timepicker to datepicker
948
datetimepicker: function(o) {
950
var tmp_args = arguments;
952
if (typeof(o) == 'string') {
953
if (o == 'getDate') {
954
return $.fn.datepicker.apply($(this[0]), tmp_args);
956
return this.each(function() {
958
$t.datepicker.apply($t, tmp_args);
962
return this.each(function() {
964
$t.datepicker($.timepicker._newInst($t, o)._defaults);
971
* Public Utility to parse date and time
973
$.datepicker.parseDateTime = function(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {
974
var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);
975
if (parseRes.timeObj) {
976
var t = parseRes.timeObj;
977
parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);
980
return parseRes.date;
984
* Public utility to parse time
986
$.datepicker.parseTime = function(timeFormat, timeString, options) {
987
var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {});
989
// Strict parse requires the timeString to match the timeFormat exactly
990
var strictParse = function(f, s, o){
992
// pattern for standard and localized AM/PM markers
993
var getPatternAmpm = function(amNames, pmNames) {
996
$.merge(markers, amNames);
999
$.merge(markers, pmNames);
1001
markers = $.map(markers, function(val) {
1002
return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&');
1004
return '(' + markers.join('|') + ')?';
1007
// figure out position of time elements.. cause js cant do named captures
1008
var getFormatPositions = function(timeFormat) {
1009
var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z|'.*?')/g),
1020
for (var i = 0; i < finds.length; i++) {
1021
if (orders[finds[i].toString().charAt(0)] == -1) {
1022
orders[finds[i].toString().charAt(0)] = i + 1;
1029
var regstr = '^' + f.toString()
1030
.replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[lz]|'.*?')/g, function (match) {
1031
switch (match.charAt(0).toLowerCase()) {
1032
case 'h': return '(\\d?\\d)';
1033
case 'm': return '(\\d?\\d)';
1034
case 's': return '(\\d?\\d)';
1035
case 'l': return '(\\d?\\d?\\d)';
1036
case 'z': return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?';
1037
case 't': return getPatternAmpm(o.amNames, o.pmNames);
1038
default: // literal escaped in quotes
1039
return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?';
1042
.replace(/\s/g, '\\s?') +
1044
order = getFormatPositions(f),
1048
treg = s.match(new RegExp(regstr, 'i'));
1058
if (order.t !== -1) {
1059
if (treg[order.t] === undefined || treg[order.t].length === 0) {
1063
ampm = $.inArray(treg[order.t].toUpperCase(), o.amNames) !== -1 ? 'AM' : 'PM';
1064
resTime.ampm = o[ampm == 'AM' ? 'amNames' : 'pmNames'][0];
1068
if (order.h !== -1) {
1069
if (ampm == 'AM' && treg[order.h] == '12') {
1070
resTime.hour = 0; // 12am = 0 hour
1072
if (ampm == 'PM' && treg[order.h] != '12') {
1073
resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12
1075
resTime.hour = Number(treg[order.h]);
1080
if (order.m !== -1) {
1081
resTime.minute = Number(treg[order.m]);
1083
if (order.s !== -1) {
1084
resTime.second = Number(treg[order.s]);
1086
if (order.l !== -1) {
1087
resTime.millisec = Number(treg[order.l]);
1089
if (order.z !== -1 && treg[order.z] !== undefined) {
1090
var tz = treg[order.z].toUpperCase();
1091
switch (tz.length) {
1094
tz = o.timezoneIso8601 ? 'Z' : '+0000';
1098
if (o.timezoneIso8601) {
1099
tz = tz.substring(1) == '0000' ? 'Z' : tz.substring(0, 3) + ':' + tz.substring(3);
1104
if (!o.timezoneIso8601) {
1105
tz = tz == 'Z' || tz.substring(1) == '00:00' ? '+0000' : tz.replace(/:/, '');
1107
if (tz.substring(1) == '00:00') {
1113
resTime.timezone = tz;
1120
};// end strictParse
1122
// First try JS Date, if that fails, use strictParse
1123
var looseParse = function(f,s,o){
1125
var d = new Date('2012-01-01 '+ s);
1128
minutes: d.getMinutes(),
1129
seconds: d.getSeconds(),
1130
millisec: d.getMilliseconds(),
1131
timezone: $.timepicker.timeZoneOffsetString(d)
1136
return strictParse(f,s,o);
1139
$.datepicker.log("Unable to parse \ntimeString: "+ s +"\ntimeFormat: "+ f);
1143
}; // end looseParse
1145
if(typeof o.parse === "function"){
1146
return o.parse(timeFormat, timeString, o)
1148
if(o.parse === 'loose'){
1149
return looseParse(timeFormat, timeString, o);
1151
return strictParse(timeFormat, timeString, o);
1155
* Public utility to format the time
1156
* format = string format of the time
1157
* time = a {}, not a Date() for timezones
1158
* options = essentially the regional[].. amNames, pmNames, ampm
1160
$.datepicker.formatTime = function(format, time, options) {
1161
options = options || {};
1162
options = $.extend({}, $.timepicker._defaults, options);
1171
var tmptime = format,
1172
ampmName = options.amNames[0],
1173
hour = parseInt(time.hour, 10);
1176
ampmName = options.pmNames[0];
1179
tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[lz]|('.*?'|".*?"))/g, function(match) {
1182
return ('0' + hour).slice(-2);
1186
return ('0' + convert24to12(hour)).slice(-2);
1188
return convert24to12(hour);
1190
return ('0' + time.minute).slice(-2);
1194
return ('0' + time.second).slice(-2);
1198
return ('00' + time.millisec).slice(-3);
1200
return time.timezone === null? options.defaultTimezone : time.timezone;
1202
return ampmName.charAt(0).toUpperCase();
1204
return ampmName.toUpperCase();
1206
return ampmName.charAt(0).toLowerCase();
1208
return ampmName.toLowerCase();
1210
return match.replace(/\'/g, "") || "'";
1214
tmptime = $.trim(tmptime);
1219
* the bad hack :/ override datepicker so it doesnt close on select
1220
// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378
1222
$.datepicker._base_selectDate = $.datepicker._selectDate;
1223
$.datepicker._selectDate = function(id, dateStr) {
1224
var inst = this._getInst($(id)[0]),
1225
tp_inst = this._get(inst, 'timepicker');
1228
tp_inst._limitMinMaxDateTime(inst, true);
1229
inst.inline = inst.stay_open = true;
1230
//This way the onSelect handler called from calendarpicker get the full dateTime
1231
this._base_selectDate(id, dateStr);
1232
inst.inline = inst.stay_open = false;
1233
this._notifyChange(inst);
1234
this._updateDatepicker(inst);
1236
this._base_selectDate(id, dateStr);
1241
* second bad hack :/ override datepicker so it triggers an event when changing the input field
1242
* and does not redraw the datepicker on every selectDate event
1244
$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;
1245
$.datepicker._updateDatepicker = function(inst) {
1247
// don't popup the datepicker if there is another instance already opened
1248
var input = inst.input[0];
1249
if ($.datepicker._curInst && $.datepicker._curInst != inst && $.datepicker._datepickerShowing && $.datepicker._lastInput != input) {
1253
if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {
1255
this._base_updateDatepicker(inst);
1257
// Reload the time control when changing something in the input text field.
1258
var tp_inst = this._get(inst, 'timepicker');
1260
tp_inst._addTimePicker(inst);
1262
if (tp_inst._defaults.useLocalTimezone) { //checks daylight saving with the new date.
1263
var date = new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay, 12);
1264
selectLocalTimeZone(tp_inst, date);
1265
tp_inst._onTimeChange();
1272
* third bad hack :/ override datepicker so it allows spaces and colon in the input field
1274
$.datepicker._base_doKeyPress = $.datepicker._doKeyPress;
1275
$.datepicker._doKeyPress = function(event) {
1276
var inst = $.datepicker._getInst(event.target),
1277
tp_inst = $.datepicker._get(inst, 'timepicker');
1280
if ($.datepicker._get(inst, 'constrainInput')) {
1281
var ampm = useAmpm(tp_inst._defaults.timeFormat),
1282
dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),
1283
datetimeChars = tp_inst._defaults.timeFormat.toString()
1284
.replace(/[hms]/g, '')
1285
.replace(/TT/g, ampm ? 'APM' : '')
1286
.replace(/Tt/g, ampm ? 'AaPpMm' : '')
1287
.replace(/tT/g, ampm ? 'AaPpMm' : '')
1288
.replace(/T/g, ampm ? 'AP' : '')
1289
.replace(/tt/g, ampm ? 'apm' : '')
1290
.replace(/t/g, ampm ? 'ap' : '') +
1291
" " + tp_inst._defaults.separator +
1292
tp_inst._defaults.timeSuffix +
1293
(tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') +
1294
(tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +
1296
chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);
1297
return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);
1301
return $.datepicker._base_doKeyPress(event);
1305
* Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField
1307
$.datepicker._base_updateAlternate = $.datepicker._updateAlternate;
1308
/* Update any alternate field to synchronise with the main field. */
1309
$.datepicker._updateAlternate = function(inst) {
1310
var tp_inst = this._get(inst, 'timepicker');
1312
var altField = tp_inst._defaults.altField;
1313
if (altField) { // update alternate field too
1314
var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,
1315
date = this._getDate(inst),
1316
formatCfg = $.datepicker._getFormatConfig(inst),
1317
altFormattedDateTime = '',
1318
altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,
1319
altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,
1320
altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;
1322
altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;
1323
if(!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly){
1324
if(tp_inst._defaults.altFormat)
1325
altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, (date === null ? new Date() : date), formatCfg) + altSeparator + altFormattedDateTime;
1326
else altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;
1328
$(altField).val(altFormattedDateTime);
1332
$.datepicker._base_updateAlternate(inst);
1337
* Override key up event to sync manual input changes.
1339
$.datepicker._base_doKeyUp = $.datepicker._doKeyUp;
1340
$.datepicker._doKeyUp = function(event) {
1341
var inst = $.datepicker._getInst(event.target),
1342
tp_inst = $.datepicker._get(inst, 'timepicker');
1345
if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {
1347
$.datepicker._updateDatepicker(inst);
1349
$.datepicker.log(err);
1354
return $.datepicker._base_doKeyUp(event);
1358
* override "Today" button to also grab the time.
1360
$.datepicker._base_gotoToday = $.datepicker._gotoToday;
1361
$.datepicker._gotoToday = function(id) {
1362
var inst = this._getInst($(id)[0]),
1364
this._base_gotoToday(id);
1365
var tp_inst = this._get(inst, 'timepicker');
1366
selectLocalTimeZone(tp_inst);
1367
var now = new Date();
1368
this._setTime(inst, now);
1369
$('.ui-datepicker-today', $dp).click();
1373
* Disable & enable the Time in the datetimepicker
1375
$.datepicker._disableTimepickerDatepicker = function(target) {
1376
var inst = this._getInst(target);
1381
var tp_inst = this._get(inst, 'timepicker');
1382
$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
1384
tp_inst._defaults.showTimepicker = false;
1385
tp_inst._updateDateTime(inst);
1389
$.datepicker._enableTimepickerDatepicker = function(target) {
1390
var inst = this._getInst(target);
1395
var tp_inst = this._get(inst, 'timepicker');
1396
$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
1398
tp_inst._defaults.showTimepicker = true;
1399
tp_inst._addTimePicker(inst); // Could be disabled on page load
1400
tp_inst._updateDateTime(inst);
1405
* Create our own set time function
1407
$.datepicker._setTime = function(inst, date) {
1408
var tp_inst = this._get(inst, 'timepicker');
1410
var defaults = tp_inst._defaults;
1412
// calling _setTime with no date sets time to defaults
1413
tp_inst.hour = date ? date.getHours() : defaults.hour;
1414
tp_inst.minute = date ? date.getMinutes() : defaults.minute;
1415
tp_inst.second = date ? date.getSeconds() : defaults.second;
1416
tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;
1418
//check if within min/max times..
1419
tp_inst._limitMinMaxDateTime(inst, true);
1421
tp_inst._onTimeChange();
1422
tp_inst._updateDateTime(inst);
1427
* Create new public method to set only time, callable as $().datepicker('setTime', date)
1429
$.datepicker._setTimeDatepicker = function(target, date, withDate) {
1430
var inst = this._getInst(target);
1435
var tp_inst = this._get(inst, 'timepicker');
1438
this._setDateFromField(inst);
1441
if (typeof date == "string") {
1442
tp_inst._parseTime(date, withDate);
1443
tp_date = new Date();
1444
tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
1446
tp_date = new Date(date.getTime());
1448
if (tp_date.toString() == 'Invalid Date') {
1449
tp_date = undefined;
1451
this._setTime(inst, tp_date);
1458
* override setDate() to allow setting time too within Date object
1460
$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;
1461
$.datepicker._setDateDatepicker = function(target, date) {
1462
var inst = this._getInst(target);
1467
var tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;
1469
this._updateDatepicker(inst);
1470
this._base_setDateDatepicker.apply(this, arguments);
1471
this._setTimeDatepicker(target, tp_date, true);
1475
* override getDate() to allow getting time too within Date object
1477
$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;
1478
$.datepicker._getDateDatepicker = function(target, noDefault) {
1479
var inst = this._getInst(target);
1484
var tp_inst = this._get(inst, 'timepicker');
1487
// if it hasn't yet been defined, grab from field
1488
if(inst.lastVal === undefined){
1489
this._setDateFromField(inst, noDefault);
1492
var date = this._getDate(inst);
1493
if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) {
1494
date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
1498
return this._base_getDateDatepicker(target, noDefault);
1502
* override parseDate() because UI 1.8.14 throws an error about "Extra characters"
1503
* An option in datapicker to ignore extra format characters would be nicer.
1505
$.datepicker._base_parseDate = $.datepicker.parseDate;
1506
$.datepicker.parseDate = function(format, value, settings) {
1509
date = this._base_parseDate(format, value, settings);
1511
// Hack! The error message ends with a colon, a space, and
1512
// the "extra" characters. We rely on that instead of
1513
// attempting to perfectly reproduce the parsing algorithm.
1514
date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings);
1515
$.datepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format);
1521
* override formatDate to set date with time to the input
1523
$.datepicker._base_formatDate = $.datepicker._formatDate;
1524
$.datepicker._formatDate = function(inst, day, month, year) {
1525
var tp_inst = this._get(inst, 'timepicker');
1527
tp_inst._updateDateTime(inst);
1528
return tp_inst.$input.val();
1530
return this._base_formatDate(inst);
1534
* override options setter to add time to maxDate(Time) and minDate(Time). MaxDate
1536
$.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;
1537
$.datepicker._optionDatepicker = function(target, name, value) {
1538
var inst = this._getInst(target),
1544
var tp_inst = this._get(inst, 'timepicker');
1549
overrides = tp_inst._defaults.evnts,
1552
if (typeof name == 'string') { // if min/max was set with the string
1553
if (name === 'minDate' || name === 'minDateTime') {
1555
} else if (name === 'maxDate' || name === 'maxDateTime') {
1557
} else if (name === 'onSelect') {
1559
} else if (overrides.hasOwnProperty(name)) {
1560
if (typeof (value) === 'undefined') {
1561
return overrides[name];
1564
name_clone = {}; //empty results in exiting function after overrides updated
1566
} else if (typeof name == 'object') { //if min/max was set with the JSON
1569
} else if (name.minDateTime) {
1570
min = name.minDateTime;
1571
} else if (name.maxDate) {
1573
} else if (name.maxDateTime) {
1574
max = name.maxDateTime;
1576
for (prop in overrides) {
1577
if (overrides.hasOwnProperty(prop) && name[prop]) {
1578
fns[prop] = name[prop];
1583
if (fns.hasOwnProperty(prop)) {
1584
overrides[prop] = fns[prop];
1585
if (!name_clone) { name_clone = $.extend({}, name);}
1586
delete name_clone[prop];
1589
if (name_clone && isEmptyObject(name_clone)) { return; }
1590
if (min) { //if min was set
1594
min = new Date(min);
1596
tp_inst._defaults.minDate = min;
1597
tp_inst._defaults.minDateTime = min;
1598
} else if (max) { //if max was set
1602
max = new Date(max);
1604
tp_inst._defaults.maxDate = max;
1605
tp_inst._defaults.maxDateTime = max;
1606
} else if (onselect) {
1607
tp_inst._defaults.onSelect = onselect;
1610
if (value === undefined) {
1611
return this._base_optionDatepicker.call($.datepicker, target, name);
1613
return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);
1616
* jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,
1617
* it will return false for all objects
1619
var isEmptyObject = function(obj) {
1622
if (obj.hasOwnProperty(obj)) {
1630
* jQuery extend now ignores nulls!
1632
var extendRemove = function(target, props) {
1633
$.extend(target, props);
1634
for (var name in props) {
1635
if (props[name] === null || props[name] === undefined) {
1636
target[name] = props[name];
1643
* Determine by the time format if should use ampm
1644
* Returns true if should use ampm, false if not
1646
var useAmpm = function(timeFormat){
1647
return (timeFormat.indexOf('t') !== -1 && timeFormat.indexOf('h') !== -1);
1651
* Converts 24 hour format into 12 hour
1652
* Returns 12 hour without leading 0
1654
var convert24to12 = function(hour) {
1663
return String(hour);
1667
* Splits datetime string into date ans time substrings.
1668
* Throws exception when date can't be parsed
1669
* Returns [dateString, timeString]
1671
var splitDateTime = function(dateFormat, dateTimeString, dateSettings, timeSettings) {
1673
// The idea is to get the number separator occurances in datetime and the time format requested (since time has
1674
// fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.
1675
var separator = timeSettings && timeSettings.separator ? timeSettings.separator : $.timepicker._defaults.separator,
1676
format = timeSettings && timeSettings.timeFormat ? timeSettings.timeFormat : $.timepicker._defaults.timeFormat,
1677
timeParts = format.split(separator), // how many occurances of separator may be in our format?
1678
timePartsLen = timeParts.length,
1679
allParts = dateTimeString.split(separator),
1680
allPartsLen = allParts.length;
1682
if (allPartsLen > 1) {
1684
allParts.splice(0,allPartsLen-timePartsLen).join(separator),
1685
allParts.splice(0,timePartsLen).join(separator)
1690
$.datepicker.log('Could not split the date from the time. Please check the following datetimepicker options' +
1691
"\nthrown error: " + err +
1692
"\ndateTimeString" + dateTimeString +
1693
"\ndateFormat = " + dateFormat +
1694
"\nseparator = " + timeSettings.separator +
1695
"\ntimeFormat = " + timeSettings.timeFormat);
1697
if (err.indexOf(":") >= 0) {
1698
// Hack! The error message ends with a colon, a space, and
1699
// the "extra" characters. We rely on that instead of
1700
// attempting to perfectly reproduce the parsing algorithm.
1701
var dateStringLength = dateTimeString.length - (err.length - err.indexOf(':') - 2),
1702
timeString = dateTimeString.substring(dateStringLength);
1704
return [$.trim(dateTimeString.substring(0, dateStringLength)), $.trim(dateTimeString.substring(dateStringLength))];
1710
return [dateTimeString, ''];
1714
* Internal function to parse datetime interval
1715
* Returns: {date: Date, timeObj: Object}, where
1716
* date - parsed date without time (type Date)
1717
* timeObj = {hour: , minute: , second: , millisec: } - parsed time. Optional
1719
var parseDateTimeInternal = function(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {
1721
var splitRes = splitDateTime(dateFormat, dateTimeString, dateSettings, timeSettings);
1722
date = $.datepicker._base_parseDate(dateFormat, splitRes[0], dateSettings);
1723
if (splitRes[1] !== '') {
1724
var timeString = splitRes[1],
1725
parsedTime = $.datepicker.parseTime(timeFormat, timeString, timeSettings);
1727
if (parsedTime === null) {
1728
throw 'Wrong time format';
1742
* Internal function to set timezone_select to the local timezone
1744
var selectLocalTimeZone = function(tp_inst, date) {
1745
if (tp_inst && tp_inst.timezone_select) {
1746
tp_inst._defaults.useLocalTimezone = true;
1747
var now = typeof date !== 'undefined' ? date : new Date();
1748
var tzoffset = $.timepicker.timeZoneOffsetString(now);
1749
if (tp_inst._defaults.timezoneIso8601) {
1750
tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3);
1752
tp_inst.timezone_select.val(tzoffset);
1757
* Create a Singleton Insance
1759
$.timepicker = new Timepicker();
1762
* Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)
1766
$.timepicker.timeZoneOffsetString = function(date) {
1767
var off = date.getTimezoneOffset() * -1,
1769
hours = (off - minutes) / 60;
1770
return (off >= 0 ? '+' : '-') + ('0' + (hours * 101).toString()).substr(-2) + ('0' + (minutes * 101).toString()).substr(-2);
1774
* Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to
1775
* enforce date range limits.
1776
* n.b. The input value must be correctly formatted (reformatting is not supported)
1777
* @param Element startTime
1778
* @param Element endTime
1779
* @param obj options Options for the timepicker() call
1782
$.timepicker.timeRange = function(startTime, endTime, options) {
1783
return $.timepicker.handleRange('timepicker', startTime, endTime, options);
1787
* Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to
1788
* enforce date range limits.
1789
* @param Element startTime
1790
* @param Element endTime
1791
* @param obj options Options for the `timepicker()` call. Also supports `reformat`,
1792
* a boolean value that can be used to reformat the input values to the `dateFormat`.
1793
* @param string method Can be used to specify the type of picker to be added
1796
$.timepicker.dateTimeRange = function(startTime, endTime, options) {
1797
$.timepicker.dateRange(startTime, endTime, options, 'datetimepicker');
1801
* Calls `method` on the `startTime` and `endTime` elements, and configures them to
1802
* enforce date range limits.
1803
* @param Element startTime
1804
* @param Element endTime
1805
* @param obj options Options for the `timepicker()` call. Also supports `reformat`,
1806
* a boolean value that can be used to reformat the input values to the `dateFormat`.
1807
* @param string method Can be used to specify the type of picker to be added
1810
$.timepicker.dateRange = function(startTime, endTime, options, method) {
1811
method = method || 'datepicker';
1812
$.timepicker.handleRange(method, startTime, endTime, options);
1816
* Calls `method` on the `startTime` and `endTime` elements, and configures them to
1817
* enforce date range limits.
1818
* @param string method Can be used to specify the type of picker to be added
1819
* @param Element startTime
1820
* @param Element endTime
1821
* @param obj options Options for the `timepicker()` call. Also supports `reformat`,
1822
* a boolean value that can be used to reformat the input values to the `dateFormat`.
1825
$.timepicker.handleRange = function(method, startTime, endTime, options) {
1826
$.fn[method].call(startTime, $.extend({
1827
onClose: function(dateText, inst) {
1828
checkDates(this, endTime, dateText);
1830
onSelect: function(selectedDateTime) {
1831
selected(this, endTime, 'minDate');
1833
}, options, options.start));
1834
$.fn[method].call(endTime, $.extend({
1835
onClose: function(dateText, inst) {
1836
checkDates(this, startTime, dateText);
1838
onSelect: function(selectedDateTime) {
1839
selected(this, startTime, 'maxDate');
1841
}, options, options.end));
1842
// timepicker doesn't provide access to its 'timeFormat' option,
1843
// nor could I get datepicker.formatTime() to behave with times, so I
1844
// have disabled reformatting for timepicker
1845
if (method != 'timepicker' && options.reformat) {
1846
$([startTime, endTime]).each(function() {
1847
var format = $(this)[method].call($(this), 'option', 'dateFormat'),
1848
date = new Date($(this).val());
1849
if ($(this).val() && date) {
1850
$(this).val($.datepicker.formatDate(format, date));
1854
checkDates(startTime, endTime, startTime.val());
1856
function checkDates(changed, other, dateText) {
1857
if (other.val() && (new Date(startTime.val()) > new Date(endTime.val()))) {
1858
other.val(dateText);
1861
selected(startTime, endTime, 'minDate');
1862
selected(endTime, startTime, 'maxDate');
1864
function selected(changed, other, option) {
1865
if (!$(changed).val()) {
1868
var date = $(changed)[method].call($(changed), 'getDate');
1869
// timepicker doesn't implement 'getDate' and returns a jQuery
1871
$(other)[method].call($(other), 'option', option, date);
1874
return $([startTime.get(0), endTime.get(0)]);
1878
* Keep up with the version
1880
$.timepicker.version = "1.1.1";
b'\\ No newline at end of file'