[PLUGINS] +les plugins de bases
[ptitvelo/web/www.git] / www / plugins / calendrier_mini-2.0 / javascript / jquery-ui.multidatespicker.js
1 /*
2 * MultiDatesPicker v1.6.1
3 * http://multidatespickr.sourceforge.net/
4 *
5 * Copyright 2011, Luca Lauretta
6 * Dual licensed under the MIT or GPL version 2 licenses.
7 */
8 (function( $ ){
9 $.extend($.ui, { multiDatesPicker: { version: "1.6.1" } });
10
11 $.fn.multiDatesPicker = function(method) {
12 var mdp_arguments = arguments;
13 var ret = this;
14 var today_date = new Date();
15 var day_zero = new Date(0);
16 var mdp_events = {};
17
18 function removeDate(date, type) {
19 if(!type) type = 'picked';
20 date = dateConvert.call(this, date);
21 for(var i in this.multiDatesPicker.dates[type])
22 if(!methods.compareDates(this.multiDatesPicker.dates[type][i], date))
23 return this.multiDatesPicker.dates[type].splice(i, 1).pop();
24 }
25 function removeIndex(index, type) {
26 if(!type) type = 'picked';
27 return this.multiDatesPicker.dates[type].splice(index, 1).pop();
28 }
29 function addDate(date, type, no_sort) {
30 if(!type) type = 'picked';
31 date = dateConvert.call(this, date);
32
33 // @todo: use jQuery UI datepicker method instead
34 date.setHours(0);
35 date.setMinutes(0);
36 date.setSeconds(0);
37 date.setMilliseconds(0);
38
39 if (methods.gotDate.call(this, date, type) === false) {
40 this.multiDatesPicker.dates[type].push(date);
41 if(!no_sort) this.multiDatesPicker.dates[type].sort(methods.compareDates);
42 }
43 }
44 function sortDates(type) {
45 if(!type) type = 'picked';
46 this.multiDatesPicker.dates[type].sort(methods.compareDates);
47 }
48 function dateConvert(date, desired_type, date_format) {
49 if(!desired_type) desired_type = 'object';/*
50 if(!date_format && (typeof date == 'string')) {
51 date_format = $(this).datepicker('option', 'dateFormat');
52 if(!date_format) date_format = $.datepicker._defaults.dateFormat;
53 }
54 */
55 return methods.dateConvert.call(this, date, desired_type, date_format);
56 }
57
58 var methods = {
59 init : function( options ) {
60 var $this = $(this);
61 this.multiDatesPicker.changed = false;
62
63 var mdp_events = {
64 beforeShow: function(input, inst) {
65 this.multiDatesPicker.changed = false;
66 if(this.multiDatesPicker.originalBeforeShow)
67 this.multiDatesPicker.originalBeforeShow.call(this, input, inst);
68 },
69 onSelect : function(dateText, inst) {
70 var $this = $(this);
71 this.multiDatesPicker.changed = true;
72
73 if (dateText) {
74 $this.multiDatesPicker('toggleDate', dateText);
75 }
76
77 if (this.multiDatesPicker.mode == 'normal' && this.multiDatesPicker.dates.picked.length > 0 && this.multiDatesPicker.pickableRange) {
78 var min_date = this.multiDatesPicker.dates.picked[0],
79 max_date = new Date(min_date.getTime());
80
81 methods.sumDays(max_date, this.multiDatesPicker.pickableRange-1);
82
83 // counts the number of disabled dates in the range
84 if(this.multiDatesPicker.adjustRangeToDisabled) {
85 var c_disabled,
86 disabled = this.multiDatesPicker.dates.disabled.slice(0);
87 do {
88 c_disabled = 0;
89 for(var i = 0; i < disabled.length; i++) {
90 if(disabled[i].getTime() <= max_date.getTime()) {
91 if((min_date.getTime() <= disabled[i].getTime()) && (disabled[i].getTime() <= max_date.getTime()) ) {
92 c_disabled++;
93 }
94 disabled.splice(i, 1);
95 i--;
96 }
97 }
98 max_date.setDate(max_date.getDate() + c_disabled);
99 } while(c_disabled != 0);
100 }
101
102 if(this.multiDatesPicker.maxDate && (max_date > this.multiDatesPicker.maxDate))
103 max_date = this.multiDatesPicker.maxDate;
104
105 $this
106 .datepicker("option", "minDate", min_date)
107 .datepicker("option", "maxDate", max_date);
108 } else {
109 $this
110 .datepicker("option", "minDate", this.multiDatesPicker.minDate)
111 .datepicker("option", "maxDate", this.multiDatesPicker.maxDate);
112 }
113
114 if(this.tagName == 'INPUT') { // for inputs
115 $this.val(
116 $this.multiDatesPicker('getDates', 'string')
117 );
118 }
119
120 if(this.multiDatesPicker.originalOnSelect && dateText)
121 this.multiDatesPicker.originalOnSelect.call(this, dateText, inst);
122
123 // thanks to bibendus83 -> http://sourceforge.net/tracker/?func=detail&atid=1495384&aid=3403159&group_id=358205
124 if ($this.datepicker('option', 'altField') != undefined && $this.datepicker('option', 'altField') != "") {
125 $($this.datepicker('option', 'altField')).val(
126 $this.multiDatesPicker('getDates', 'string')
127 );
128 }
129 },
130 beforeShowDay : function(date) {
131 var $this = $(this),
132 gotThisDate = $this.multiDatesPicker('gotDate', date) !== false,
133 isDisabledCalendar = $this.datepicker('option', 'disabled'),
134 isDisabledDate = $this.multiDatesPicker('gotDate', date, 'disabled') !== false,
135 areAllSelected = this.multiDatesPicker.maxPicks == this.multiDatesPicker.dates.picked.length;
136
137 var custom = [true, ''];
138 if(this.multiDatesPicker.originalBeforeShowDay)
139 custom = this.multiDatesPicker.originalBeforeShowDay.call(this, date);
140
141 var highlight_class = (gotThisDate ? 'ui-state-highlight' : '') + ((custom[1] && gotThisDate) ? ' ' : '') + custom[1];
142 var selectable_date = !(isDisabledCalendar || isDisabledDate || (areAllSelected && !highlight_class));
143 custom[0] = selectable_date && custom[0];
144 custom[1] = highlight_class;
145 return custom;
146 },
147 onClose: function(dateText, inst) {
148 if(this.tagName == 'INPUT' && this.multiDatesPicker.changed) {
149 $(inst.dpDiv[0]).stop(false,true);
150 setTimeout('$("#'+inst.id+'").datepicker("show")',50);
151 }
152 if(this.multiDatesPicker.originalOnClose) this.multiDatesPicker.originalOnClose.call(this, dateText, inst);
153 }
154 };
155
156 if(options) {
157 this.multiDatesPicker.originalBeforeShow = options.beforeShow;
158 this.multiDatesPicker.originalOnSelect = options.onSelect;
159 this.multiDatesPicker.originalBeforeShowDay = options.beforeShowDay;
160 this.multiDatesPicker.originalOnClose = options.onClose;
161
162 $this.datepicker(options);
163
164 this.multiDatesPicker.minDate = $.datepicker._determineDate(this, options.minDate, null);
165 this.multiDatesPicker.maxDate = $.datepicker._determineDate(this, options.maxDate, null);
166
167 if(options.addDates) methods.addDates.call(this, options.addDates);
168 if(options.addDisabledDates)
169 methods.addDates.call(this, options.addDisabledDates, 'disabled');
170
171 methods.setMode.call(this, options);
172 } else {
173 $this.datepicker();
174 }
175
176 $this.datepicker('option', mdp_events);
177
178 if(this.tagName == 'INPUT') $this.val($this.multiDatesPicker('getDates', 'string'));
179
180 // Fixes the altField filled with defaultDate by default
181 var altFieldOption = $this.datepicker('option', 'altField');
182 if (altFieldOption) $(altFieldOption).val($this.multiDatesPicker('getDates', 'string'));
183 },
184 compareDates : function(date1, date2) {
185 date1 = dateConvert.call(this, date1);
186 date2 = dateConvert.call(this, date2);
187 // return > 0 means date1 is later than date2
188 // return == 0 means date1 is the same day as date2
189 // return < 0 means date1 is earlier than date2
190 var diff = date1.getFullYear() - date2.getFullYear();
191 if(!diff) {
192 diff = date1.getMonth() - date2.getMonth();
193 if(!diff)
194 diff = date1.getDate() - date2.getDate();
195 }
196 return diff;
197 },
198 sumDays : function( date, n_days ) {
199 var origDateType = typeof date;
200 obj_date = dateConvert.call(this, date);
201 obj_date.setDate(obj_date.getDate() + n_days);
202 return dateConvert.call(this, obj_date, origDateType);
203 },
204 dateConvert : function( date, desired_format, dateFormat ) {
205 var from_format = typeof date;
206
207 if(from_format == desired_format) {
208 if(from_format == 'object') {
209 try {
210 date.getTime();
211 } catch (e) {
212 $.error('Received date is in a non supported format!');
213 return false;
214 }
215 }
216 return date;
217 }
218
219 var $this = $(this);
220 if(typeof date == 'undefined') date = new Date(0);
221
222 if(desired_format != 'string' && desired_format != 'object' && desired_format != 'number')
223 $.error('Date format "'+ desired_format +'" not supported!');
224
225 if(!dateFormat) {
226 dateFormat = $.datepicker._defaults.dateFormat;
227
228 // thanks to bibendus83 -> http://sourceforge.net/tracker/index.php?func=detail&aid=3213174&group_id=358205&atid=1495382
229 var dp_dateFormat = $this.datepicker('option', 'dateFormat');
230 if (dp_dateFormat) {
231 dateFormat = dp_dateFormat;
232 }
233 }
234
235 // converts to object as a neutral format
236 switch(from_format) {
237 case 'object': break;
238 case 'string': date = $.datepicker.parseDate(dateFormat, date); break;
239 case 'number': date = new Date(date); break;
240 default: $.error('Conversion from "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker');
241 }
242 // then converts to the desired format
243 switch(desired_format) {
244 case 'object': return date;
245 case 'string': return $.datepicker.formatDate(dateFormat, date);
246 case 'number': return date.getTime();
247 default: $.error('Conversion to "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker');
248 }
249 return false;
250 },
251 gotDate : function( date, type ) {
252 if(!type) type = 'picked';
253 for(var i = 0; i < this.multiDatesPicker.dates[type].length; i++) {
254 if(methods.compareDates.call(this, this.multiDatesPicker.dates[type][i], date) === 0) {
255 return i;
256 }
257 }
258 return false;
259 },
260 getDates : function( format, type ) {
261 if(!format) format = 'string';
262 if(!type) type = 'picked';
263 switch (format) {
264 case 'object':
265 return this.multiDatesPicker.dates[type];
266 case 'string':
267 case 'number':
268 var o_dates = new Array();
269 for(var i in this.multiDatesPicker.dates[type])
270 o_dates.push(
271 dateConvert.call(
272 this,
273 this.multiDatesPicker.dates[type][i],
274 format
275 )
276 );
277 return o_dates;
278
279 default: $.error('Format "'+format+'" not supported!');
280 }
281 },
282 addDates : function( dates, type ) {
283 if(dates.length > 0) {
284 if(!type) type = 'picked';
285 switch(typeof dates) {
286 case 'object':
287 case 'array':
288 if(dates.length) {
289 for(var i in dates)
290 if (typeof dates[i] != "function")
291 addDate.call(this, dates[i], type, true);
292 sortDates.call(this, type);
293 break;
294 } // else does the same as 'string'
295 case 'string':
296 case 'number':
297 addDate.call(this, dates, type);
298 break;
299 default:
300 $.error('Date format "'+ typeof dates +'" not allowed on jQuery.multiDatesPicker');
301 }
302 $(this).datepicker('refresh');
303 } else {
304 $.error('Empty array of dates received.');
305 }
306 },
307 removeDates : function( dates, type ) {
308 if(!type) type = 'picked';
309 var removed = [];
310 if (Object.prototype.toString.call(dates) === '[object Array]') {
311 for(var i in dates.sort(function(a,b){return b-a})) {
312 removed.push(removeDate.call(this, dates[i], type));
313 }
314 } else {
315 removed.push(removeDate.call(this, dates, type));
316 }
317 $(this).datepicker('refresh');
318 return removed;
319 },
320 removeIndexes : function( indexes, type ) {
321 if(!type) type = 'picked';
322 var removed = [];
323 if (Object.prototype.toString.call(indexes) === '[object Array]') {
324 for(var i in indexes.sort(function(a,b){return b-a})) {
325 removed.push(removeIndex.call(this, indexes[i], type));
326 }
327 } else {
328 removed.push(removeIndex.call(this, indexes, type));
329 }
330 $(this).datepicker('refresh');
331 return removed;
332 },
333 resetDates : function ( type ) {
334 if(!type) type = 'picked';
335 this.multiDatesPicker.dates[type] = [];
336 $(this).datepicker('refresh');
337 },
338 toggleDate : function( date, type ) {
339 if(!type) type = 'picked';
340
341 switch(this.multiDatesPicker.mode) {
342 case 'daysRange':
343 this.multiDatesPicker.dates[type] = []; // deletes all picked/disabled dates
344 var end = this.multiDatesPicker.autoselectRange[1];
345 var begin = this.multiDatesPicker.autoselectRange[0];
346 if(end < begin) { // switch
347 end = this.multiDatesPicker.autoselectRange[0];
348 begin = this.multiDatesPicker.autoselectRange[1];
349 }
350 for(var i = begin; i < end; i++)
351 methods.addDates.call(this, methods.sumDays(date, i), type);
352 break;
353 default:
354 if(methods.gotDate.call(this, date) === false) // adds dates
355 methods.addDates.call(this, date, type);
356 else // removes dates
357 methods.removeDates.call(this, date, type);
358 break;
359 }
360 },
361 setMode : function( options ) {
362 var $this = $(this);
363 if(options.mode) this.multiDatesPicker.mode = options.mode;
364
365 switch(this.multiDatesPicker.mode) {
366 case 'normal':
367 for(option in options)
368 switch(option) {
369 case 'maxPicks':
370 case 'minPicks':
371 case 'pickableRange':
372 case 'adjustRangeToDisabled':
373 this.multiDatesPicker[option] = options[option];
374 break;
375 //default: $.error('Option ' + option + ' ignored for mode "'.options.mode.'".');
376 }
377 break;
378 case 'daysRange':
379 case 'weeksRange':
380 var mandatory = 1;
381 for(option in options)
382 switch(option) {
383 case 'autoselectRange':
384 mandatory--;
385 case 'pickableRange':
386 case 'adjustRangeToDisabled':
387 this.multiDatesPicker[option] = options[option];
388 break;
389 //default: $.error('Option ' + option + ' does not exist for setMode on jQuery.multiDatesPicker');
390 }
391 if(mandatory > 0) $.error('Some mandatory options not specified!');
392 break;
393 }
394
395 /*
396 if(options.pickableRange) {
397 $this.datepicker("option", "maxDate", options.pickableRange);
398 $this.datepicker("option", "minDate", this.multiDatesPicker.minDate);
399 }
400 */
401
402 if(mdp_events.onSelect)
403 mdp_events.onSelect();
404 $this.datepicker('refresh');
405 }
406 };
407
408 this.each(function() {
409 if (!this.multiDatesPicker) {
410 this.multiDatesPicker = {
411 dates: {
412 picked: [],
413 disabled: []
414 },
415 mode: 'normal',
416 adjustRangeToDisabled: true
417 };
418 }
419
420 if(methods[method]) {
421 var exec_result = methods[method].apply(this, Array.prototype.slice.call(mdp_arguments, 1));
422 switch(method) {
423 case 'getDates':
424 case 'removeDates':
425 case 'gotDate':
426 case 'sumDays':
427 case 'compareDates':
428 case 'dateConvert':
429 ret = exec_result;
430 }
431 return exec_result;
432 } else if( typeof method === 'object' || ! method ) {
433 return methods.init.apply(this, mdp_arguments);
434 } else {
435 $.error('Method ' + method + ' does not exist on jQuery.multiDatesPicker');
436 }
437 return false;
438 });
439
440 if(method != 'gotDate' && method != 'getDates') {
441 aaaa = 1;
442 }
443
444 return ret;
445 };
446
447 var PROP_NAME = 'multiDatesPicker';
448 var dpuuid = new Date().getTime();
449 var instActive;
450
451 $.multiDatesPicker = {version: false};
452 //$.multiDatesPicker = new MultiDatesPicker(); // singleton instance
453 $.multiDatesPicker.initialized = false;
454 $.multiDatesPicker.uuid = new Date().getTime();
455 $.multiDatesPicker.version = $.ui.multiDatesPicker.version;
456
457 // Workaround for #4055
458 // Add another global to avoid noConflict issues with inline event handlers
459 window['DP_jQuery_' + dpuuid] = $;
460 })( jQuery );