[PLUGINS] +les plugins de bases
[ptitvelo/web/www.git] / www / plugins / agenda_3_5 / 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];
142 var highlight_class = (gotThisDate ? 'ui-state-highlight' : '') + ((custom[1] && gotThisDate) ? ' ' : '') + custom[1];
143 var selectable_date = !(isDisabledCalendar || isDisabledDate || (areAllSelected && !highlight_class));
144 custom[0] = selectable_date && custom[0];
145 custom[1] = highlight_class;
146 return custom;
147 },
148 onClose: function(dateText, inst) {
149 if(this.tagName == 'INPUT' && this.multiDatesPicker.changed) {
150 $(inst.dpDiv[0]).stop(false,true);
151 setTimeout('$("#'+inst.id+'").datepicker("show")',50);
152 }
153 if(this.multiDatesPicker.originalOnClose) this.multiDatesPicker.originalOnClose.call(this, dateText, inst);
154 }
155 };
156
157 if(options) {
158 this.multiDatesPicker.originalBeforeShow = options.beforeShow;
159 this.multiDatesPicker.originalOnSelect = options.onSelect;
160 this.multiDatesPicker.originalBeforeShowDay = options.beforeShowDay;
161 this.multiDatesPicker.originalOnClose = options.onClose;
162
163 $this.datepicker(options);
164
165 this.multiDatesPicker.minDate = $.datepicker._determineDate(this, options.minDate, null);
166 this.multiDatesPicker.maxDate = $.datepicker._determineDate(this, options.maxDate, null);
167
168 if(options.addDates) methods.addDates.call(this, options.addDates);
169 if(options.addDisabledDates)
170 methods.addDates.call(this, options.addDisabledDates, 'disabled');
171
172 methods.setMode.call(this, options);
173 } else {
174 $this.datepicker();
175 }
176
177 $this.datepicker('option', mdp_events);
178
179 if(this.tagName == 'INPUT') $this.val($this.multiDatesPicker('getDates', 'string'));
180
181 // Fixes the altField filled with defaultDate by default
182 var altFieldOption = $this.datepicker('option', 'altField');
183 if (altFieldOption) $(altFieldOption).val($this.multiDatesPicker('getDates', 'string'));
184 },
185 compareDates : function(date1, date2) {
186 date1 = dateConvert.call(this, date1);
187 date2 = dateConvert.call(this, date2);
188 // return > 0 means date1 is later than date2
189 // return == 0 means date1 is the same day as date2
190 // return < 0 means date1 is earlier than date2
191 var diff = date1.getFullYear() - date2.getFullYear();
192 if(!diff) {
193 diff = date1.getMonth() - date2.getMonth();
194 if(!diff)
195 diff = date1.getDate() - date2.getDate();
196 }
197 return diff;
198 },
199 sumDays : function( date, n_days ) {
200 var origDateType = typeof date;
201 obj_date = dateConvert.call(this, date);
202 obj_date.setDate(obj_date.getDate() + n_days);
203 return dateConvert.call(this, obj_date, origDateType);
204 },
205 dateConvert : function( date, desired_format, dateFormat ) {
206 var from_format = typeof date;
207
208 if(from_format == desired_format) {
209 if(from_format == 'object') {
210 try {
211 date.getTime();
212 } catch (e) {
213 $.error('Received date is in a non supported format!');
214 return false;
215 }
216 }
217 return date;
218 }
219
220 var $this = $(this);
221 if(typeof date == 'undefined') date = new Date(0);
222
223 if(desired_format != 'string' && desired_format != 'object' && desired_format != 'number')
224 $.error('Date format "'+ desired_format +'" not supported!');
225
226 if(!dateFormat) {
227 dateFormat = $.datepicker._defaults.dateFormat;
228
229 // thanks to bibendus83 -> http://sourceforge.net/tracker/index.php?func=detail&aid=3213174&group_id=358205&atid=1495382
230 var dp_dateFormat = $this.datepicker('option', 'dateFormat');
231 if (dp_dateFormat) {
232 dateFormat = dp_dateFormat;
233 }
234 }
235
236 // converts to object as a neutral format
237 switch(from_format) {
238 case 'object': break;
239 case 'string': date = $.datepicker.parseDate(dateFormat, date); break;
240 case 'number': date = new Date(date); break;
241 default: $.error('Conversion from "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker');
242 }
243 // then converts to the desired format
244 switch(desired_format) {
245 case 'object': return date;
246 case 'string': return $.datepicker.formatDate(dateFormat, date);
247 case 'number': return date.getTime();
248 default: $.error('Conversion to "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker');
249 }
250 return false;
251 },
252 gotDate : function( date, type ) {
253 if(!type) type = 'picked';
254 for(var i = 0; i < this.multiDatesPicker.dates[type].length; i++) {
255 if(methods.compareDates.call(this, this.multiDatesPicker.dates[type][i], date) === 0) {
256 return i;
257 }
258 }
259 return false;
260 },
261 getDates : function( format, type ) {
262 if(!format) format = 'string';
263 if(!type) type = 'picked';
264 switch (format) {
265 case 'object':
266 return this.multiDatesPicker.dates[type];
267 case 'string':
268 case 'number':
269 var o_dates = new Array();
270 for(var i in this.multiDatesPicker.dates[type])
271 o_dates.push(
272 dateConvert.call(
273 this,
274 this.multiDatesPicker.dates[type][i],
275 format
276 )
277 );
278 return o_dates;
279
280 default: $.error('Format "'+format+'" not supported!');
281 }
282 },
283 addDates : function( dates, type ) {
284 if(dates.length > 0) {
285 if(!type) type = 'picked';
286 switch(typeof dates) {
287 case 'object':
288 case 'array':
289 if(dates.length) {
290 for(var i in dates)
291 if (typeof dates[i] != "function")
292 addDate.call(this, dates[i], type, true);
293 sortDates.call(this, type);
294 break;
295 } // else does the same as 'string'
296 case 'string':
297 case 'number':
298 addDate.call(this, dates, type);
299 break;
300 default:
301 $.error('Date format "'+ typeof dates +'" not allowed on jQuery.multiDatesPicker');
302 }
303 $(this).datepicker('refresh');
304 } else {
305 $.error('Empty array of dates received.');
306 }
307 },
308 removeDates : function( dates, type ) {
309 if(!type) type = 'picked';
310 var removed = [];
311 if (Object.prototype.toString.call(dates) === '[object Array]') {
312 for(var i in dates.sort(function(a,b){return b-a})) {
313 removed.push(removeDate.call(this, dates[i], type));
314 }
315 } else {
316 removed.push(removeDate.call(this, dates, type));
317 }
318 $(this).datepicker('refresh');
319 return removed;
320 },
321 removeIndexes : function( indexes, type ) {
322 if(!type) type = 'picked';
323 var removed = [];
324 if (Object.prototype.toString.call(indexes) === '[object Array]') {
325 for(var i in indexes.sort(function(a,b){return b-a})) {
326 removed.push(removeIndex.call(this, indexes[i], type));
327 }
328 } else {
329 removed.push(removeIndex.call(this, indexes, type));
330 }
331 $(this).datepicker('refresh');
332 return removed;
333 },
334 resetDates : function ( type ) {
335 if(!type) type = 'picked';
336 this.multiDatesPicker.dates[type] = [];
337 $(this).datepicker('refresh');
338 },
339 toggleDate : function( date, type ) {
340 if(!type) type = 'picked';
341
342 switch(this.multiDatesPicker.mode) {
343 case 'daysRange':
344 this.multiDatesPicker.dates[type] = []; // deletes all picked/disabled dates
345 var end = this.multiDatesPicker.autoselectRange[1];
346 var begin = this.multiDatesPicker.autoselectRange[0];
347 if(end < begin) { // switch
348 end = this.multiDatesPicker.autoselectRange[0];
349 begin = this.multiDatesPicker.autoselectRange[1];
350 }
351 for(var i = begin; i < end; i++)
352 methods.addDates.call(this, methods.sumDays(date, i), type);
353 break;
354 default:
355 if(methods.gotDate.call(this, date) === false) // adds dates
356 methods.addDates.call(this, date, type);
357 else // removes dates
358 methods.removeDates.call(this, date, type);
359 break;
360 }
361 },
362 setMode : function( options ) {
363 var $this = $(this);
364 if(options.mode) this.multiDatesPicker.mode = options.mode;
365
366 switch(this.multiDatesPicker.mode) {
367 case 'normal':
368 for(option in options)
369 switch(option) {
370 case 'maxPicks':
371 case 'minPicks':
372 case 'pickableRange':
373 case 'adjustRangeToDisabled':
374 this.multiDatesPicker[option] = options[option];
375 break;
376 //default: $.error('Option ' + option + ' ignored for mode "'.options.mode.'".');
377 }
378 break;
379 case 'daysRange':
380 case 'weeksRange':
381 var mandatory = 1;
382 for(option in options)
383 switch(option) {
384 case 'autoselectRange':
385 mandatory--;
386 case 'pickableRange':
387 case 'adjustRangeToDisabled':
388 this.multiDatesPicker[option] = options[option];
389 break;
390 //default: $.error('Option ' + option + ' does not exist for setMode on jQuery.multiDatesPicker');
391 }
392 if(mandatory > 0) $.error('Some mandatory options not specified!');
393 break;
394 }
395
396 /*
397 if(options.pickableRange) {
398 $this.datepicker("option", "maxDate", options.pickableRange);
399 $this.datepicker("option", "minDate", this.multiDatesPicker.minDate);
400 }
401 */
402
403 if(mdp_events.onSelect)
404 mdp_events.onSelect();
405 $this.datepicker('refresh');
406 }
407 };
408
409 this.each(function() {
410 if (!this.multiDatesPicker) {
411 this.multiDatesPicker = {
412 dates: {
413 picked: [],
414 disabled: []
415 },
416 mode: 'normal',
417 adjustRangeToDisabled: true
418 };
419 }
420
421 if(methods[method]) {
422 var exec_result = methods[method].apply(this, Array.prototype.slice.call(mdp_arguments, 1));
423 switch(method) {
424 case 'getDates':
425 case 'removeDates':
426 case 'gotDate':
427 case 'sumDays':
428 case 'compareDates':
429 case 'dateConvert':
430 ret = exec_result;
431 }
432 return exec_result;
433 } else if( typeof method === 'object' || ! method ) {
434 return methods.init.apply(this, mdp_arguments);
435 } else {
436 $.error('Method ' + method + ' does not exist on jQuery.multiDatesPicker');
437 }
438 return false;
439 });
440
441 if(method != 'gotDate' && method != 'getDates') {
442 aaaa = 1;
443 }
444
445 return ret;
446 };
447
448 var PROP_NAME = 'multiDatesPicker';
449 var dpuuid = new Date().getTime();
450 var instActive;
451
452 $.multiDatesPicker = {version: false};
453 //$.multiDatesPicker = new MultiDatesPicker(); // singleton instance
454 $.multiDatesPicker.initialized = false;
455 $.multiDatesPicker.uuid = new Date().getTime();
456 $.multiDatesPicker.version = $.ui.multiDatesPicker.version;
457
458 // Workaround for #4055
459 // Add another global to avoid noConflict issues with inline event handlers
460 window['DP_jQuery_' + dpuuid] = $;
461 })( jQuery );