web_interface/astpp/assets/js/ui/ui-timepicker-addon.js   F
last analyzed

Complexity

Total Complexity 353
Complexity/F 5.79

Size

Lines of Code 1305
Function Count 61

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
nc 0
dl 0
loc 1305
rs 2.4
c 0
b 0
f 0
wmc 353
mnd 7
bc 155
fnc 61
bpm 2.5409
cpm 5.7868
noi 23

31 Functions

Rating   Name   Duplication   Size   Complexity  
B $.datepicker._updateDatepicker 0 20 8
C $.extend._updateDateTime 0 33 13
A $.datepicker._enableTimepickerDatepicker 0 10 2
A $.datepicker._formatDate 0 11 3
A $.extend._getPatternAmpm 0 10 3
A $.datepicker._selectDate 0 15 2
F $.extend._limitMinMaxDateTime 0 102 33
D $.datepicker._setTime 0 32 18
A ui-timepicker-addon.js ➔ extendRemove 0 7 4
A $.datepicker._getDateDatepicker 0 12 4
A $.datepicker._disableTimepickerDatepicker 0 9 2
A $.fn.extend.timepicker 0 10 2
F $.extend._parseTime 0 77 30
B $.datepicker._doKeyUp 0 17 5
A $.extend._onSelectHandler 0 7 4
B $.datepicker._setTimeDatepicker 0 20 5
A ui-timepicker-addon.js ➔ Timepicker 0 62 1
A $.extend._addTimePicker 0 9 3
C $.datepicker._doKeyPress 0 30 11
A $.fn.extend.datetimepicker 0 20 3
F $.extend._injectTimePicker 0 326 51
D $.datepicker._optionDatepicker 0 45 19
F $.extend._onTimeChange 0 49 26
A $.datepicker._setDateDatepicker 0 8 2
A $.extend._formatTime 0 9 2
B $.datepicker.formatTime 0 41 5
A $.datepicker.parseDate 0 17 3
A $.extend.setDefaults 0 4 1
A $.extend._getFormatPositions 0 11 4
F $.extend._newInst 0 79 21
B $.datepicker._gotoToday 0 19 6

How to fix   Complexity   

Complexity

Complex classes like web_interface/astpp/assets/js/ui/ui-timepicker-addon.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*
2
* jQuery timepicker addon
3
* By: Trent Richardson [http://trentrichardson.com]
4
* Version 0.9.9
5
* Last Modified: 02/05/2012
6
* 
7
* Copyright 2012 Trent Richardson
8
* Dual licensed under the MIT and GPL licenses.
9
* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
10
* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
11
* 
12
* HERES THE CSS:
13
* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
14
* .ui-timepicker-div dl { text-align: left; }
15
* .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
16
* .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }
17
* .ui-timepicker-div td { font-size: 90%; }
18
* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
19
*/
20
21
(function($) {
22
23
$.extend($.ui, { timepicker: { version: "0.9.9" } });
24
25
/* Time picker manager.
26
   Use the singleton instance of this class, $.timepicker, to interact with the time picker.
27
   Settings for (groups of) time pickers are maintained in an instance object,
28
   allowing multiple different settings on the same page. */
29
30
function Timepicker() {
31
	this.regional = []; // Available regional settings, indexed by language code
32
	this.regional[''] = { // Default regional settings
33
		currentText: 'Now',
34
		closeText: 'Done',
35
		ampm: false,
36
		amNames: ['AM', 'A'],
37
		pmNames: ['PM', 'P'],
38
		timeFormat: 'hh:mm tt',
39
		timeSuffix: '',
40
		timeOnlyTitle: 'Choose Time',
41
		timeText: 'Time',
42
		hourText: 'Hour',
43
		minuteText: 'Minute',
44
		secondText: 'Second',
45
		millisecText: 'Millisecond',
46
		timezoneText: 'Time Zone'
47
	};
48
	this._defaults = { // Global defaults for all the datetime picker instances
49
		showButtonPanel: true,
50
		timeOnly: false,
51
		showHour: true,
52
		showMinute: true,
53
		showSecond: false,
54
		showMillisec: false,
55
		showTimezone: false,
56
		showTime: true,
57
		stepHour: 1,
58
		stepMinute: 1,
59
		stepSecond: 1,
60
		stepMillisec: 1,
61
		hour: 0,
62
		minute: 0,
63
		second: 0,
64
		millisec: 0,
65
		timezone: '+0000',
66
		hourMin: 0,
67
		minuteMin: 0,
68
		secondMin: 0,
69
		millisecMin: 0,
70
		hourMax: 23,
71
		minuteMax: 59,
72
		secondMax: 59,
73
		millisecMax: 999,
74
		minDateTime: null,
75
		maxDateTime: null,
76
		onSelect: null,
77
		hourGrid: 0,
78
		minuteGrid: 0,
79
		secondGrid: 0,
80
		millisecGrid: 0,
81
		alwaysSetTime: true,
82
		separator: ' ',
83
		altFieldTimeOnly: true,
84
		showTimepicker: true,
85
		timezoneIso8609: false,
86
		timezoneList: null,
87
		addSliderAccess: false,
88
		sliderAccessArgs: null
89
	};
90
	$.extend(this._defaults, this.regional['']);
91
};
92
93
$.extend(Timepicker.prototype, {
94
	$input: null,
95
	$altInput: null,
96
	$timeObj: null,
97
	inst: null,
98
	hour_slider: null,
99
	minute_slider: null,
100
	second_slider: null,
101
	millisec_slider: null,
102
	timezone_select: null,
103
	hour: 0,
104
	minute: 0,
105
	second: 0,
106
	millisec: 0,
107
	timezone: '+0000',
108
	hourMinOriginal: null,
109
	minuteMinOriginal: null,
110
	secondMinOriginal: null,
111
	millisecMinOriginal: null,
112
	hourMaxOriginal: null,
113
	minuteMaxOriginal: null,
114
	secondMaxOriginal: null,
115
	millisecMaxOriginal: null,
116
	ampm: '',
117
	formattedDate: '',
118
	formattedTime: '',
119
	formattedDateTime: '',
120
	timezoneList: null,
121
122
	/* Override the default settings for all instances of the time picker.
123
	   @param  settings  object - the new settings to use as defaults (anonymous object)
124
	   @return the manager object */
125
	setDefaults: function(settings) {
126
		extendRemove(this._defaults, settings || {});
127
		return this;
128
	},
129
130
	//########################################################################
131
	// Create a new Timepicker instance
132
	//########################################################################
133
	_newInst: function($input, o) {
134
		var tp_inst = new Timepicker(),
135
			inlineSettings = {};
136
			
137
		for (var attrName in this._defaults) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
138
			var attrValue = $input.attr('time:' + attrName);
139
			if (attrValue) {
140
				try {
141
					inlineSettings[attrName] = eval(attrValue);
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
142
				} catch (err) {
143
					inlineSettings[attrName] = attrValue;
144
				}
145
			}
146
		}
147
		tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, {
148
			beforeShow: function(input, dp_inst) {
149
				if ($.isFunction(o.beforeShow))
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $.isFunction(o.beforeShow) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
150
					return o.beforeShow(input, dp_inst, tp_inst);
151
			},
152
			onChangeMonthYear: function(year, month, dp_inst) {
153
				// Update the time as well : this prevents the time from disappearing from the $input field.
154
				tp_inst._updateDateTime(dp_inst);
155
				if ($.isFunction(o.onChangeMonthYear))
156
					o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);
157
			},
158
			onClose: function(dateText, dp_inst) {
159
				if (tp_inst.timeDefined === true && $input.val() != '')
160
					tp_inst._updateDateTime(dp_inst);
161
				if ($.isFunction(o.onClose))
162
					o.onClose.call($input[0], dateText, dp_inst, tp_inst);
163
			},
164
			timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
165
		});
166
		tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() });
167
		tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() });
168
169
		if (tp_inst._defaults.timezoneList === null) {
170
			var timezoneList = [];
171
			for (var i = -11; i <= 12; i++)
172
				timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00');
173
			if (tp_inst._defaults.timezoneIso8609)
174
				timezoneList = $.map(timezoneList, function(val) {
175
					return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3));
176
				});
177
			tp_inst._defaults.timezoneList = timezoneList;
178
		}
179
180
		tp_inst.hour = tp_inst._defaults.hour;
181
		tp_inst.minute = tp_inst._defaults.minute;
182
		tp_inst.second = tp_inst._defaults.second;
183
		tp_inst.millisec = tp_inst._defaults.millisec;
184
		tp_inst.ampm = '';
185
		tp_inst.$input = $input;
186
187
		if (o.altField)
188
			tp_inst.$altInput = $(o.altField)
189
				.css({ cursor: 'pointer' })
190
				.focus(function(){ $input.trigger("focus"); });
191
		
192
		if(tp_inst._defaults.minDate==0 || tp_inst._defaults.minDateTime==0)
193
		{
194
			tp_inst._defaults.minDate=new Date();
195
		}
196
		if(tp_inst._defaults.maxDate==0 || tp_inst._defaults.maxDateTime==0)
197
		{
198
			tp_inst._defaults.maxDate=new Date();
199
		}
200
		
201
		// datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..
202
		if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date)
203
			tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());
204
		if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date)
205
			tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());
206
		if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date)
207
			tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());
208
		if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date)
209
			tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());
210
		return tp_inst;
211
	},
212
213
	//########################################################################
214
	// add our sliders to the calendar
215
	//########################################################################
216
	_addTimePicker: function(dp_inst) {
217
		var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ?
218
				this.$input.val() + ' ' + this.$altInput.val() : 
219
				this.$input.val();
220
221
		this.timeDefined = this._parseTime(currDT);
222
		this._limitMinMaxDateTime(dp_inst, false);
223
		this._injectTimePicker();
224
	},
225
226
	//########################################################################
227
	// parse the time string from input value or _setTime
228
	//########################################################################
229
	_parseTime: function(timeString, withDate) {
230
		var regstr = this._defaults.timeFormat.toString()
231
				.replace(/h{1,2}/ig, '(\\d?\\d)')
232
				.replace(/m{1,2}/ig, '(\\d?\\d)')
233
				.replace(/s{1,2}/ig, '(\\d?\\d)')
234
				.replace(/l{1}/ig, '(\\d?\\d?\\d)')
235
				.replace(/t{1,2}/ig, this._getPatternAmpm())
236
				.replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?')
237
				.replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$',
238
			order = this._getFormatPositions(),
239
			ampm = '',
240
			treg;
241
242
		if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
243
244
		if (withDate || !this._defaults.timeOnly) {
245
			// the time should come after x number of characters and a space.
246
			// x = at least the length of text specified by the date format
247
			var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
248
			// escape special regex characters in the seperator
249
			var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g");
250
			regstr = '^.{' + dp_dateFormat.length + ',}?' + this._defaults.separator.replace(specials, "\\$&") + regstr;
251
		}
252
		
253
		treg = timeString.match(new RegExp(regstr, 'i'));
254
255
		if (treg) {
256
			if (order.t !== -1) {
257
				if (treg[order.t] === undefined || treg[order.t].length === 0) {
258
					ampm = '';
259
					this.ampm = '';
260
				} else {
261
					ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM';
262
					this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0];
263
				}
264
			}
265
266
			if (order.h !== -1) {
267
				if (ampm == 'AM' && treg[order.h] == '12')
268
					this.hour = 0; // 12am = 0 hour
269
				else if (ampm == 'PM' && treg[order.h] != '12')
270
					this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12
271
				else this.hour = Number(treg[order.h]);
272
			}
273
274
			if (order.m !== -1) this.minute = Number(treg[order.m]);
275
			if (order.s !== -1) this.second = Number(treg[order.s]);
276
			if (order.l !== -1) this.millisec = Number(treg[order.l]);
277
			if (order.z !== -1 && treg[order.z] !== undefined) {
278
				var tz = treg[order.z].toUpperCase();
279
				switch (tz.length) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
280
				case 1:	// Z
281
					tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000';
282
					break;
283
				case 5:	// +hhmm
284
					if (this._defaults.timezoneIso8609)
285
						tz = tz.substring(1) == '0000'
286
						   ? 'Z'
287
						   : tz.substring(0, 3) + ':' + tz.substring(3);
288
					break;
289
				case 6:	// +hh:mm
290
					if (!this._defaults.timezoneIso8609)
291
						tz = tz == 'Z' || tz.substring(1) == '00:00'
292
						   ? '+0000'
293
						   : tz.replace(/:/, '');
294
					else if (tz.substring(1) == '00:00')
295
						tz = 'Z';
296
					break;
297
				}
298
				this.timezone = tz;
299
			}
300
			
301
			return true;
302
303
		}
304
		return false;
305
	},
306
307
	//########################################################################
308
	// pattern for standard and localized AM/PM markers
309
	//########################################################################
310
	_getPatternAmpm: function() {
311
		var markers = [];
312
			o = this._defaults;
0 ignored issues
show
Bug introduced by
The variable o seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.o.
Loading history...
313
		if (o.amNames)
314
			$.merge(markers, o.amNames);
315
		if (o.pmNames)
316
			$.merge(markers, o.pmNames);
317
		markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') });
318
		return '(' + markers.join('|') + ')?';
319
	},
320
321
	//########################################################################
322
	// figure out position of time elements.. cause js cant do named captures
323
	//########################################################################
324
	_getFormatPositions: function() {
325
		var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z)/g),
326
			orders = { h: -1, m: -1, s: -1, l: -1, t: -1, z: -1 };
327
328
		if (finds)
329
			for (var i = 0; i < finds.length; i++)
330
				if (orders[finds[i].toString().charAt(0)] == -1)
331
					orders[finds[i].toString().charAt(0)] = i + 1;
332
333
		return orders;
334
	},
335
336
	//########################################################################
337
	// generate and inject html for timepicker into ui datepicker
338
	//########################################################################
339
	_injectTimePicker: function() {
340
		var $dp = this.inst.dpDiv,
341
			o = this._defaults,
342
			tp_inst = this,
343
			// Added by Peter Medeiros:
344
			// - Figure out what the hour/minute/second max should be based on the step values.
345
			// - Example: if stepMinute is 15, then minMax is 45.
346
			hourMax = parseInt((o.hourMax - ((o.hourMax - o.hourMin) % o.stepHour)) ,10),
347
			minMax  = parseInt((o.minuteMax - ((o.minuteMax - o.minuteMin) % o.stepMinute)) ,10),
348
			secMax  = parseInt((o.secondMax - ((o.secondMax - o.secondMin) % o.stepSecond)) ,10),
349
			millisecMax  = parseInt((o.millisecMax - ((o.millisecMax - o.millisecMin) % o.stepMillisec)) ,10),
350
			dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, '');
351
352
		// Prevent displaying twice
353
		//if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) {
354
		if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) {
355
			var noDisplay = ' style="display:none;"',
356
				html =	'<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' +
357
						'<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' +
358
						((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +
359
						'<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' +
360
						((o.showTime) ? '' : noDisplay) + '></dd>' +
361
						'<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' +
362
						((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>',
363
				hourGridSize = 0,
364
				minuteGridSize = 0,
365
				secondGridSize = 0,
366
				millisecGridSize = 0,
367
				size;
368
369
 			// Hours
370
			html += '<dd class="ui_tpicker_hour"><div id="ui_tpicker_hour_' + dp_id + '"' +
371
						((o.showHour) ? '' : noDisplay) + '></div>';
372
			if (o.showHour && o.hourGrid > 0) {
373
				html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';
374
375
				for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) {
376
					hourGridSize++;
377
					var tmph = (o.ampm && h > 12) ? h-12 : h;
378
					if (tmph < 10) tmph = '0' + tmph;
379
					if (o.ampm) {
380
						if (h == 0) tmph = 12 +'a';
381
						else if (h < 12) tmph += 'a';
382
						else tmph += 'p';
383
					}
384
					html += '<td>' + tmph + '</td>';
385
				}
386
387
				html += '</tr></table></div>';
388
			}
389
			html += '</dd>';
390
391
			// Minutes
392
			html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' +
393
					((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>'+
394
					'<dd class="ui_tpicker_minute"><div id="ui_tpicker_minute_' + dp_id + '"' +
395
							((o.showMinute) ? '' : noDisplay) + '></div>';
396
397
			if (o.showMinute && o.minuteGrid > 0) {
398
				html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';
399
400
				for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) {
401
					minuteGridSize++;
402
					html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>';
403
				}
404
405
				html += '</tr></table></div>';
406
			}
407
			html += '</dd>';
408
409
			// Seconds
410
			html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' +
411
					((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>'+
412
					'<dd class="ui_tpicker_second"><div id="ui_tpicker_second_' + dp_id + '"'+
413
							((o.showSecond) ? '' : noDisplay) + '></div>';
414
415
			if (o.showSecond && o.secondGrid > 0) {
416
				html += '<div style="padding-left: 1px"><table><tr>';
417
418
				for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) {
419
					secondGridSize++;
420
					html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>';
421
				}
422
423
				html += '</tr></table></div>';
424
			}
425
			html += '</dd>';
426
427
			// Milliseconds
428
			html += '<dt class="ui_tpicker_millisec_label" id="ui_tpicker_millisec_label_' + dp_id + '"' +
429
					((o.showMillisec) ? '' : noDisplay) + '>' + o.millisecText + '</dt>'+
430
					'<dd class="ui_tpicker_millisec"><div id="ui_tpicker_millisec_' + dp_id + '"'+
431
							((o.showMillisec) ? '' : noDisplay) + '></div>';
432
433
			if (o.showMillisec && o.millisecGrid > 0) {
434
				html += '<div style="padding-left: 1px"><table><tr>';
435
436
				for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) {
437
					millisecGridSize++;
438
					html += '<td>' + ((l < 10) ? '0' : '') + l + '</td>';
439
				}
440
441
				html += '</tr></table></div>';
442
			}
443
			html += '</dd>';
444
445
			// Timezone
446
			html += '<dt class="ui_tpicker_timezone_label" id="ui_tpicker_timezone_label_' + dp_id + '"' +
447
					((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>';
448
			html += '<dd class="ui_tpicker_timezone" id="ui_tpicker_timezone_' + dp_id + '"'	+
449
							((o.showTimezone) ? '' : noDisplay) + '></dd>';
450
451
			html += '</dl></div>';
452
			$tp = $(html);
0 ignored issues
show
Bug introduced by
The variable $tp seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.$tp.
Loading history...
453
454
				// if we only want time picker...
455
			if (o.timeOnly === true) {
456
				$tp.prepend(
457
					'<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' +
458
						'<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' +
459
					'</div>');
460
				$dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();
461
			}
462
463
			this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({
464
				orientation: "horizontal",
465
				value: this.hour,
466
				min: o.hourMin,
467
				max: hourMax,
468
				step: o.stepHour,
469
				slide: function(event, ui) {
470
					tp_inst.hour_slider.slider( "option", "value", ui.value);
471
					tp_inst._onTimeChange();
472
				}
473
			});
474
475
			
476
			// Updated by Peter Medeiros:
477
			// - Pass in Event and UI instance into slide function
478
			this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({
479
				orientation: "horizontal",
480
				value: this.minute,
481
				min: o.minuteMin,
482
				max: minMax,
483
				step: o.stepMinute,
484
				slide: function(event, ui) {
485
					tp_inst.minute_slider.slider( "option", "value", ui.value);
486
					tp_inst._onTimeChange();
487
				}
488
			});
489
490
			this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({
491
				orientation: "horizontal",
492
				value: this.second,
493
				min: o.secondMin,
494
				max: secMax,
495
				step: o.stepSecond,
496
				slide: function(event, ui) {
497
					tp_inst.second_slider.slider( "option", "value", ui.value);
498
					tp_inst._onTimeChange();
499
				}
500
			});
501
502
			this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({
503
				orientation: "horizontal",
504
				value: this.millisec,
505
				min: o.millisecMin,
506
				max: millisecMax,
507
				step: o.stepMillisec,
508
				slide: function(event, ui) {
509
					tp_inst.millisec_slider.slider( "option", "value", ui.value);
510
					tp_inst._onTimeChange();
511
				}
512
			});
513
514
			this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('<select></select>').find("select");
515
			$.fn.append.apply(this.timezone_select,
516
				$.map(o.timezoneList, function(val, idx) {
0 ignored issues
show
Unused Code introduced by
The parameter idx is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
517
					return $("<option />")
518
						.val(typeof val == "object" ? val.value : val)
519
						.text(typeof val == "object" ? val.label : val);
520
				})
521
			);
522
			this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone);
523
			this.timezone_select.change(function() {
524
				tp_inst._onTimeChange();
525
			});
526
527
			// Add grid functionality
528
			if (o.showHour && o.hourGrid > 0) {
529
				size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin);
530
531
				$tp.find(".ui_tpicker_hour table").css({
532
					width: size + "%",
533
					marginLeft: (size / (-2 * hourGridSize)) + "%",
534
					borderCollapse: 'collapse'
535
				}).find("td").each( function(index) {
0 ignored issues
show
Unused Code introduced by
The parameter index is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
536
					$(this).click(function() {
537
						var h = $(this).html();
538
						if(o.ampm)	{
539
							var ap = h.substring(2).toLowerCase(),
540
								aph = parseInt(h.substring(0,2), 10);
541
							if (ap == 'a') {
542
								if (aph == 12) h = 0;
543
								else h = aph;
544
							} else if (aph == 12) h = 12;
545
							else h = aph + 12;
546
						}
547
						tp_inst.hour_slider.slider("option", "value", h);
548
						tp_inst._onTimeChange();
549
						tp_inst._onSelectHandler();
550
					}).css({
551
						cursor: 'pointer',
552
						width: (100 / hourGridSize) + '%',
553
						textAlign: 'center',
554
						overflow: 'hidden'
555
					});
556
				});
557
			}
558
559
			if (o.showMinute && o.minuteGrid > 0) {
560
				size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin);
561
				$tp.find(".ui_tpicker_minute table").css({
562
					width: size + "%",
563
					marginLeft: (size / (-2 * minuteGridSize)) + "%",
564
					borderCollapse: 'collapse'
565
				}).find("td").each(function(index) {
0 ignored issues
show
Unused Code introduced by
The parameter index is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
566
					$(this).click(function() {
567
						tp_inst.minute_slider.slider("option", "value", $(this).html());
568
						tp_inst._onTimeChange();
569
						tp_inst._onSelectHandler();
570
					}).css({
571
						cursor: 'pointer',
572
						width: (100 / minuteGridSize) + '%',
573
						textAlign: 'center',
574
						overflow: 'hidden'
575
					});
576
				});
577
			}
578
579
			if (o.showSecond && o.secondGrid > 0) {
580
				$tp.find(".ui_tpicker_second table").css({
581
					width: size + "%",
0 ignored issues
show
Bug introduced by
The variable size does not seem to be initialized in case o.showHour && o.hourGrid > 0 on line 528 is false. Are you sure this can never be the case?
Loading history...
582
					marginLeft: (size / (-2 * secondGridSize)) + "%",
583
					borderCollapse: 'collapse'
584
				}).find("td").each(function(index) {
0 ignored issues
show
Unused Code introduced by
The parameter index is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
585
					$(this).click(function() {
586
						tp_inst.second_slider.slider("option", "value", $(this).html());
587
						tp_inst._onTimeChange();
588
						tp_inst._onSelectHandler();
589
					}).css({
590
						cursor: 'pointer',
591
						width: (100 / secondGridSize) + '%',
592
						textAlign: 'center',
593
						overflow: 'hidden'
594
					});
595
				});
596
			}
597
598
			if (o.showMillisec && o.millisecGrid > 0) {
599
				$tp.find(".ui_tpicker_millisec table").css({
600
					width: size + "%",
0 ignored issues
show
Bug introduced by
The variable size does not seem to be initialized in case o.showHour && o.hourGrid > 0 on line 528 is false. Are you sure this can never be the case?
Loading history...
601
					marginLeft: (size / (-2 * millisecGridSize)) + "%",
602
					borderCollapse: 'collapse'
603
				}).find("td").each(function(index) {
0 ignored issues
show
Unused Code introduced by
The parameter index is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
604
					$(this).click(function() {
605
						tp_inst.millisec_slider.slider("option", "value", $(this).html());
606
						tp_inst._onTimeChange();
607
						tp_inst._onSelectHandler();
608
					}).css({
609
						cursor: 'pointer',
610
						width: (100 / millisecGridSize) + '%',
611
						textAlign: 'center',
612
						overflow: 'hidden'
613
					});
614
				});
615
			}
616
617
			var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');
618
			if ($buttonPanel.length) $buttonPanel.before($tp);
619
			else $dp.append($tp);
620
621
			this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id);
622
623
			if (this.inst !== null) {
624
				var timeDefined = this.timeDefined;
625
				this._onTimeChange();
626
				this.timeDefined = timeDefined;
627
			}
628
629
			//Emulate datepicker onSelect behavior. Call on slidestop.
630
			var onSelectDelegate = function() {
631
				tp_inst._onSelectHandler();
632
			};
633
			this.hour_slider.bind('slidestop',onSelectDelegate);
634
			this.minute_slider.bind('slidestop',onSelectDelegate);
635
			this.second_slider.bind('slidestop',onSelectDelegate);
636
			this.millisec_slider.bind('slidestop',onSelectDelegate);
637
			
638
			// slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/
639
			if (this._defaults.addSliderAccess){
640
				var sliderAccessArgs = this._defaults.sliderAccessArgs;
641
				setTimeout(function(){ // fix for inline mode
642
					if($tp.find('.ui-slider-access').length == 0){
643
						$tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);
644
645
						// fix any grids since sliders are shorter
646
						var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);
647
						if(sliderAccessWidth){
648
							$tp.find('table:visible').each(function(){
649
								var $g = $(this),
650
									oldWidth = $g.outerWidth(),
651
									oldMarginLeft = $g.css('marginLeft').toString().replace('%',''),
652
									newWidth = oldWidth - sliderAccessWidth,
653
									newMarginLeft = ((oldMarginLeft * newWidth)/oldWidth) + '%';
654
						
655
								$g.css({ width: newWidth, marginLeft: newMarginLeft });
656
							});
657
						}
658
					}
659
				},0);
660
			}
661
			// end slideAccess integration
662
			
663
		}
664
	},
665
666
	//########################################################################
667
	// This function tries to limit the ability to go outside the
668
	// min/max date range
669
	//########################################################################
670
	_limitMinMaxDateTime: function(dp_inst, adjustSliders){
671
		var o = this._defaults,
672
			dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);
673
674
		if(!this._defaults.showTimepicker) return; // No time so nothing to check here
675
676
		if($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date){
677
			var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),
678
				minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);
679
680
			if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null){
681
				this.hourMinOriginal = o.hourMin;
682
				this.minuteMinOriginal = o.minuteMin;
683
				this.secondMinOriginal = o.secondMin;
684
				this.millisecMinOriginal = o.millisecMin;
685
			}
686
687
			if(dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) {
688
				this._defaults.hourMin = minDateTime.getHours();
689
				if (this.hour <= this._defaults.hourMin) {
690
					this.hour = this._defaults.hourMin;
691
					this._defaults.minuteMin = minDateTime.getMinutes();
692
					if (this.minute <= this._defaults.minuteMin) {
693
						this.minute = this._defaults.minuteMin;
694
						this._defaults.secondMin = minDateTime.getSeconds();
695
					} else if (this.second <= this._defaults.secondMin){
696
						this.second = this._defaults.secondMin;
697
						this._defaults.millisecMin = minDateTime.getMilliseconds();
698
					} else {
699
						if(this.millisec < this._defaults.millisecMin)
700
							this.millisec = this._defaults.millisecMin;
701
						this._defaults.millisecMin = this.millisecMinOriginal;
702
					}
703
				} else {
704
					this._defaults.minuteMin = this.minuteMinOriginal;
705
					this._defaults.secondMin = this.secondMinOriginal;
706
					this._defaults.millisecMin = this.millisecMinOriginal;
707
				}
708
			}else{
709
				this._defaults.hourMin = this.hourMinOriginal;
710
				this._defaults.minuteMin = this.minuteMinOriginal;
711
				this._defaults.secondMin = this.secondMinOriginal;
712
				this._defaults.millisecMin = this.millisecMinOriginal;
713
			}
714
		}
715
716
		if($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date){
717
			var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),
718
				maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);
719
720
			if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){
721
				this.hourMaxOriginal = o.hourMax;
722
				this.minuteMaxOriginal = o.minuteMax;
723
				this.secondMaxOriginal = o.secondMax;
724
				this.millisecMaxOriginal = o.millisecMax;
725
			}
726
727
			if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){
728
				this._defaults.hourMax = maxDateTime.getHours();
729
				if (this.hour >= this._defaults.hourMax) {
730
					this.hour = this._defaults.hourMax;
731
					this._defaults.minuteMax = maxDateTime.getMinutes();
732
					if (this.minute >= this._defaults.minuteMax) {
733
						this.minute = this._defaults.minuteMax;
734
						this._defaults.secondMax = maxDateTime.getSeconds();
735
					} else if (this.second >= this._defaults.secondMax) {
736
						this.second = this._defaults.secondMax;
737
						this._defaults.millisecMax = maxDateTime.getMilliseconds();
738
					} else {
739
						if(this.millisec > this._defaults.millisecMax) this.millisec = this._defaults.millisecMax;
740
						this._defaults.millisecMax = this.millisecMaxOriginal;
741
					}
742
				} else {
743
					this._defaults.minuteMax = this.minuteMaxOriginal;
744
					this._defaults.secondMax = this.secondMaxOriginal;
745
					this._defaults.millisecMax = this.millisecMaxOriginal;
746
				}
747
			}else{
748
				this._defaults.hourMax = this.hourMaxOriginal;
749
				this._defaults.minuteMax = this.minuteMaxOriginal;
750
				this._defaults.secondMax = this.secondMaxOriginal;
751
				this._defaults.millisecMax = this.millisecMaxOriginal;
752
			}
753
		}
754
755
		if(adjustSliders !== undefined && adjustSliders === true){
756
			var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)) ,10),
757
                minMax  = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)) ,10),
758
                secMax  = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)) ,10),
759
				millisecMax  = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)) ,10);
760
761
			if(this.hour_slider)
762
				this.hour_slider.slider("option", { min: this._defaults.hourMin, max: hourMax }).slider('value', this.hour);
763
			if(this.minute_slider)
764
				this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: minMax }).slider('value', this.minute);
765
			if(this.second_slider)
766
				this.second_slider.slider("option", { min: this._defaults.secondMin, max: secMax }).slider('value', this.second);
767
			if(this.millisec_slider)
768
				this.millisec_slider.slider("option", { min: this._defaults.millisecMin, max: millisecMax }).slider('value', this.millisec);
769
		}
770
771
	},
772
773
	
774
	//########################################################################
775
	// when a slider moves, set the internal time...
776
	// on time change is also called when the time is updated in the text field
777
	//########################################################################
778
	_onTimeChange: function() {
779
		var hour   = (this.hour_slider) ? this.hour_slider.slider('value') : false,
780
			minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,
781
			second = (this.second_slider) ? this.second_slider.slider('value') : false,
782
			millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false,
783
			timezone = (this.timezone_select) ? this.timezone_select.val() : false,
784
			o = this._defaults;
785
786
		if (typeof(hour) == 'object') hour = false;
787
		if (typeof(minute) == 'object') minute = false;
788
		if (typeof(second) == 'object') second = false;
789
		if (typeof(millisec) == 'object') millisec = false;
790
		if (typeof(timezone) == 'object') timezone = false;
791
792
		if (hour !== false) hour = parseInt(hour,10);
793
		if (minute !== false) minute = parseInt(minute,10);
794
		if (second !== false) second = parseInt(second,10);
795
		if (millisec !== false) millisec = parseInt(millisec,10);
796
797
		var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];
798
799
		// If the update was done in the input field, the input field should not be updated.
800
		// If the update was done using the sliders, update the input field.
801
		var hasChanged = (hour != this.hour || minute != this.minute
802
				|| second != this.second || millisec != this.millisec
803
				|| (this.ampm.length > 0
804
				    && (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1))
805
				|| timezone != this.timezone);
806
		
807
		if (hasChanged) {
808
809
			if (hour !== false)this.hour = hour;
810
			if (minute !== false) this.minute = minute;
811
			if (second !== false) this.second = second;
812
			if (millisec !== false) this.millisec = millisec;
813
			if (timezone !== false) this.timezone = timezone;
814
			
815
			if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
816
			
817
			this._limitMinMaxDateTime(this.inst, true);
818
		}
819
		if (o.ampm) this.ampm = ampm;
820
		
821
		//this._formatTime();
822
		this.formattedTime = $.datepicker.formatTime(this._defaults.timeFormat, this, this._defaults);
823
		if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix);
824
		this.timeDefined = true;
825
		if (hasChanged) this._updateDateTime();
826
	},
827
    
828
	//########################################################################
829
	// call custom onSelect. 
830
	// bind to sliders slidestop, and grid click.
831
	//########################################################################
832
	_onSelectHandler: function() {
833
		var onSelect = this._defaults.onSelect;
834
		var inputEl = this.$input ? this.$input[0] : null;
835
		if (onSelect && inputEl) {
836
			onSelect.apply(inputEl, [this.formattedDateTime, this]);
837
		}
838
	},
839
840
	//########################################################################
841
	// left for any backwards compatibility
842
	//########################################################################
843
	_formatTime: function(time, format) {
844
		time = time || { hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone };
845
		var tmptime = (format || this._defaults.timeFormat).toString();
846
847
		tmptime = $.datepicker.formatTime(tmptime, time, this._defaults);
848
		
849
		if (arguments.length) return tmptime;
850
		else this.formattedTime = tmptime;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
851
	},
852
853
	//########################################################################
854
	// update our input with the new date time..
855
	//########################################################################
856
	_updateDateTime: function(dp_inst) {
857
		dp_inst = this.inst || dp_inst;
858
		var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),
859
			dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),
860
			formatCfg = $.datepicker._getFormatConfig(dp_inst),
861
			timeAvailable = dt !== null && this.timeDefined;
862
		this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);
863
		var formattedDateTime = this.formattedDate;
864
		if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0))
865
			return;
866
867
		if (this._defaults.timeOnly === true) {
868
			formattedDateTime = this.formattedTime;
869
		} else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {
870
			formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;
871
		}
872
873
		this.formattedDateTime = formattedDateTime;
874
875
		if(!this._defaults.showTimepicker) {
876
			this.$input.val(this.formattedDate);
877
		} else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {
878
			this.$altInput.val(this.formattedTime);
879
			this.$input.val(this.formattedDate);
880
		} else if(this.$altInput) {
881
			this.$altInput.val(formattedDateTime);
882
			this.$input.val(formattedDateTime);
883
		} else {
884
			this.$input.val(formattedDateTime);
885
		}
886
		
887
		this.$input.trigger("change");
888
	}
889
890
});
891
892
$.fn.extend({
893
	//########################################################################
894
	// shorthand just to use timepicker..
895
	//########################################################################
896
	timepicker: function(o) {
897
		o = o || {};
898
		var tmp_args = arguments;
899
900
		if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true });
901
902
		return $(this).each(function() {
903
			$.fn.datetimepicker.apply($(this), tmp_args);
904
		});
905
	},
906
907
	//########################################################################
908
	// extend timepicker to datepicker
909
	//########################################################################
910
	datetimepicker: function(o) {
911
		o = o || {};
912
		var $input = this,
0 ignored issues
show
Unused Code introduced by
The variable $input seems to be never used. Consider removing it.
Loading history...
913
		tmp_args = arguments;
914
915
		if (typeof(o) == 'string'){
916
			if(o == 'getDate') 
917
				return $.fn.datepicker.apply($(this[0]), tmp_args);
918
			else 
919
				return this.each(function() {
920
					var $t = $(this);
921
					$t.datepicker.apply($t, tmp_args);
922
				});
923
		}
924
		else
925
			return this.each(function() {
926
				var $t = $(this);
927
				$t.datepicker($.timepicker._newInst($t, o)._defaults);
928
			});
929
	}
930
});
931
932
//########################################################################
933
// format the time all pretty... 
934
// format = string format of the time
935
// time = a {}, not a Date() for timezones
936
// options = essentially the regional[].. amNames, pmNames, ampm
937
//########################################################################
938
$.datepicker.formatTime = function(format, time, options) {
939
	options = options || {};
940
	options = $.extend($.timepicker._defaults, options);
941
	time = $.extend({hour:0, minute:0, second:0, millisec:0, timezone:'+0000'}, time);
942
	
943
	var tmptime = format;
944
	var ampmName = options['amNames'][0];
945
946
	var hour = parseInt(time.hour, 10);
947
	if (options.ampm) {
948
		if (hour > 11){
949
			ampmName = options['pmNames'][0];
950
			if(hour > 12)
951
				hour = hour % 12;
952
		}
953
		if (hour === 0)
954
			hour = 12;
955
	}
956
	tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function(match) {
957
		switch (match.toLowerCase()) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
958
			case 'hh': return ('0' + hour).slice(-2);
959
			case 'h':  return hour;
960
			case 'mm': return ('0' + time.minute).slice(-2);
961
			case 'm':  return time.minute;
962
			case 'ss': return ('0' + time.second).slice(-2);
963
			case 's':  return time.second;
964
			case 'l':  return ('00' + time.millisec).slice(-3);
965
			case 'z':  return time.timezone;
966
			case 't': case 'tt':
967
				if (options.ampm) {
968
					if (match.length == 1)
969
						ampmName = ampmName.charAt(0);
970
					return match.charAt(0) == 'T' ? ampmName.toUpperCase() : ampmName.toLowerCase();
971
				}
972
				return '';
973
		}
0 ignored issues
show
Comprehensibility introduced by
There is no default case in this switch, so nothing gets returned when all cases fail. You might want to consider adding a default or return undefined explicitly.
Loading history...
974
	});
975
976
	tmptime = $.trim(tmptime);
977
	return tmptime;
978
}
979
980
//########################################################################
981
// the bad hack :/ override datepicker so it doesnt close on select
982
// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378
983
//########################################################################
984
$.datepicker._base_selectDate = $.datepicker._selectDate;
985
$.datepicker._selectDate = function (id, dateStr) {
986
	var inst = this._getInst($(id)[0]),
987
		tp_inst = this._get(inst, 'timepicker');
988
989
	if (tp_inst) {
990
		tp_inst._limitMinMaxDateTime(inst, true);
991
		inst.inline = inst.stay_open = true;
992
		//This way the onSelect handler called from calendarpicker get the full dateTime
993
		this._base_selectDate(id, dateStr);
994
		inst.inline = inst.stay_open = false;
995
		this._notifyChange(inst);
996
		this._updateDatepicker(inst);
997
	}
998
	else this._base_selectDate(id, dateStr);
999
};
1000
1001
//#############################################################################################
1002
// second bad hack :/ override datepicker so it triggers an event when changing the input field
1003
// and does not redraw the datepicker on every selectDate event
1004
//#############################################################################################
1005
$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;
1006
$.datepicker._updateDatepicker = function(inst) {
1007
1008
	// don't popup the datepicker if there is another instance already opened
1009
	var input = inst.input[0];
1010
	if($.datepicker._curInst &&
1011
	   $.datepicker._curInst != inst &&
1012
	   $.datepicker._datepickerShowing &&
1013
	   $.datepicker._lastInput != input) {
1014
		return;
1015
	}
1016
1017
	if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {
1018
				
1019
		this._base_updateDatepicker(inst);
1020
		
1021
		// Reload the time control when changing something in the input text field.
1022
		var tp_inst = this._get(inst, 'timepicker');
1023
		if(tp_inst) tp_inst._addTimePicker(inst);
1024
	}
1025
};
1026
1027
//#######################################################################################
1028
// third bad hack :/ override datepicker so it allows spaces and colon in the input field
1029
//#######################################################################################
1030
$.datepicker._base_doKeyPress = $.datepicker._doKeyPress;
1031
$.datepicker._doKeyPress = function(event) {
1032
	var inst = $.datepicker._getInst(event.target),
1033
		tp_inst = $.datepicker._get(inst, 'timepicker');
1034
1035
	if (tp_inst) {
1036
		if ($.datepicker._get(inst, 'constrainInput')) {
1037
			var ampm = tp_inst._defaults.ampm,
1038
				dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),
1039
				datetimeChars = tp_inst._defaults.timeFormat.toString()
1040
								.replace(/[hms]/g, '')
1041
								.replace(/TT/g, ampm ? 'APM' : '')
1042
								.replace(/Tt/g, ampm ? 'AaPpMm' : '')
1043
								.replace(/tT/g, ampm ? 'AaPpMm' : '')
1044
								.replace(/T/g, ampm ? 'AP' : '')
1045
								.replace(/tt/g, ampm ? 'apm' : '')
1046
								.replace(/t/g, ampm ? 'ap' : '') +
1047
								" " +
1048
								tp_inst._defaults.separator +
1049
								tp_inst._defaults.timeSuffix +
1050
								(tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') +
1051
								(tp_inst._defaults.amNames.join('')) +
1052
								(tp_inst._defaults.pmNames.join('')) +
1053
								dateChars,
1054
				chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);
1055
			return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);
1056
		}
1057
	}
1058
	
1059
	return $.datepicker._base_doKeyPress(event);
1060
};
1061
1062
//#######################################################################################
1063
// Override key up event to sync manual input changes.
1064
//#######################################################################################
1065
$.datepicker._base_doKeyUp = $.datepicker._doKeyUp;
1066
$.datepicker._doKeyUp = function (event) {
1067
	var inst = $.datepicker._getInst(event.target),
1068
		tp_inst = $.datepicker._get(inst, 'timepicker');
1069
1070
	if (tp_inst) {
1071
		if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {
1072
			try {
1073
				$.datepicker._updateDatepicker(inst);
1074
			}
1075
			catch (err) {
1076
				$.datepicker.log(err);
1077
			}
1078
		}
1079
	}
1080
1081
	return $.datepicker._base_doKeyUp(event);
1082
};
1083
1084
//#######################################################################################
1085
// override "Today" button to also grab the time.
1086
//#######################################################################################
1087
$.datepicker._base_gotoToday = $.datepicker._gotoToday;
1088
$.datepicker._gotoToday = function(id) {
1089
	var inst = this._getInst($(id)[0]),
1090
		$dp = inst.dpDiv;
1091
	this._base_gotoToday(id);
1092
	var now = new Date();
1093
	var tp_inst = this._get(inst, 'timepicker');
1094
	if (tp_inst && tp_inst._defaults.showTimezone && tp_inst.timezone_select) {
1095
		var tzoffset = now.getTimezoneOffset(); // If +0100, returns -60
1096
		var tzsign = tzoffset > 0 ? '-' : '+';
1097
		tzoffset = Math.abs(tzoffset);
1098
		var tzmin = tzoffset % 60;
1099
		tzoffset = tzsign + ('0' + (tzoffset - tzmin) / 60).slice(-2) + ('0' + tzmin).slice(-2);
1100
		if (tp_inst._defaults.timezoneIso8609)
1101
			tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3);
1102
		tp_inst.timezone_select.val(tzoffset);
1103
	}
1104
	this._setTime(inst, now);
1105
	$( '.ui-datepicker-today', $dp).click(); 
1106
};
1107
1108
//#######################################################################################
1109
// Disable & enable the Time in the datetimepicker
1110
//#######################################################################################
1111
$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {
0 ignored issues
show
Unused Code introduced by
The parameter date is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter withDate is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1112
	var inst = this._getInst(target),
1113
	tp_inst = this._get(inst, 'timepicker');
1114
	$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
1115
	if (tp_inst) {
1116
		tp_inst._defaults.showTimepicker = false;
1117
		tp_inst._updateDateTime(inst);
1118
	}
1119
};
1120
1121
$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {
0 ignored issues
show
Unused Code introduced by
The parameter withDate is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter date is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1122
	var inst = this._getInst(target),
1123
	tp_inst = this._get(inst, 'timepicker');
1124
	$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
1125
	if (tp_inst) {
1126
		tp_inst._defaults.showTimepicker = true;
1127
		tp_inst._addTimePicker(inst); // Could be disabled on page load
1128
		tp_inst._updateDateTime(inst);
1129
	}
1130
};
1131
1132
//#######################################################################################
1133
// Create our own set time function
1134
//#######################################################################################
1135
$.datepicker._setTime = function(inst, date) {
1136
	var tp_inst = this._get(inst, 'timepicker');
1137
	if (tp_inst) {
1138
		var defaults = tp_inst._defaults,
1139
			// calling _setTime with no date sets time to defaults
1140
			hour = date ? date.getHours() : defaults.hour,
1141
			minute = date ? date.getMinutes() : defaults.minute,
1142
			second = date ? date.getSeconds() : defaults.second,
1143
			millisec = date ? date.getMilliseconds() : defaults.millisec;
1144
1145
		//check if within min/max times..
1146
		if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax) || (millisec < defaults.millisecMin || millisec > defaults.millisecMax)) {
1147
			hour = defaults.hourMin;
1148
			minute = defaults.minuteMin;
1149
			second = defaults.secondMin;
1150
			millisec = defaults.millisecMin;
1151
		}
1152
1153
		tp_inst.hour = hour;
1154
		tp_inst.minute = minute;
1155
		tp_inst.second = second;
1156
		tp_inst.millisec = millisec;
1157
1158
		if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour);
1159
		if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute);
1160
		if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second);
1161
		if (tp_inst.millisec_slider) tp_inst.millisec_slider.slider('value', millisec);
1162
1163
		tp_inst._onTimeChange();
1164
		tp_inst._updateDateTime(inst);
1165
	}
1166
};
1167
1168
//#######################################################################################
1169
// Create new public method to set only time, callable as $().datepicker('setTime', date)
1170
//#######################################################################################
1171
$.datepicker._setTimeDatepicker = function(target, date, withDate) {
1172
	var inst = this._getInst(target),
1173
		tp_inst = this._get(inst, 'timepicker');
1174
1175
	if (tp_inst) {
1176
		this._setDateFromField(inst);
1177
		var tp_date;
1178
		if (date) {
1179
			if (typeof date == "string") {
1180
				tp_inst._parseTime(date, withDate);
1181
				tp_date = new Date();
1182
				tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
1183
			}
1184
			else tp_date = new Date(date.getTime());
1185
			if (tp_date.toString() == 'Invalid Date') tp_date = undefined;
1186
			this._setTime(inst, tp_date);
1187
		}
1188
	}
1189
1190
};
1191
1192
//#######################################################################################
1193
// override setDate() to allow setting time too within Date object
1194
//#######################################################################################
1195
$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;
1196
$.datepicker._setDateDatepicker = function(target, date) {
1197
	var inst = this._getInst(target),
1198
	tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;
1199
1200
	this._updateDatepicker(inst);
1201
	this._base_setDateDatepicker.apply(this, arguments);
1202
	this._setTimeDatepicker(target, tp_date, true);
1203
};
1204
1205
//#######################################################################################
1206
// override getDate() to allow getting time too within Date object
1207
//#######################################################################################
1208
$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;
1209
$.datepicker._getDateDatepicker = function(target, noDefault) {
1210
	var inst = this._getInst(target),
1211
		tp_inst = this._get(inst, 'timepicker');
1212
1213
	if (tp_inst) {
1214
		this._setDateFromField(inst, noDefault);
1215
		var date = this._getDate(inst);
1216
		if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
1217
		return date;
1218
	}
1219
	return this._base_getDateDatepicker(target, noDefault);
1220
};
1221
1222
//#######################################################################################
1223
// override parseDate() because UI 1.8.14 throws an error about "Extra characters"
1224
// An option in datapicker to ignore extra format characters would be nicer.
1225
//#######################################################################################
1226
$.datepicker._base_parseDate = $.datepicker.parseDate;
1227
$.datepicker.parseDate = function(format, value, settings) {
1228
	var date;
1229
	try {
1230
		date = this._base_parseDate(format, value, settings);
1231
	} catch (err) {
1232
		if (err.indexOf(":") >= 0) {
1233
			// Hack!  The error message ends with a colon, a space, and
1234
			// the "extra" characters.  We rely on that instead of
1235
			// attempting to perfectly reproduce the parsing algorithm.
1236
			date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings);
1237
		} else {
1238
			// The underlying error was not related to the time
1239
			throw err;
1240
		}
1241
	}
1242
	return date;
1243
};
1244
1245
//#######################################################################################
1246
// override formatDate to set date with time to the input
1247
//#######################################################################################
1248
$.datepicker._base_formatDate=$.datepicker._formatDate;
1249
$.datepicker._formatDate = function(inst, day, month, year){
1250
	var tp_inst = this._get(inst, 'timepicker');
1251
	if(tp_inst)
1252
	{
1253
		if(day)
1254
			var b = this._base_formatDate(inst, day, month, year);
0 ignored issues
show
Unused Code introduced by
The variable b seems to be never used. Consider removing it.
Loading history...
1255
		tp_inst._updateDateTime(inst);	
1256
		return tp_inst.$input.val();
1257
	}
1258
	return this._base_formatDate(inst);
1259
};
1260
1261
//#######################################################################################
1262
// override options setter to add time to maxDate(Time) and minDate(Time). MaxDate
1263
//#######################################################################################
1264
$.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;
1265
$.datepicker._optionDatepicker = function(target, name, value) {
1266
	var inst = this._getInst(target),
1267
		tp_inst = this._get(inst, 'timepicker');
1268
	if (tp_inst) {
1269
		var min,max,onselect;
1270
		if (typeof name == 'string') { // if min/max was set with the string
1271
			if (name==='minDate' || name==='minDateTime' )
1272
				min = value;
1273
			else if (name==='maxDate' || name==='maxDateTime')
1274
				max = value;
1275
			else if (name==='onSelect')
1276
				onselect=value;
1277
		} else if (typeof name == 'object') { //if min/max was set with the JSON
1278
			if(name.minDate)
1279
				min = name.minDate;
1280
			else if (name.minDateTime)
1281
				min = name.minDateTime;
1282
			else if (name.maxDate)
1283
				max = name.maxDate;
1284
			else if (name.maxDateTime)
1285
				max = name.maxDateTime;
1286
		}
1287
		if(min){ //if min was set
1288
			if(min==0)
1289
				min=new Date();
1290
			else
1291
				min= new Date(min);
1292
			
1293
			tp_inst._defaults.minDate = min;
1294
			tp_inst._defaults.minDateTime = min;
1295
		} else if (max){ //if max was set
1296
			if(max==0)
1297
				max=new Date();
1298
			else
1299
				max= new Date(max);
1300
			tp_inst._defaults.maxDate = max;
1301
			tp_inst._defaults.maxDateTime = max;
1302
		}
1303
		else if (onselect)
1304
			tp_inst._defaults.onSelect=onselect;
1305
	}
1306
	if (value === undefined)
1307
		return this._base_optionDatepicker(target, name);
1308
	return this._base_optionDatepicker(target, name, value);
1309
};
1310
1311
//#######################################################################################
1312
// jQuery extend now ignores nulls!
1313
//#######################################################################################
1314
function extendRemove(target, props) {
1315
	$.extend(target, props);
1316
	for (var name in props)
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
1317
		if (props[name] === null || props[name] === undefined)
1318
			target[name] = props[name];
1319
	return target;
1320
};
1321
1322
$.timepicker = new Timepicker(); // singleton instance
1323
$.timepicker.version = "0.9.9";
1324
1325
})(jQuery);
1326
1327