[SPIP] +spip v3.0.17
[lhc/web/clavette_www.git] / www / prive / formulaires / dateur / jquery.time_picker.js
1 /*
2 * Copyright (c) 2006 Sam Collett (http://www.texotela.co.uk)
3 * Licensed under the MIT License:
4 * http://www.opensource.org/licenses/mit-license.php
5 */
6
7 /*
8 * A time picker for jQuery
9 * Based on original timePicker by Sam Collet (http://www.texotela.co.uk)
10 * @name timePicker
11 * @version 0.1
12 * @author Anders Fajerson (http://perifer.se)
13 * @example $("#mytime").timePicker();
14 * @example $("#mytime").timePicker({step:30, startTime:"15:00", endTime:"18:00"});
15 */
16 ;if (window.jQuery)
17 (function($){
18
19 $.fn.timePicker = function(options) {
20 // Build main options before element iteration
21 var settings = $.extend({}, $.fn.timePicker.defaults, options);
22
23 return this.each(function() {
24 $.timePicker(this, settings);
25 });
26 };
27
28 $.timePicker = function (elm, settings) {
29 var elm = $(elm)[0];
30 return elm.timePicker || (elm.timePicker = new jQuery._timePicker(elm, settings));
31 };
32
33 $._timePicker = function(elm, settings) {
34
35 var tpOver = false;
36 var startTime = normaliseTime(settings.startTime);
37 var endTime = normaliseTime(settings.endTime);
38
39 $(elm).attr('autocomplete', 'OFF'); // Disable browser autocomplete
40
41 var times = [];
42 var time = new Date(startTime); // Create a new date object.
43 while(time <= endTime) {
44 times[times.length] = formatTime(time, settings);
45 time = new Date(time.setMinutes(time.getMinutes() + settings.step));
46 }
47
48 var $tpDiv = $('<div class="time-picker'+ (settings.show24Hours ? '' : ' time-picker-12hours') +'"></div>');
49 var $tpList = $('<ul></ul>');
50
51 // Build the list.
52 for(var i = 0; i < times.length; i++) {
53 $tpList.append("<li>" + times[i] + "</li>");
54 }
55 $tpDiv.append($tpList);
56 // Store element offset.
57 var elmOffset = $(elm).offset();
58 // Append the timPicker to the body and position it.
59 $tpDiv.appendTo('body').css({'top':elmOffset.top, 'left':elmOffset.left}).hide();
60
61 $("li", $tpList).unbind().mouseover(function() {
62 $("li.selected", $tpDiv).removeClass("selected"); // TODO: only needs to run once.
63 $(this).addClass("selected");
64 }).mousedown(function() {
65 tpOver = true;
66 }).click(function() {
67 setTimeVal(elm, this, $tpDiv, settings);
68 tpOver = false;
69 });
70
71 // Store ananymous function in variable since it's used twice.
72 var showPicker = function() {
73 var elmOffset = $(elm).offset();
74 $tpDiv.css({'top':elmOffset.top, 'left':elmOffset.left}).show(); // Show picker.
75 $tpDiv.mouseover(function() { // Have to use mouseover instead of mousedown because of Opera
76 tpOver = true;
77 }).mouseout(function() {
78 tpOver = false;
79 });
80 $("li", $tpDiv).removeClass("selected");
81
82 // Try to find a time in the list that matches the entered time.
83 var time = this.value ? timeStringToDate(this.value, settings) : startTime;
84 var startMin = startTime.getHours() * 60 + startTime.getMinutes();
85 var min = (time.getHours() * 60 + time.getMinutes()) - startMin;
86 var steps = Math.round(min / settings.step);
87 var roundTime = normaliseTime(new Date(2001, 0, 0, 0, (steps * settings.step + (startMin)), 0));
88 roundTime = (startTime < roundTime && roundTime < endTime) ? roundTime : startTime;
89
90 var $matchedTime = $("li:contains(" + formatTime(roundTime, settings) + ")", $tpDiv);
91
92 if ($matchedTime.length) {
93 $matchedTime.addClass("selected");
94 // Scroll to matched time.
95 $tpDiv[0].scrollTop = $matchedTime[0].offsetTop;
96 }
97 };
98
99 $(elm).unbind().focus(showPicker).click(showPicker)
100 // Hide timepicker on blur
101 .blur(function() {
102 if (!tpOver && $tpDiv[0].parentNode) { // Don't remove when timePicker is clicked or when already removed
103 $tpDiv.hide();
104 }
105 })
106
107 // Key support
108 .keypress(function(e) {
109 switch (e.keyCode) {
110 case 38: // Up arrow.
111 case 63232: // Safari up arrow.
112 var $selected = $("li.selected", $tpList);
113 var prev = $selected.prev().addClass("selected")[0];
114 if (prev) {
115 $selected.removeClass("selected");
116 $tpDiv[0].scrollTop = prev.offsetTop;
117 }
118 return false;
119 break;
120 case 40: // Down arrow.
121 case 63233: // Safari down arrow.
122 var $selected = $("li.selected", $tpList);
123 var next = $selected.length ? $selected.next().addClass("selected")[0] : $("li:first").addClass("selected")[0];
124 if (next) {
125 $selected.removeClass("selected");
126 $tpDiv[0].scrollTop = next.offsetTop;
127 }
128 return false;
129 break;
130 case 13: // Enter
131 if (!$tpDiv.is(":hidden")) {
132 var sel = $("li.selected", $tpList)[0];
133 setTimeVal(elm, sel, $tpDiv, settings);
134 return false;
135 }
136 break;
137 }
138 });
139
140 // Helper function to get an inputs current time as Date object.
141 // Returns a Date object.
142 this.getTime = function() {
143 return timeStringToDate(elm.value, settings);
144 };
145 // Helper function to set a time input.
146 // Takes a Date object.
147 this.setTime = function(time) {
148 elm.value = formatTime(normaliseTime(time), settings);
149 // Trigger element's change events.
150 $(elm).change();
151 };
152
153 }; // End fn;
154
155 // Plugin defaults.
156 $.fn.timePicker.defaults = {
157 step:30,
158 startTime: new Date(0, 0, 0, 0, 0, 0),
159 endTime: new Date(0, 0, 0, 23, 30, 0),
160 separator: ':',
161 show24Hours: true
162 };
163
164 // Private functions.
165
166 function setTimeVal(elm, sel, $tpDiv, settings) {
167 // Update input field
168 elm.value = $(sel).text();
169 // Trigger element's change events.
170 $(elm).change();
171 // Keep focus for all but IE (which doesn't like it)
172 if (!$.browser.msie) {
173 elm.focus();
174 }
175 // Hide picker
176 $tpDiv.hide();
177 }
178
179 function formatTime(time, settings) {
180 var h = time.getHours();
181 var hours = settings.show24Hours ? h : (((h + 11) % 12) + 1);
182 var minutes = time.getMinutes();
183 return formatNumber(hours) + settings.separator + formatNumber(minutes) + (settings.show24Hours ? '' : ((h < 12) ? ' AM' : ' PM'));
184 }
185
186 function formatNumber(value) {
187 return (value < 10 ? '0' : '') + value;
188 }
189
190 function timeStringToDate(input, settings) {
191 if (input) {
192 var array = input.split(settings.separator);
193 var hours = parseFloat(array[0]);
194 var minutes = parseFloat(array[1]);
195 var time = new Date(0, 0, 0, hours, minutes, 0);
196 return normaliseTime(time);
197 }
198 return null;
199 }
200
201 /* Normalise time object to a common date. */
202 function normaliseTime(time) {
203 time.setFullYear(2001);
204 time.setMonth(0);
205 time.setDate(0);
206 return time;
207 }
208
209 })(jQuery);