# MultiDatesPicker for jQuery UI

MDP is a little plugin that enables jQuery UI calendar to manage multiple dates with the following features:

- Select date ranges.
- Pick multiple dates not in secuence.
- Define a maximum number of pickable dates.
- Define a range X days from where it is possible to select Y dates.
- Define unavailable dates.

Tweet

## Download

Download from SourceForge.

## Bugs or features request?

Please use one of the following links:

- GitHub Issues

## How to use it

Being an extension to jQuery UI DatePicker you need to include both jQuery and jQuery UI (with datepicker module included!) javascript files to your HTML page, and right after that, include MultiDatesPicker.

To apply it to an element, do it the same way as you would do with jQuery UI datepicker, but write multiDatesPicker instead of datepicker:
`$(element_or_selector).multiDatesPicker(options_to_initialize_datepicker_and_multidatepicker);`

### MultiDatesPicker specific options

- #### addDates

  Adds an array of dates specified in a string, milliseconds or javascript date object format.
  NOTE: the string format you should pass to multiDatePicker depends on the localization of datepicker, see this page for more infos on how to configure it.

- #### addDisabledDates

  Disables an array of dates specified in a string, milliseconds or javascript date object format.
  NOTE: the string format you should pass to multiDatePicker depends on the localization of datepicker, see this page for more infos on how to configure it.

- #### separator

  Allows to specify a custom separator for the string representation of the dates selected (defaults ", ").

- #### mode

  Allows to enable a different MDP modes: 'normal' (default) or 'daysRange'.

  #### normal mode options

  - #### maxPicks

    Number of dates allowed to be selected (see demo).

  - #### pickableRange

    Limits the range of dates available for selection to a certain number of days from the first selection (see demo).

  - #### adjustRangeToDisabled

    A boolean that allows to maintain the number of pickable days even in case there are disabled days within the range specified in 'pickableRange'.
    See the corresponding demo and try toggling this flag to see the results.

  #### daysRange mode options

  - #### autoselectRange

    Array of two integers: the first sets the beginning of the range relative to the date clicked on; the last sets the end of the range. Both numbers may be negative (see demo).

### Available methods:

- #### compareDates( date1, date2 )

  Compares two dates returning 1, 0 or -1 if date2 is greater, equal or smaller than date1 respectively.

- #### gotDate( date, type )

  Returns the index of the date in the dates array, or false in case that date is not found.
  The parameter dates can be a string or a date object.

  Example: `$('#simpliest-usage').multiDatesPicker('gotDate', new Date());`

- #### addDates( dates, type )

  Adds one or more dates to the calendar.
  The parameter dates can be a string, a date object or an array (of strings or javascript date objects).

  Example adding today: `$('#simpliest-usage').multiDatesPicker('addDates', new Date());`

- #### removeIndexes( indexes, type )

  Removes one or more dates from the dates array using their indexes.
  The parameter indexes can be an integer or an array of integers.

  Example removing first date: `$('#simpliest-usage').multiDatesPicker('removeIndexes', 0);`

- #### removeDates( dates, type )

  Removes one or more dates from the dates array using their dates.
  The parameter dates can be a single value or an array of milliseconds, strings or date object.

  Example removing today date: `$('#simpliest-usage').multiDatesPicker('removeDates', new Date());`

- #### resetDates( type )

  Removes all dates.
  The array of dates to reset can be of type 'picked' (default) or 'disabled'.

  Example resetting disabled dates: `$('#simpliest-usage').multiDatesPicker('resetDates', 'disabled');`

- #### toggleDate( date, type )

  Adds/removes a single date from the calendar.
  The date can be passed as string or as javascript date object.

  Example toggling today: `$('#simpliest-usage').multiDatesPicker('toggleDate', new Date());`

- #### getDates( format, type )

  Retrives the array of dates associated with the multiDatesPicker in the specified format: "string" (default) for localized string format, or "object" for javascript date object format.

  Example: `var dates = $('#simpliest-usage').multiDatesPicker('getDates');`

- #### value( string )

  If no parameter is passed, returns the string value that would be used in input elements. Otherwise parses the string for dates to add.

  Get Example: `var dates = $('#simpliest-usage').multiDatesPicker('value');`

  Set Example: `$('#simpliest-usage').multiDatesPicker('value', '2/19/1985, 11/14/2009');`

- #### destroy()

  Destroys the MDP and Datepicker instances on the element.

  Example: `$('#simpliest-usage').multiDatesPicker('destroy');`

## Use cases

You can find MDP implemented in the following sites:

- avisooportunoexpress.mx
  A Mexican website developed by me, aimed to sell advertisements on El Universal CPN mexican newspaper products.

If you're using MDP in your site and would like to share it, simply contact me. You'd get free ad from here and we get more examples of implementation from you :)

## Demos

Here are some demos for you to understand how it works and what you can obtain with it.
To see how it is implemented simply check the source code of this page: I've tried to keep the code simple and clear :)

- ### Simplest usage

  Just apply the plugin to an HTML element and you're ready to select multiple dates :)

  #### Code used

      $('#simpliest-usage').multiDatesPicker();

- ### Custom date format

  Same as previous example, but using custom date formats and custom default day.

  #### Code used

      $('#custom-date-format').multiDatesPicker({
      	dateFormat: "y-m-d",
      	defaultDate:"85-2-19"
      });

- ### Pre-select dates

  The name says it all: you can preselect some dates specifying them in an array.
  Dates in the array can be a mix of object date and string dates.

  In this example we've preselected the 14th and 19th of the current month.

  #### Code used

      var date = new Date();
      $('#pre-select-dates').multiDatesPicker({
      	addDates: [date.setDate(14), date.setDate(19)]
      });

- ### Disable dates

  Again, the name says it all: you can specify some dates to disable.
  Dates in the array can be a mix of object date and string dates.

  In this example are disabled the first and third day of the current month.

  #### Code used

      var today = new Date();
      $('#disable-dates').multiDatesPicker({
      	addDisabledDates: [today.setDate(1), today.setDate(3)]
      });

- ### Disable calendar

  Disable a calendar picking functionality.

  Today and tomorrow are selected just to show how selected dates looks in a disabled calendar.

  #### Code used

      var today = new Date();
      var tomorrow = (new Date()).setDate(today.getDate()+1);
      $('#disable-calendar').multiDatesPicker({
      	disabled: true,
      	addDates: [today, tomorrow]
      });

- ### Custom methods

  Define 'beforeShow', 'beforeShowDay'*, 'onSelect' and 'onClose' to apply custom behaviours.

  * Being that MDP needs 'beforeShowDay' method to change the way jQuery datepicker behaves, there may be cases in which your custom definition in MDP won't produce the same effects as if you were using it with datepicker alone.
  Note that, disabling dates using 'beforeShowDay' will produce undesired results with MDP functionalities that involves ranges, because MDP will still consider those dates as available.

  #### Code used

      $('#custom-methods').multiDatesPicker({
      	beforeShowDay: $.datepicker.noWeekends
      });

- ### Using altField

  A way to have a calendar always displayed and a field that fills with selected dates.

  I've placed two days in the 'value' attribute of the altField just to test out how those are automatically added to the calendar.

  #### Code used

      $('#with-altField').multiDatesPicker({
      	altField: '#altField'
      });

- ### Set maximum picks

  Set the maximum number of dates that can be picked.

  #### Code used

      $('#maxPicks').multiDatesPicker({
      	maxPicks: 2
      });

- ### Use pickableRange and adjustRangeToDisabled

  Define a range of dates to be allowed after the first date have been picked.
  Some dates have been disabled to allow testing of adjustRangeToDisabled.

  #### Code used

      var date = new Date();
      $('#pickableRange').multiDatesPicker({
      	pickableRange: 7,
      	adjustRangeToDisabled: true,
      	addDisabledDates: [date.setDate(10), date.setDate(15)]
      });

- ### Days Range Mode: Auto Select Range

  This way you can automatically select a range of days with respect to the day clicked.

  In this example the day range is set to [0, 5], which means from the day clicked to 5 days in advance.
  You can also specify other combinations like:

  - [-1,2] from a day before to two days after the clicked day
  - [1,3] from the day after to three days after the clicked day
  - ...

  #### Code used

      $('#simple-select-days-range').multiDatesPicker({
      	mode: 'daysRange',
      	autoselectRange: [0,5]
      });

- ### Min and Max date

  As with the jQuery Datespicker, you can define a minimum and maximum date from where to pick dates.
  The values are relative to the current date.

  In this example the minimum day is set to today and the maximum to 30 days from now.

  #### Code used

      var today = new Date();
      $('#simple-select-min-max').multiDatesPicker({
      	minDate: 0,
      	maxDate: 30
      });

- ### From input

  Just an example of how it would work with an input text field.

  I've placed two days in the 'value' attribute of the altField just to test out how those are automatically added to the calendar.

  #### Code used

      $('#from-input').multiDatesPicker();

- ### Full year

  Just an example of how it would look to show the full year.

  #### Code used

      var today = new Date();
      var y = today.getFullYear();
      $('#full-year').multiDatesPicker({
      	addDates: ['10/14/'+y, '02/19/'+y, '01/14/'+y, '11/16/'+y],
      	numberOfMonths: [3,4],
      	defaultDate: '1/1/'+y
      });

## Tips

- To avoid the ugly jitter effect for picked dates, you can add the following code to your css:

      /* begin: jQuery UI Datepicker moving pixels fix */
      	table.ui-datepicker-calendar {border-collapse: separate;}
      	.ui-datepicker-calendar td {border: 1px solid transparent;}
      /* end: jQuery UI Datepicker moving pixels fix */

- To add emphasis to the selected dates, you can add the following code to your css:

      /* begin: jQuery UI Datepicker emphasis on selected dates */
      .ui-datepicker .ui-datepicker-calendar .ui-state-highlight a {
      	background: #743620 none; /* a color that fits the widget theme */
      	color: white; /* a color that is readeable with the color above */
      }
      /* end: jQuery UI Datepicker emphasis on selected dates */

To even further customize the way the calendar looks, just modify the jQuery UI's theme you're using.
Multiple Dates Picker is about adding functionality not style :)

## Things pending

Apart from some features and bug fixes, there is need for a better documentation and a unit-test to guarantee that any improvements won't break the existent functionalities.

I'll try to maintain this project in my spare time (it is not my primary business), and I welcome anyone who wants to help (just contact me :)

## Contact me

You're welcome to get in touch with me to collaborate to this project:

- luca.lauretta.info please do not email me for support or bug reporting, use the report section instead.