jQuery datePicker demo: limit available dates

< date picker home

The following example demonstrates how you can limit the available dates for clicking on the calendar based on the values in a dropdown.

It also demonstrates how you can add behaviour to the date picker so that when a date is rolled over the following X days are also highlighted.

Step 1: Choose Duration of stay

Underlying rules

  • 3 nights must start on a Friday
  • 5 nights must start on a Monday
  • 7 nights must start on a Saturday

Step 2: Choose a holiday start date

Page sourcecode

$(function()
{
    $durationRules = $('#durationRules');
    $datePicker = $('#datePicker');
    
    var allowedDay;
    var numNights;

    $datePicker.datePicker(
        {
            renderCallback:function ($td, thisDate, month, year)
            {
                var alreadyDisabled = $td.is('.disabled');
                if (allowedDay && thisDate.getDay() != allowedDay && !alreadyDisabled) {
                    // the disabled class prevents the user from being able to select the element.
                    // the disallowed-day class provides a hook for different CSS styling of cells which are disabled 
                    // by this rule vs cells which are disabled because e.g. they fall outside the startDate - endDate range.
                    $td.addClass('disabled disallowed-day');
                } else if (!alreadyDisabled) {    // only add the highlight class if the date wasn't already for some 
                                                // reason disabled (e.g. it is outside the startDate - endDate range)
                    $td.addClass('highlight');
                    
                    // we also want to highlight the other related days when you roll over the relevant date
                    var $allTDs = $('td', $td.parent().parent());
                    var td = $td[0];

                    for (var i=0; i<$allTDs.length; i++) {
                        if ($allTDs[i] == td) {
                            break;
                        }
                    }
                    var includedNightCells = [];
                    for (var j=i; j < i+numNights; j++) {
                        includedNightCells.push($allTDs[j]);
                    }
                    var $includedNightCells = $(includedNightCells)    ;

                    $td.hover(
                        function()
                        {
                            $includedNightCells.addClass('included-night');
                        },
                        function()
                        {
                            $allTDs.removeClass('included-night');
                        }
                    );
                }
            }
        }
    );

    $durationRules.bind(
        'change', 
        function()
        {
            var rules = $durationRules.val().split(',');
            numNights = parseInt(rules[0]);
            allowedDay = parseInt(rules[1]);

            // if the current selected date is illegal via the new rules then remove it...
            if (Date.fromString($datePicker.val()).getDay() != allowedDay) {
                $datePicker.val('');
            }

        }
    ).trigger('change');
    
    // add a listener for the form submit for this demo to illustrate that the date field on the form is being sucessfully set
    $('#chooseDateForm').bind(
        'submit',
        function()
        {
            var v = $datePicker.val();
            alert(v == '' ? 'You didn\'t select a date' : 'You selected ' + v);
            return false;
        }
    );
});

Page extra CSS

table.jCalendar td
{
    border: 1px solid;
    padding: 3px 4px;
}
table.jCalendar td.disabled
{
    border: 1px solid #bbb;
}
table.jCalendar td.highlight,
table.jCalendar td.other-month.highlight
{
    background: #dd6;
    color: #000;
    border: 1px solid #dd6;
}
table.jCalendar td.highlight.dp-hover
{
    background: #ee0;
    border: 1px solid #000;
}
table.jCalendar td.selected,
table.jCalendar td.selected.other-month,
table.jCalendar td.selected.dp-hover
{
    background: #ff0;
    color: #000;
    border: 1px solid #000;
}
/** 
 * Deal with the fact that all days are now disabled but we want to be able to visually 
 * differentiate between dates that are disabled because they are the wrong day of the
 * week and dates disabled for another reason...
 **/
table.jCalendar td.disallowed-day,
table.jCalendar td.disallowed-day.dp-hover
{
    background: #ccc;
    border: 1px solid #ccc;
    color: #000;
}
table.jCalendar td.disallowed-day.other-month
{
    background: #ddd;
    border: 1px solid #ddd;
}
table.jCalendar td.included-night,
table.jCalendar td.other-month.included-night
{
    border: 1px solid #ee0; 
    background: #ee0;
}

div.step
{
    overflow: hidden;
}