diff --git a/jquery-ui-timepicker-addon.css b/jquery-ui-timepicker-addon.css
new file mode 100644
index 0000000..19b889f
--- /dev/null
+++ b/jquery-ui-timepicker-addon.css
@@ -0,0 +1,5 @@
+.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
+.ui-timepicker-div dl { text-align: left; }
+.ui-timepicker-div dl dt { height: 25px; }
+.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }
+.ui-timepicker-div td { font-size: 90%; }
diff --git a/jquery-ui-timepicker-addon.js b/jquery-ui-timepicker-addon.js
index 85c795c..c22a5ad 100644
--- a/jquery-ui-timepicker-addon.js
+++ b/jquery-ui-timepicker-addon.js
@@ -1,10 +1,10 @@
/*
* jQuery timepicker addon
* By: Trent Richardson [http://trentrichardson.com]
-* Version 0.9.3
-* Last Modified: 02/05/2011
+* Version 0.9.4
+* Last Modified: 05/12/2011
*
-* Copyright 2010 Trent Richardson
+* Copyright 2011 Trent Richardson
* Dual licensed under the MIT and GPL licenses.
* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
@@ -19,7 +19,7 @@
(function($) {
-$.extend($.ui, { timepicker: { version: "0.9.3" } });
+$.extend($.ui, { timepicker: { version: "0.9.4" } });
/* Time picker manager.
Use the singleton instance of this class, $.timepicker, to interact with the time picker.
@@ -37,7 +37,8 @@ function Timepicker() {
timeText: 'Time',
hourText: 'Hour',
minuteText: 'Minute',
- secondText: 'Second'
+ secondText: 'Second',
+ timezoneText: 'Time Zone'
};
this._defaults = { // Global defaults for all the datetime picker instances
showButtonPanel: true,
@@ -45,6 +46,7 @@ function Timepicker() {
showHour: true,
showMinute: true,
showSecond: false,
+ showTimezone: false,
showTime: true,
stepHour: 0.05,
stepMinute: 0.05,
@@ -52,6 +54,7 @@ function Timepicker() {
hour: 0,
minute: 0,
second: 0,
+ timezone: '+0000',
hourMin: 0,
minuteMin: 0,
secondMin: 0,
@@ -59,14 +62,18 @@ function Timepicker() {
minuteMax: 59,
secondMax: 59,
minDateTime: null,
- maxDateTime: null,
+ maxDateTime: null,
hourGrid: 0,
minuteGrid: 0,
secondGrid: 0,
alwaysSetTime: true,
separator: ' ',
altFieldTimeOnly: true,
- showTimepicker: true
+ showTimepicker: true,
+ timezoneList: ["-1100", "-1000", "-0900", "-0800", "-0700", "-0600",
+ "-0500", "-0400", "-0300", "-0200", "-0100", "+0000",
+ "+0100", "+0200", "+0300", "+0400", "+0500", "+0600",
+ "+0700", "+0800", "+0900", "+1000", "+1100", "+1200"]
};
$.extend(this._defaults, this.regional['']);
}
@@ -79,9 +86,11 @@ $.extend(Timepicker.prototype, {
hour_slider: null,
minute_slider: null,
second_slider: null,
+ timezone_select: null,
hour: 0,
minute: 0,
second: 0,
+ timezone: '+0000',
hourMinOriginal: null,
minuteMinOriginal: null,
secondMinOriginal: null,
@@ -92,6 +101,10 @@ $.extend(Timepicker.prototype, {
formattedDate: '',
formattedTime: '',
formattedDateTime: '',
+ timezoneList: ["-1100", "-1000", "-0900", "-0800", "-0700", "-0600",
+ "-0500", "-0400", "-0300", "-0200", "-0100", "+0000",
+ "+0100", "+0200", "+0300", "+0400", "+0500", "+0600",
+ "+0700", "+0800", "+0900", "+1000", "+1100", "+1200"],
/* Override the default settings for all instances of the time picker.
@param settings object - the new settings to use as defaults (anonymous object)
@@ -107,14 +120,7 @@ $.extend(Timepicker.prototype, {
_newInst: function($input, o) {
var tp_inst = new Timepicker(),
inlineSettings = {};
-
- tp_inst.hour = tp_inst._defaults.hour;
- tp_inst.minute = tp_inst._defaults.minute;
- tp_inst.second = tp_inst._defaults.second;
- tp_inst.ampm = '';
- tp_inst.$input = $input;
-
for (var attrName in this._defaults) {
var attrValue = $input.attr('time:' + attrName);
if (attrValue) {
@@ -126,7 +132,7 @@ $.extend(Timepicker.prototype, {
}
}
tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, {
- beforeShow: function(input, dp_inst) {
+ beforeShow: function(input, dp_inst) {
if ($.isFunction(o.beforeShow))
o.beforeShow(input, dp_inst, tp_inst);
},
@@ -134,17 +140,23 @@ $.extend(Timepicker.prototype, {
// Update the time as well : this prevents the time from disappearing from the $input field.
tp_inst._updateDateTime(dp_inst);
if ($.isFunction(o.onChangeMonthYear))
- o.onChangeMonthYear(year, month, dp_inst, tp_inst);
+ o.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(o.onClose))
- o.onClose(dateText, dp_inst, tp_inst);
+ o.onClose.call($input[0], dateText, dp_inst, tp_inst);
},
timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
});
+ tp_inst.hour = tp_inst._defaults.hour;
+ tp_inst.minute = tp_inst._defaults.minute;
+ tp_inst.second = tp_inst._defaults.second;
+ tp_inst.ampm = '';
+ tp_inst.$input = $input;
+
if (o.altField)
tp_inst.$altInput = $(o.altField)
.css({ cursor: 'pointer' })
@@ -185,6 +197,7 @@ $.extend(Timepicker.prototype, {
.replace(/m{1,2}/ig, '(\\d?\\d)')
.replace(/s{1,2}/ig, '(\\d?\\d)')
.replace(/t{1,2}/ig, '(am|pm|a|p)?')
+ .replace(/z{1}/ig, '((\\+|-)\\d\\d\\d\\d)?')
.replace(/\s/g, '\\s?') + '$',
order = this._getFormatPositions(),
treg;
@@ -195,9 +208,11 @@ $.extend(Timepicker.prototype, {
// the time should come after x number of characters and a space.
// x = at least the length of text specified by the date format
var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
- regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator + regstr;
+ // escape special regex characters in the seperator
+ var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g");
+ regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr;
}
-
+
treg = timeString.match(new RegExp(regstr, 'i'));
if (treg) {
@@ -216,6 +231,7 @@ $.extend(Timepicker.prototype, {
if (order.m !== -1) this.minute = Number(treg[order.m]);
if (order.s !== -1) this.second = Number(treg[order.s]);
+ if (order.z !== -1) this.timezone = treg[order.z];
return true;
@@ -227,8 +243,8 @@ $.extend(Timepicker.prototype, {
// figure out position of time elements.. cause js cant do named captures
//########################################################################
_getFormatPositions: function() {
- var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|t{1,2})/g),
- orders = { h: -1, m: -1, s: -1, t: -1 };
+ var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|t{1,2}|z)/g),
+ orders = { h: -1, m: -1, s: -1, t: -1, z: -1 };
if (finds)
for (var i = 0; i < finds.length; i++)
@@ -328,6 +344,11 @@ $.extend(Timepicker.prototype, {
'';
} else html += '
';
+
+ html += '' + o.timezoneText + '';
+ html += '';
html += '';
$tp = $(html);
@@ -379,6 +400,20 @@ $.extend(Timepicker.prototype, {
tp_inst._onTimeChange();
}
});
+
+
+ this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('').find("select");
+ $.fn.append.apply(this.timezone_select,
+ $.map(o.timezoneList, function(val, idx) {
+ return $("")
+ .val(typeof val == "object" ? val.value : val)
+ .text(typeof val == "object" ? val.label : val);
+ })
+ );
+ this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone);
+ this.timezone_select.change(function() {
+ tp_inst._onTimeChange();
+ });
// Add grid functionality
if (o.showHour && o.hourGrid > 0) {
@@ -402,6 +437,7 @@ $.extend(Timepicker.prototype, {
}
tp_inst.hour_slider.slider("option", "value", h);
tp_inst._onTimeChange();
+ tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / hourGridSize) + '%',
@@ -421,6 +457,7 @@ $.extend(Timepicker.prototype, {
$(this).click(function() {
tp_inst.minute_slider.slider("option", "value", $(this).html());
tp_inst._onTimeChange();
+ tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / minuteGridSize) + '%',
@@ -439,6 +476,7 @@ $.extend(Timepicker.prototype, {
$(this).click(function() {
tp_inst.second_slider.slider("option", "value", $(this).html());
tp_inst._onTimeChange();
+ tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / secondGridSize) + '%',
@@ -452,7 +490,7 @@ $.extend(Timepicker.prototype, {
if ($buttonPanel.length) $buttonPanel.before($tp);
else $dp.append($tp);
- this.$timeObj = $('#ui_tpicker_time_'+ dp_id);
+ this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id);
if (this.inst !== null) {
var timeDefined = this.timeDefined;
@@ -461,16 +499,12 @@ $.extend(Timepicker.prototype, {
}
//Emulate datepicker onSelect behavior. Call on slidestop.
- var onSelect = tp_inst._defaults['onSelect'];
- if (onSelect) {
- var inputEl = tp_inst.$input ? tp_inst.$input[0] : null;
- var onSelectHandler = function() {
- onSelect.apply(inputEl, [tp_inst.formattedDateTime, tp_inst]); // trigger custom callback*/
- }
- this.hour_slider.bind('slidestop',onSelectHandler);
- this.minute_slider.bind('slidestop',onSelectHandler);
- this.second_slider.bind('slidestop',onSelectHandler);
+ var onSelectDelegate = function() {
+ tp_inst._onSelectHandler();
}
+ this.hour_slider.bind('slidestop',onSelectDelegate);
+ this.minute_slider.bind('slidestop',onSelectDelegate);
+ this.second_slider.bind('slidestop',onSelectDelegate);
}
},
@@ -480,27 +514,36 @@ $.extend(Timepicker.prototype, {
//########################################################################
_limitMinMaxDateTime: function(dp_inst, adjustSliders){
var o = this._defaults,
- dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay),
- tp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay, this.hour, this.minute, this.second, 0);
-
+ dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);
+
+ if(!this._defaults.showTimepicker) return; // No time so nothing to check here
+
if(this._defaults.minDateTime !== null && dp_date){
var minDateTime = this._defaults.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.hourMinOriginal = o.hourMin;
this.minuteMinOriginal = o.minuteMin;
this.secondMinOriginal = o.secondMin;
}
-
- if(minDateTimeDate.getTime() == dp_date.getTime()){
- this._defaults.hourMin = minDateTime.getHours();
- this._defaults.minuteMin = minDateTime.getMinutes();
- this._defaults.secondMin = minDateTime.getSeconds();
- if(this.hour < this._defaults.hourMin) this.hour = this._defaults.hourMin;
- if(this.minute < this._defaults.minuteMin) this.minute = this._defaults.minuteMin;
- if(this.second < this._defaults.secondMin) this.second = this._defaults.secondMin;
+ 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();
+ } else {
+ if(this.second < this._defaults.secondMin) this.second = this._defaults.secondMin;
+ this._defaults.secondMin = this.secondMinOriginal;
+ }
+ } else {
+ this._defaults.minuteMin = this.minuteMinOriginal;
+ this._defaults.secondMin = this.secondMinOriginal;
+ }
}else{
this._defaults.hourMin = this.hourMinOriginal;
this._defaults.minuteMin = this.minuteMinOriginal;
@@ -517,22 +560,30 @@ $.extend(Timepicker.prototype, {
this.minuteMaxOriginal = o.minuteMax;
this.secondMaxOriginal = o.secondMax;
}
-
- if(maxDateTimeDate.getTime() == dp_date.getTime()){
+
+ if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){
this._defaults.hourMax = maxDateTime.getHours();
- this._defaults.minuteMax = maxDateTime.getMinutes();
- this._defaults.secondMax = maxDateTime.getSeconds();
-
- if(this.hour > this._defaults.hourMax){ this.hour = this._defaults.hourMax; }
- if(this.minute > this._defaults.minuteMax) this.minute = this._defaults.minuteMax;
- if(this.second > this._defaults.secondMax) this.second = this._defaults.secondMax;
+ 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.secondMin = maxDateTime.getSeconds();
+ } else {
+ if(this.second > this._defaults.secondMax) this.second = this._defaults.secondMax;
+ this._defaults.secondMax = this.secondMaxOriginal;
+ }
+ } else {
+ this._defaults.minuteMax = this.minuteMaxOriginal;
+ this._defaults.secondMax = this.secondMaxOriginal;
+ }
}else{
this._defaults.hourMax = this.hourMaxOriginal;
this._defaults.minuteMax = this.minuteMaxOriginal;
this._defaults.secondMax = this.secondMaxOriginal;
}
}
-
+
if(adjustSliders !== undefined && adjustSliders === true){
this.hour_slider.slider("option", { min: this._defaults.hourMin, max: this._defaults.hourMax }).slider('value', this.hour);
this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: this._defaults.minuteMax }).slider('value', this.minute);
@@ -540,6 +591,7 @@ $.extend(Timepicker.prototype, {
}
},
+
//########################################################################
// when a slider moves, set the internal time...
@@ -548,8 +600,9 @@ $.extend(Timepicker.prototype, {
_onTimeChange: function() {
var hour = (this.hour_slider) ? this.hour_slider.slider('value') : false,
minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,
- second = (this.second_slider) ? this.second_slider.slider('value') : false;
-
+ second = (this.second_slider) ? this.second_slider.slider('value') : false,
+ timezone = (this.timezone_select) ? this.timezone_select.val() : false
+
if (hour !== false) hour = parseInt(hour,10);
if (minute !== false) minute = parseInt(minute,10);
if (second !== false) second = parseInt(second,10);
@@ -558,13 +611,15 @@ $.extend(Timepicker.prototype, {
// If the update was done in the input field, the input field should not be updated.
// If the update was done using the sliders, update the input field.
- var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || (this.ampm.length > 0 && this.ampm != ampm));
+ var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || (this.ampm.length > 0 && this.ampm != ampm) || timezone != this.timezone);
if (hasChanged) {
if (hour !== false)this.hour = hour;
if (minute !== false) this.minute = minute;
if (second !== false) this.second = second;
+ if (timezone !== false) this.timezone = timezone;
+ this._limitMinMaxDateTime(this.inst, true);
}
if (this._defaults.ampm) this.ampm = ampm;
@@ -573,13 +628,25 @@ $.extend(Timepicker.prototype, {
this.timeDefined = true;
if (hasChanged) this._updateDateTime();
},
+
+ //########################################################################
+ // call custom onSelect.
+ // bind to sliders slidestop, and grid click.
+ //########################################################################
+ _onSelectHandler: function() {
+ var onSelect = this._defaults['onSelect'];
+ var inputEl = this.$input ? this.$input[0] : null;
+ if (onSelect && inputEl) {
+ onSelect.apply(inputEl, [this.formattedDateTime, this]);
+ }
+ },
//########################################################################
// format the time all pretty...
//########################################################################
_formatTime: function(time, format, ampm) {
if (ampm == undefined) ampm = this._defaults.ampm;
- time = time || { hour: this.hour, minute: this.minute, second: this.second, ampm: this.ampm };
+ time = time || { hour: this.hour, minute: this.minute, second: this.second, ampm: this.ampm, timezone: this.timezone };
var tmptime = format || this._defaults.timeFormat.toString();
if (ampm) {
@@ -595,7 +662,8 @@ $.extend(Timepicker.prototype, {
.replace(/TT/g, time.ampm.toUpperCase())
.replace(/tt/g, time.ampm.toLowerCase())
.replace(/T/g, time.ampm.charAt(0).toUpperCase())
- .replace(/t/g, time.ampm.charAt(0).toLowerCase());
+ .replace(/t/g, time.ampm.charAt(0).toLowerCase())
+ .replace(/z/g, time.timezone);
} else {
tmptime = tmptime.toString()
.replace(/hh/g, ((time.hour < 10) ? '0' : '') + time.hour)
@@ -603,7 +671,8 @@ $.extend(Timepicker.prototype, {
.replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)
.replace(/m/g, time.minute)
.replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)
- .replace(/s/g, time.second);
+ .replace(/s/g, time.second)
+ .replace(/z/g, time.timezone);
tmptime = $.trim(tmptime.replace(/t/gi, ''));
}
@@ -627,7 +696,7 @@ $.extend(Timepicker.prototype, {
if (this._defaults.timeOnly === true) {
formattedDateTime = this.formattedTime;
- } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {
+ } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {
formattedDateTime += this._defaults.separator + this.formattedTime;
}
@@ -671,7 +740,7 @@ $.fn.extend({
datetimepicker: function(o) {
o = o || {};
var $input = this,
- tmp_args = arguments;
+ tmp_args = arguments;
if (typeof(o) == 'string'){
if(o == 'getDate')
@@ -792,9 +861,9 @@ $.datepicker._gotoToday = function(id) {
$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
+ $(target).datepicker('getDate'); // Init selected[Year|Month|Day]
if (tp_inst) {
tp_inst._defaults.showTimepicker = false;
- tp_inst._onTimeChange();
tp_inst._updateDateTime(inst);
}
};
@@ -802,9 +871,10 @@ $.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {
$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
+ $(target).datepicker('getDate'); // Init selected[Year|Month|Day]
if (tp_inst) {
tp_inst._defaults.showTimepicker = true;
- tp_inst._onTimeChange();
+ tp_inst._addTimePicker(inst); // Could be disabled on page load
tp_inst._updateDateTime(inst);
}
};
@@ -858,8 +928,8 @@ $.datepicker._setTimeDatepicker = function(target, date, withDate) {
}
else tp_date = new Date(date.getTime());
if (tp_date.toString() == 'Invalid Date') tp_date = undefined;
+ this._setTime(inst, tp_date);
}
- this._setTime(inst, tp_date);
}
};
@@ -906,6 +976,6 @@ function extendRemove(target, props) {
}
$.timepicker = new Timepicker(); // singleton instance
-$.timepicker.version = "0.9.3";
+$.timepicker.version = "0.9.4";
})(jQuery);