diff --git a/jquery-ui.multidatespicker.js b/jquery-ui.multidatespicker.js index 85546af..230c824 100644 --- a/jquery-ui.multidatespicker.js +++ b/jquery-ui.multidatespicker.js @@ -6,493 +6,522 @@ * Dual licensed under the MIT or GPL version 2 licenses. */ (function( $ ){ - $.extend($.ui, { multiDatesPicker: { version: "1.6.4" } }); - - $.fn.multiDatesPicker = function(method) { - var mdp_arguments = arguments; - var ret = this; - var today_date = new Date(); - var day_zero = new Date(0); - var mdp_events = {}; - - function removeDate(date, type) { - if(!type) type = 'picked'; - date = dateConvert.call(this, date); - for(var i = 0; i < this.multiDatesPicker.dates[type].length; i++) - if(!methods.compareDates(this.multiDatesPicker.dates[type][i], date)) - return this.multiDatesPicker.dates[type].splice(i, 1).pop(); - } - function removeIndex(index, type) { - if(!type) type = 'picked'; - return this.multiDatesPicker.dates[type].splice(index, 1).pop(); - } - function addDate(date, type, no_sort) { - if(!type) type = 'picked'; - date = dateConvert.call(this, date); - - // @todo: use jQuery UI datepicker method instead - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - date.setMilliseconds(0); - - if (methods.gotDate.call(this, date, type) === false) { - this.multiDatesPicker.dates[type].push(date); - if(!no_sort) this.multiDatesPicker.dates[type].sort(methods.compareDates); - } - } - function sortDates(type) { - if(!type) type = 'picked'; - this.multiDatesPicker.dates[type].sort(methods.compareDates); - } - function dateConvert(date, desired_type, date_format) { - if(!desired_type) desired_type = 'object';/* - if(!date_format && (typeof date == 'string')) { - date_format = $(this).datepicker('option', 'dateFormat'); - if(!date_format) date_format = $.datepicker._defaults.dateFormat; - } - */ - return methods.dateConvert.call(this, date, desired_type, date_format); - } - - var methods = { - init : function( options ) { - var $this = $(this); - this.multiDatesPicker.changed = false; - - var mdp_events = { - beforeShow: function(input, inst) { - this.multiDatesPicker.changed = false; - if(this.multiDatesPicker.originalBeforeShow) - this.multiDatesPicker.originalBeforeShow.call(this, input, inst); - }, - onSelect : function(dateText, inst) { - var $this = $(this); - this.multiDatesPicker.changed = true; - - if (dateText) { - $this.multiDatesPicker('toggleDate', dateText); - this.multiDatesPicker.changed = true; - // @todo: this will be optimized when I'll move methods to the singleton. - } - - if (this.multiDatesPicker.mode == 'normal' && this.multiDatesPicker.pickableRange) { - if(this.multiDatesPicker.dates.picked.length > 0) { - var min_date = this.multiDatesPicker.dates.picked[0], - max_date = new Date(min_date.getTime()); - - methods.sumDays(max_date, this.multiDatesPicker.pickableRange-1); - - // counts the number of disabled dates in the range - if(this.multiDatesPicker.adjustRangeToDisabled) { - var c_disabled, - disabled = this.multiDatesPicker.dates.disabled.slice(0); - do { - c_disabled = 0; - for(var i = 0; i < disabled.length; i++) { - if(disabled[i].getTime() <= max_date.getTime()) { - if((min_date.getTime() <= disabled[i].getTime()) && (disabled[i].getTime() <= max_date.getTime()) ) { - c_disabled++; - } - disabled.splice(i, 1); - i--; - } - } - max_date.setDate(max_date.getDate() + c_disabled); - } while(c_disabled != 0); - } - - if(this.multiDatesPicker.maxDate && (max_date > this.multiDatesPicker.maxDate)) - max_date = this.multiDatesPicker.maxDate; - - $this - .datepicker("option", "minDate", min_date) - .datepicker("option", "maxDate", max_date); - } else { - $this - .datepicker("option", "minDate", this.multiDatesPicker.minDate) - .datepicker("option", "maxDate", this.multiDatesPicker.maxDate); - } - } - - if(this.multiDatesPicker.originalOnSelect && dateText) - this.multiDatesPicker.originalOnSelect.call(this, dateText, inst); - - }, - beforeShowDay : function(date) { - var $this = $(this), - gotThisDate = $this.multiDatesPicker('gotDate', date) !== false, - isDisabledCalendar = $this.datepicker('option', 'disabled'), - isDisabledDate = $this.multiDatesPicker('gotDate', date, 'disabled') !== false, - areAllSelected = this.multiDatesPicker.maxPicks <= this.multiDatesPicker.dates.picked.length; - - var bsdReturn = [true, '', null]; - if(this.multiDatesPicker.originalBeforeShowDay) - bsdReturn = this.multiDatesPicker.originalBeforeShowDay.call(this, date); - - bsdReturn[1] = gotThisDate ? 'ui-state-highlight '+bsdReturn[1] : bsdReturn[1]; - bsdReturn[0] = bsdReturn[0] && !(isDisabledCalendar || isDisabledDate || (areAllSelected && !bsdReturn[1])); - return bsdReturn; - } - }; - - // value have to be extracted before datepicker is initiated - if($this.val()) var inputDates = $this.val() - - if(options) { - // value have to be extracted before datepicker is initiated - //if(options.altField) var inputDates = $(options.altField).val(); - if(options.separator) this.multiDatesPicker.separator = options.separator; - if(!this.multiDatesPicker.separator) this.multiDatesPicker.separator = ', '; - - this.multiDatesPicker.originalBeforeShow = options.beforeShow; - this.multiDatesPicker.originalOnSelect = options.onSelect; - this.multiDatesPicker.originalBeforeShowDay = options.beforeShowDay; - this.multiDatesPicker.originalOnClose = options.onClose; - - // datepicker init - $this.datepicker(options); - - this.multiDatesPicker.minDate = $.datepicker._determineDate(this, options.minDate, null); - this.multiDatesPicker.maxDate = $.datepicker._determineDate(this, options.maxDate, null); - if(options.addDates) methods.addDates.call(this, options.addDates); - - if(options.addDisabledDates) - methods.addDates.call(this, options.addDisabledDates, 'disabled'); - - methods.setMode.call(this, options); - } else { - $this.datepicker(); - } - $this.datepicker('option', mdp_events); - - // adds any dates found in the input or alt field - if(inputDates) $this.multiDatesPicker('value', inputDates); - - // generates the new string of added dates - var inputs_values = $this.multiDatesPicker('value'); - - // fills the input field back with all the dates in the calendar - $this.val(inputs_values); - - // Fixes the altField filled with defaultDate by default - var altFieldOption = $this.datepicker('option', 'altField'); - if (altFieldOption) $(altFieldOption).val(inputs_values); - - // Updates the calendar view - $this.datepicker('refresh'); - }, - compareDates : function(date1, date2) { - date1 = dateConvert.call(this, date1); - date2 = dateConvert.call(this, date2); - // return > 0 means date1 is later than date2 - // return == 0 means date1 is the same day as date2 - // return < 0 means date1 is earlier than date2 - var diff = date1.getFullYear() - date2.getFullYear(); - if(!diff) { - diff = date1.getMonth() - date2.getMonth(); - if(!diff) - diff = date1.getDate() - date2.getDate(); - } - return diff; - }, - sumDays : function( date, n_days ) { - var origDateType = typeof date; - obj_date = dateConvert.call(this, date); - obj_date.setDate(obj_date.getDate() + n_days); - return dateConvert.call(this, obj_date, origDateType); - }, - dateConvert : function( date, desired_format, dateFormat ) { - var from_format = typeof date; - var $this = $(this); - - if(from_format == desired_format) { - if(from_format == 'object') { - try { - date.getTime(); - } catch (e) { - $.error('Received date is in a non supported format!'); - return false; - } - } - return date; - } - - if(typeof date == 'undefined') date = new Date(0); - - if(desired_format != 'string' && desired_format != 'object' && desired_format != 'number') - $.error('Date format "'+ desired_format +'" not supported!'); - - if(!dateFormat) { - // thanks to bibendus83 -> http://sourceforge.net/tracker/index.php?func=detail&aid=3213174&group_id=358205&atid=1495382 - var dp_dateFormat = $this.datepicker('option', 'dateFormat'); - if (dp_dateFormat) { - dateFormat = dp_dateFormat; - } else { - dateFormat = $.datepicker._defaults.dateFormat; - } - } - - // converts to object as a neutral format - switch(from_format) { - case 'object': break; - case 'string': date = $.datepicker.parseDate(dateFormat, date); break; - case 'number': date = new Date(date); break; - default: $.error('Conversion from "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker'); - } - // then converts to the desired format - switch(desired_format) { - case 'object': return date; - case 'string': return $.datepicker.formatDate(dateFormat, date); - case 'number': return date.getTime(); - default: $.error('Conversion to "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker'); - } - return false; - }, - gotDate : function( date, type ) { - if(!type) type = 'picked'; - for(var i = 0; i < this.multiDatesPicker.dates[type].length; i++) { - if(methods.compareDates.call(this, this.multiDatesPicker.dates[type][i], date) === 0) { - return i; - } - } - return false; - }, - value : function( value ) { - if(value && typeof value == 'string') { - methods.addDates.call(this, value.split(this.multiDatesPicker.separator)); - } else { - var dates = methods.getDates.call(this, 'string'); - return dates.length - ? dates.join(this.multiDatesPicker.separator) - : ""; - } - }, - getDates : function( format, type ) { - if(!format) format = 'string'; - if(!type) type = 'picked'; - switch (format) { - case 'object': - return this.multiDatesPicker.dates[type]; - case 'string': - case 'number': - var o_dates = new Array(); - for(var i in this.multiDatesPicker.dates[type]) - o_dates.push( - dateConvert.call( - this, - this.multiDatesPicker.dates[type][i], - format - ) - ); - return o_dates; - - default: $.error('Format "'+format+'" not supported!'); - } - }, - addDates : function( dates, type ) { - if(dates.length > 0) { - if(!type) type = 'picked'; - switch(typeof dates) { - case 'object': - case 'array': - if(dates.length) { - for(var i = 0; i < dates.length; i++) - addDate.call(this, dates[i], type, true); - sortDates.call(this, type); - break; - } // else does the same as 'string' - case 'string': - case 'number': - addDate.call(this, dates, type); - break; - default: - $.error('Date format "'+ typeof dates +'" not allowed on jQuery.multiDatesPicker'); - } - //$(this).datepicker('refresh'); - } else { - $.error('Empty array of dates received.'); - } - }, - removeDates : function( dates, type ) { - if(!type) type = 'picked'; - var removed = []; - if (Object.prototype.toString.call(dates) === '[object Array]') { - for(var i in dates.sort(function(a,b){return b-a})) { - removed.push(removeDate.call(this, dates[i], type)); - } - } else { - removed.push(removeDate.call(this, dates, type)); - } - return removed; - }, - removeIndexes : function( indexes, type ) { - if(!type) type = 'picked'; - var removed = []; - if (Object.prototype.toString.call(indexes) === '[object Array]') { - for(var i in indexes.sort(function(a,b){return b-a})) { - removed.push(removeIndex.call(this, indexes[i], type)); - } - } else { - removed.push(removeIndex.call(this, indexes, type)); - } - return removed; - }, - resetDates : function ( type ) { - if(!type) type = 'picked'; - this.multiDatesPicker.dates[type] = []; - }, - toggleDate : function( date, type ) { - if(!type) type = 'picked'; - - switch(this.multiDatesPicker.mode) { - case 'daysRange': - this.multiDatesPicker.dates[type] = []; // deletes all picked/disabled dates - var end = this.multiDatesPicker.autoselectRange[1]; - var begin = this.multiDatesPicker.autoselectRange[0]; - if(end < begin) { // switch - end = this.multiDatesPicker.autoselectRange[0]; - begin = this.multiDatesPicker.autoselectRange[1]; - } - for(var i = begin; i < end; i++) - methods.addDates.call(this, methods.sumDays.call(this,date, i), type); - break; - default: - if(methods.gotDate.call(this, date) === false) // adds dates - methods.addDates.call(this, date, type); - else // removes dates - methods.removeDates.call(this, date, type); - break; - } - }, - setMode : function( options ) { - var $this = $(this); - if(options.mode) this.multiDatesPicker.mode = options.mode; - - switch(this.multiDatesPicker.mode) { - case 'normal': - for(option in options) - switch(option) { - case 'maxPicks': - case 'minPicks': - case 'pickableRange': - case 'adjustRangeToDisabled': - this.multiDatesPicker[option] = options[option]; - break; - //default: $.error('Option ' + option + ' ignored for mode "'.options.mode.'".'); - } - break; - case 'daysRange': - case 'weeksRange': - var mandatory = 1; - for(option in options) - switch(option) { - case 'autoselectRange': - mandatory--; - case 'pickableRange': - case 'adjustRangeToDisabled': - this.multiDatesPicker[option] = options[option]; - break; - //default: $.error('Option ' + option + ' does not exist for setMode on jQuery.multiDatesPicker'); - } - if(mandatory > 0) $.error('Some mandatory options not specified!'); - break; - } - - /* - if(options.pickableRange) { - $this.datepicker("option", "maxDate", options.pickableRange); - $this.datepicker("option", "minDate", this.multiDatesPicker.minDate); - } - */ - - if(mdp_events.onSelect) - mdp_events.onSelect(); - }, - destroy: function(){ - this.multiDatesPicker = null; - $(this).datepicker('destroy'); - } - }; - - this.each(function() { - var $this = $(this); - if (!this.multiDatesPicker) { - this.multiDatesPicker = { - dates: { - picked: [], - disabled: [] - }, - mode: 'normal', - adjustRangeToDisabled: true - }; - } - - if(methods[method]) { - var exec_result = methods[method].apply(this, Array.prototype.slice.call(mdp_arguments, 1)); - switch(method) { - case 'removeDates': - case 'removeIndexes': - case 'resetDates': - case 'toggleDate': - case 'addDates': - var altField = $this.datepicker('option', 'altField'); - // @todo: should use altFormat for altField - var dates_string = methods.value.call(this); - if (altField !== undefined && altField != "") { - $(altField).val(dates_string); - } - $this.val(dates_string); - - $.datepicker._refreshDatepicker(this); - } - switch(method) { - case 'removeDates': - case 'getDates': - case 'gotDate': - case 'sumDays': - case 'compareDates': - case 'dateConvert': - case 'value': - ret = exec_result; - } - return exec_result; - } else if( typeof method === 'object' || ! method ) { - return methods.init.apply(this, mdp_arguments); - } else { - $.error('Method ' + method + ' does not exist on jQuery.multiDatesPicker'); - } - return false; - }); - - return ret; - }; + $.extend($.ui, { multiDatesPicker: { version: "1.6.4" } }); + + $.fn.multiDatesPicker = function(method) { + var mdp_arguments = arguments; + var ret = this; + var today_date = new Date(); + var day_zero = new Date(0); + var mdp_events = {}; + + function removeDate(date, type) { + if(!type) type = 'picked'; + date = dateConvert.call(this, date); + for(var i = 0; i < this.multiDatesPicker.dates[type].length; i++) + if(!methods.compareDates(this.multiDatesPicker.dates[type][i], date)) + return this.multiDatesPicker.dates[type].splice(i, 1).pop(); + } + function removeIndex(index, type) { + if(!type) type = 'picked'; + return this.multiDatesPicker.dates[type].splice(index, 1).pop(); + } + function addDate(date, type, no_sort) { + if(!type) type = 'picked'; + date = dateConvert.call(this, date); + + // @todo: use jQuery UI datepicker method instead + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + date.setMilliseconds(0); + + if (methods.gotDate.call(this, date, type) === false) { + this.multiDatesPicker.dates[type].push(date); + if(!no_sort) this.multiDatesPicker.dates[type].sort(methods.compareDates); + } + } + function sortDates(type) { + if(!type) type = 'picked'; + this.multiDatesPicker.dates[type].sort(methods.compareDates); + } + function dateConvert(date, desired_type, date_format) { + if(!desired_type) desired_type = 'object';/* + if(!date_format && (typeof date == 'string')) { + date_format = $(this).datepicker('option', 'dateFormat'); + if(!date_format) date_format = $.datepicker._defaults.dateFormat; + } + */ + return methods.dateConvert.call(this, date, desired_type, date_format); + } + + var methods = { + init : function( options ) { + var $this = $(this); + this.multiDatesPicker.changed = false; + + var mdp_events = { + beforeShow: function(input, inst) { + this.multiDatesPicker.changed = false; + if(this.multiDatesPicker.originalBeforeShow) + this.multiDatesPicker.originalBeforeShow.call(this, input, inst); + }, + onSelect : function(dateText, inst) { + var $this = $(this); + this.multiDatesPicker.changed = true; + + if (dateText) { + $this.multiDatesPicker('toggleDate', dateText); + this.multiDatesPicker.changed = true; + // @todo: this will be optimized when I'll move methods to the singleton. + } + + if (this.multiDatesPicker.mode == 'normal' && this.multiDatesPicker.pickableRange) { + if(this.multiDatesPicker.dates.picked.length > 0) { + var min_date = this.multiDatesPicker.dates.picked[0], + max_date = new Date(min_date.getTime()); + + methods.sumDays(max_date, this.multiDatesPicker.pickableRange-1); + + // counts the number of disabled dates in the range + if(this.multiDatesPicker.adjustRangeToDisabled) { + var c_disabled, + disabled = this.multiDatesPicker.dates.disabled.slice(0); + do { + c_disabled = 0; + for(var i = 0; i < disabled.length; i++) { + if(disabled[i].getTime() <= max_date.getTime()) { + if((min_date.getTime() <= disabled[i].getTime()) && (disabled[i].getTime() <= max_date.getTime()) ) { + c_disabled++; + } + disabled.splice(i, 1); + i--; + } + } + max_date.setDate(max_date.getDate() + c_disabled); + } while(c_disabled != 0); + } + + if(this.multiDatesPicker.maxDate && (max_date > this.multiDatesPicker.maxDate)) + max_date = this.multiDatesPicker.maxDate; + + $this + .datepicker("option", "minDate", min_date) + .datepicker("option", "maxDate", max_date); + } else { + $this + .datepicker("option", "minDate", this.multiDatesPicker.minDate) + .datepicker("option", "maxDate", this.multiDatesPicker.maxDate); + } + } + + if(this.multiDatesPicker.originalOnSelect && dateText) + this.multiDatesPicker.originalOnSelect.call(this, dateText, inst); + + }, + beforeShowDay : function(date) { + var $this = $(this), + gotThisDate = $this.multiDatesPicker('gotDate', date) !== false, + isDisabledCalendar = $this.datepicker('option', 'disabled'), + isDisabledDate = $this.multiDatesPicker('gotDate', date, 'disabled') !== false, + areAllSelected = this.multiDatesPicker.maxPicks <= this.multiDatesPicker.dates.picked.length; + + var bsdReturn = [true, '', null]; + if(this.multiDatesPicker.originalBeforeShowDay) + bsdReturn = this.multiDatesPicker.originalBeforeShowDay.call(this, date); + + bsdReturn[1] = gotThisDate ? 'ui-state-highlight '+bsdReturn[1] : bsdReturn[1]; + bsdReturn[0] = bsdReturn[0] && !(isDisabledCalendar || isDisabledDate || (areAllSelected && !bsdReturn[1])); + return bsdReturn; + } + }; + + // value have to be extracted before datepicker is initiated + if($this.val()) var inputDates = $this.val() + + if(options) { + // value have to be extracted before datepicker is initiated + //if(options.altField) var inputDates = $(options.altField).val(); + if(options.separator) this.multiDatesPicker.separator = options.separator; + if(!this.multiDatesPicker.separator) this.multiDatesPicker.separator = ', '; + + this.multiDatesPicker.originalBeforeShow = options.beforeShow; + this.multiDatesPicker.originalOnSelect = options.onSelect; + this.multiDatesPicker.originalBeforeShowDay = options.beforeShowDay; + this.multiDatesPicker.originalOnClose = options.onClose; + + // datepicker init + $this.datepicker(options); + + this.multiDatesPicker.minDate = $.datepicker._determineDate(this, options.minDate, null); + this.multiDatesPicker.maxDate = $.datepicker._determineDate(this, options.maxDate, null); + if(options.addDates) methods.addDates.call(this, options.addDates); + + if(options.addFormattedDates) { + if(!$.isArray(options.addFormattedDates) || options.addFormattedDates.length < 2) { + $.error('addFormattedDates parameter needs to be an array of 2 elements [dates, datepicker_format]'); + } + methods.addFormattedDates.call(this, options.addFormattedDates[0], options.addFormattedDates[1]); + } - var PROP_NAME = 'multiDatesPicker'; - var dpuuid = new Date().getTime(); - var instActive; + if(options.addDisabledDates) + methods.addDates.call(this, options.addDisabledDates, 'disabled'); + + methods.setMode.call(this, options); + } else { + $this.datepicker(); + } + $this.datepicker('option', mdp_events); + + // adds any dates found in the input or alt field + if(inputDates) $this.multiDatesPicker('value', inputDates); + + // generates the new string of added dates + var inputs_values = $this.multiDatesPicker('value'); + + // fills the input field back with all the dates in the calendar + $this.val(inputs_values); + + // Fixes the altField filled with defaultDate by default + var altFieldOption = $this.datepicker('option', 'altField'); + if (altFieldOption) $(altFieldOption).val(inputs_values); + + // Updates the calendar view + $this.datepicker('refresh'); + }, + compareDates : function(date1, date2) { + date1 = dateConvert.call(this, date1); + date2 = dateConvert.call(this, date2); + // return > 0 means date1 is later than date2 + // return == 0 means date1 is the same day as date2 + // return < 0 means date1 is earlier than date2 + var diff = date1.getFullYear() - date2.getFullYear(); + if(!diff) { + diff = date1.getMonth() - date2.getMonth(); + if(!diff) + diff = date1.getDate() - date2.getDate(); + } + return diff; + }, + sumDays : function( date, n_days ) { + var origDateType = typeof date; + obj_date = dateConvert.call(this, date); + obj_date.setDate(obj_date.getDate() + n_days); + return dateConvert.call(this, obj_date, origDateType); + }, + dateConvert : function( date, desired_format, dateFormat ) { + var from_format = typeof date; + var $this = $(this); + + if(from_format == desired_format) { + if(from_format == 'object') { + try { + date.getTime(); + } catch (e) { + $.error('Received date is in a non supported format!'); + return false; + } + } + return date; + } + + if(typeof date == 'undefined') date = new Date(0); + + if(desired_format != 'string' && desired_format != 'object' && desired_format != 'number') + $.error('Date format "'+ desired_format +'" not supported!'); + + if(!dateFormat) { + // thanks to bibendus83 -> http://sourceforge.net/tracker/index.php?func=detail&aid=3213174&group_id=358205&atid=1495382 + var dp_dateFormat = $this.datepicker('option', 'dateFormat'); + if (dp_dateFormat) { + dateFormat = dp_dateFormat; + } else { + dateFormat = $.datepicker._defaults.dateFormat; + } + } + + // converts to object as a neutral format + switch(from_format) { + case 'object': break; + case 'string': date = $.datepicker.parseDate(dateFormat, date); break; + case 'number': date = new Date(date); break; + default: $.error('Conversion from "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker'); + } + // then converts to the desired format + switch(desired_format) { + case 'object': return date; + case 'string': return $.datepicker.formatDate(dateFormat, date); + case 'number': return date.getTime(); + default: $.error('Conversion to "'+ desired_format +'" format not allowed on jQuery.multiDatesPicker'); + } + return false; + }, + gotDate : function( date, type ) { + if(!type) type = 'picked'; + for(var i = 0; i < this.multiDatesPicker.dates[type].length; i++) { + if(methods.compareDates.call(this, this.multiDatesPicker.dates[type][i], date) === 0) { + return i; + } + } + return false; + }, + value : function( value ) { + if(value && typeof value == 'string') { + methods.addDates.call(this, value.split(this.multiDatesPicker.separator)); + } else { + var dates = methods.getDates.call(this, 'string'); + return dates.length + ? dates.join(this.multiDatesPicker.separator) + : ""; + } + }, + getDates : function( format, type ) { + if(!format) format = 'string'; + if(!type) type = 'picked'; + switch (format) { + case 'object': + return this.multiDatesPicker.dates[type]; + case 'string': + case 'number': + var o_dates = new Array(); + for(var i in this.multiDatesPicker.dates[type]) + o_dates.push( + dateConvert.call( + this, + this.multiDatesPicker.dates[type][i], + format + ) + ); + return o_dates; + + default: $.error('Format "'+format+'" not supported!'); + } + }, + getFormattedDates : function( format ) { + var dates = methods.getDates.call(this, 'object'); + if(!dates.length) return ''; + var formatted = $.map(dates, function(date, i) { + return $.datepicker.formatDate(format, date); + }).join(this.multiDatesPicker.separator); + + return formatted; + }, + addDates : function( dates, type ) { + if(dates.length > 0) { + if(!type) type = 'picked'; + switch(typeof dates) { + case 'object': + case 'array': + if(dates.length) { + for(var i = 0; i < dates.length; i++) + addDate.call(this, dates[i], type, true); + sortDates.call(this, type); + break; + } // else does the same as 'string' + case 'string': + case 'number': + addDate.call(this, dates, type); + break; + default: + $.error('Date format "'+ typeof dates +'" not allowed on jQuery.multiDatesPicker'); + } + //$(this).datepicker('refresh'); + } else { + $.error('Empty array of dates received.'); + } + }, + addFormattedDates : function( dates, format ) { + if(!$.isArray(dates)) { + $.error('Element 0 of addFormattedDates parameter must be an array of string'); + } + if(dates.length > 0) { + for(var i = 0; i < dates.length; i++) + addDate.call(this, $.datepicker.parseDate(format, dates[i]), 'picked', true); + sortDates.call(this, 'picked'); + } else { + $.error('Empty array of dates received.'); + } + }, + removeDates : function( dates, type ) { + if(!type) type = 'picked'; + var removed = []; + if (Object.prototype.toString.call(dates) === '[object Array]') { + for(var i in dates.sort(function(a,b){return b-a})) { + removed.push(removeDate.call(this, dates[i], type)); + } + } else { + removed.push(removeDate.call(this, dates, type)); + } + return removed; + }, + removeIndexes : function( indexes, type ) { + if(!type) type = 'picked'; + var removed = []; + if (Object.prototype.toString.call(indexes) === '[object Array]') { + for(var i in indexes.sort(function(a,b){return b-a})) { + removed.push(removeIndex.call(this, indexes[i], type)); + } + } else { + removed.push(removeIndex.call(this, indexes, type)); + } + return removed; + }, + resetDates : function ( type ) { + if(!type) type = 'picked'; + this.multiDatesPicker.dates[type] = []; + }, + toggleDate : function( date, type ) { + if(!type) type = 'picked'; + + switch(this.multiDatesPicker.mode) { + case 'daysRange': + this.multiDatesPicker.dates[type] = []; // deletes all picked/disabled dates + var end = this.multiDatesPicker.autoselectRange[1]; + var begin = this.multiDatesPicker.autoselectRange[0]; + if(end < begin) { // switch + end = this.multiDatesPicker.autoselectRange[0]; + begin = this.multiDatesPicker.autoselectRange[1]; + } + for(var i = begin; i < end; i++) + methods.addDates.call(this, methods.sumDays.call(this,date, i), type); + break; + default: + if(methods.gotDate.call(this, date) === false) // adds dates + methods.addDates.call(this, date, type); + else // removes dates + methods.removeDates.call(this, date, type); + break; + } + }, + setMode : function( options ) { + var $this = $(this); + if(options.mode) this.multiDatesPicker.mode = options.mode; + + switch(this.multiDatesPicker.mode) { + case 'normal': + for(option in options) + switch(option) { + case 'maxPicks': + case 'minPicks': + case 'pickableRange': + case 'adjustRangeToDisabled': + this.multiDatesPicker[option] = options[option]; + break; + //default: $.error('Option ' + option + ' ignored for mode "'.options.mode.'".'); + } + break; + case 'daysRange': + case 'weeksRange': + var mandatory = 1; + for(option in options) + switch(option) { + case 'autoselectRange': + mandatory--; + case 'pickableRange': + case 'adjustRangeToDisabled': + this.multiDatesPicker[option] = options[option]; + break; + //default: $.error('Option ' + option + ' does not exist for setMode on jQuery.multiDatesPicker'); + } + if(mandatory > 0) $.error('Some mandatory options not specified!'); + break; + } + + /* + if(options.pickableRange) { + $this.datepicker("option", "maxDate", options.pickableRange); + $this.datepicker("option", "minDate", this.multiDatesPicker.minDate); + } + */ + + if(mdp_events.onSelect) + mdp_events.onSelect(); + }, + destroy: function(){ + this.multiDatesPicker = null; + $(this).datepicker('destroy'); + } + }; + + this.each(function() { + var $this = $(this); + if (!this.multiDatesPicker) { + this.multiDatesPicker = { + dates: { + picked: [], + disabled: [] + }, + mode: 'normal', + adjustRangeToDisabled: true + }; + } + + if(methods[method]) { + var exec_result = methods[method].apply(this, Array.prototype.slice.call(mdp_arguments, 1)); + switch(method) { + case 'removeDates': + case 'removeIndexes': + case 'resetDates': + case 'toggleDate': + case 'addDates': + var altField = $this.datepicker('option', 'altField'); + // @todo: should use altFormat for altField + var dates_string = methods.value.call(this); + if (altField !== undefined && altField != "") { + $(altField).val(dates_string); + } + $this.val(dates_string); + + $.datepicker._refreshDatepicker(this); + } + switch(method) { + case 'removeDates': + case 'getDates': + case 'getFormattedDates': + case 'gotDate': + case 'sumDays': + case 'compareDates': + case 'dateConvert': + case 'value': + ret = exec_result; + } + return exec_result; + } else if( typeof method === 'object' || ! method ) { + return methods.init.apply(this, mdp_arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.multiDatesPicker'); + } + return false; + }); + + return ret; + }; - $.multiDatesPicker = {version: false}; - //$.multiDatesPicker = new MultiDatesPicker(); // singleton instance - $.multiDatesPicker.initialized = false; - $.multiDatesPicker.uuid = new Date().getTime(); - $.multiDatesPicker.version = $.ui.multiDatesPicker.version; - - // allows MDP not to hide everytime a date is picked - $.multiDatesPicker._hideDatepicker = $.datepicker._hideDatepicker; - $.datepicker._hideDatepicker = function(){ - var target = this._curInst.input[0]; - var mdp = target.multiDatesPicker; - if(!mdp || (this._curInst.inline === false && !mdp.changed)) { - return $.multiDatesPicker._hideDatepicker.apply(this, arguments); - } else { - mdp.changed = false; - $.datepicker._refreshDatepicker(target); - return; - } - }; + var PROP_NAME = 'multiDatesPicker'; + var dpuuid = new Date().getTime(); + var instActive; - // Workaround for #4055 - // Add another global to avoid noConflict issues with inline event handlers - window['DP_jQuery_' + dpuuid] = $; + $.multiDatesPicker = {version: false}; + //$.multiDatesPicker = new MultiDatesPicker(); // singleton instance + $.multiDatesPicker.initialized = false; + $.multiDatesPicker.uuid = new Date().getTime(); + $.multiDatesPicker.version = $.ui.multiDatesPicker.version; + + // allows MDP not to hide everytime a date is picked + $.multiDatesPicker._hideDatepicker = $.datepicker._hideDatepicker; + $.datepicker._hideDatepicker = function(){ + var target = this._curInst.input[0]; + var mdp = target.multiDatesPicker; + if(!mdp || (this._curInst.inline === false && !mdp.changed)) { + return $.multiDatesPicker._hideDatepicker.apply(this, arguments); + } else { + mdp.changed = false; + $.datepicker._refreshDatepicker(target); + return; + } + }; + + // Workaround for #4055 + // Add another global to avoid noConflict issues with inline event handlers + window['DP_jQuery_' + dpuuid] = $; })( jQuery ); \ No newline at end of file