5

I want to be able to link multiple pairs of jQuery UI datepicker instances so that the second one in each pair can't select a date earlier than the first. I'm following this example to get started.

Example:

<ul>
<li>
<input class="counter" name="counter" type="hidden" value="43"/>
<label>Start: </label><input name="start_43" id="start_43" size="10" />
<label>End: </label><input name="end_43" id="end_43" size="10" />
</li>

<li>
<input class="counter" name="counter" type="hidden" value="44"/>
<label>Start: </label><input name="start_44" id="start_44" size="10" />
<label>End: </label><input name="end_44" id="end_44" size="10" />
</li>
</ul>

I'm looping over the instances by finding the "counter" number:

$(document).ready(function() {
    var starts = $("input[name='counter']");
    var dates = new Array();
    starts.each(function(){
        var x = this.value;
        // http://jqueryui.com/demos/datepicker/#date-range
        dates[x] = $( "#start_"+x+", #end_"+x ).datepicker({
            onSelect: function( selectedDate ) {
            var option = this.id == "#start_"+x ? "minDate" : "maxDate",
            instance = $( this ).data( "datepicker" );
            date = $.datepicker.parseDate(
            instance.settings.dateFormat ||
            $.datepicker._defaults.dateFormat,
            selectedDate, instance.settings );
            dates[x].not( this ).datepicker( "option", option, date );
            }
        });
    });
});

This works to enable a datepicker on each input but it doesn't prevent the second instance from choosing a date before the first. In fact it requires that the second instance choose a date before the first. When selected, the second instance populates both inputs!

Can anyone see where I'm going wrong?

2 Answers 2

5

I'm not 100% about what the parseDate is for, or why you're retrieving the instance from the datastore. However, I believe your primary problem is the this.id test. IDs never start with # in the actual DOM element.

onSelect: function(selectedDate) {
    var option = this.id.indexOf("start_") != -1 ? "minDate" : "maxDate";
    dates[i].not(this).datepicker("option", option, selectedDate);
}

The above should do it, or you could just take the hash out of your code probably (which I just did and seems to work fine). :]

Sign up to request clarification or add additional context in comments.

3 Comments

@oleonard Just to be clear, all you have to do is change the following line, removing the hash in front of the word start: var option = this.id == "start_"+x ? "minDate" : "maxDate"
Ah, you're exactly right! I didn't realize that "#" had snuck in. Now it works correctly. Thanks for the extra set of eyes!
@oleonard I know exactly what you mean. My team lead was staring at something for about a half hour when I suggested he should really let me see if a second head might help reveal the problem. "I don't see a scope for this variable. Did you forget to type 's dot'?" Problem solved!
0

This will work

$("#FirstCal").datepicker({
        dateFormat: 'M d, yy',
        navigationAsDateFormat: true, prevText: 'M', nextText: 'M',
        changeMonth: true,
        changeYear: true,
        showOn: "both",
        showStatus: true,
        firstDay: 0,
        changeFirstDay: false,
        beforeShow: customRange,
        buttonImage: '/Content/images/Calendar_img.png',
        buttonImageOnly: true
    });

    $("#secondCal").datepicker({
        dateFormat: 'M d, yy',
        navigationAsDateFormat: true, prevText: 'M', nextText: 'M',
        changeMonth: true,
        changeYear: true,
        showOn: "both",
        showStatus: true,
        firstDay: 0,
        changeFirstDay: false,
        beforeShow: customRange,
        buttonImage: '/Content/images/Calendar_img.png',
        buttonImageOnly: true
    });

function customRange(input) {
    var min = new Date();
    var min = new Date('<%=DateTime.Now.Year %>', '0', '1');
    var max = new Date('<%=DateTime.Now.AddYears(1).Year %>', '11', '31');

    var dateMin = min;
    var dateMax = max;

    if (input.id == "firstCal" && $("#secondCal").datepicker("getDate") != null) {
        if (dateMin < min) {
            dateMin = min;
        }
    }
    else if (input.id == "secondCal") {
        if ($("#firstCal").datepicker("getDate") != null) {
            dateMin = $("#firstCal").datepicker("getDate");
        }
    }
    return {
        minDate: dateMin,
        maxDate: dateMax
    };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.