Date range validation example

by Yure Pereira

HTML

<form id="myform">
    <input type="text" name="startDate" id="startDate" class="validDate" />
    <br/>
    <input type="text" name="endDate" id="endDate" class="validDate" />
    <br/>
    <input type="submit" />
</form>

CSS

.error {
    background:#fcc;
}

JavaScript

$(function () {
    // simple date mm/dd/yyyy format
    $.validator.addMethod('validDate', function (value, element) {
        return this.optional(element) || /^(0?[1-9]|1[012])[ /](0?[1-9]|[12][0-9]|3[01])[ /][0-9]{4}$/.test(value);
    }, 'Please provide a date in the mm/dd/yyyy format');

    $.validator.addMethod('dateBefore', function (value, element, params) {
        // if end date is valid, validate it as well
        var end = $(params);
        if (!end.data('validation.running')) {
            $(element).data('validation.running', true);
            // The validator internally keeps track of which element is being validated currently.  This ensures that validating 'end' will not trample 'start'
            // see http://stackoverflow.com/questions/22107742/jquery-validation-date-range-issue
            setTimeout($.proxy(

            function () {
                this.element(end);
            }, this), 0);
            // Ensure clearing the 'flag' happens after the validation of 'end' to prevent endless looping
            setTimeout(function () {
                $(element).data('validation.running', false);
            }, 0);
        }
        return this.optional(element) || this.optional(end[0]) || new Date(value) < new Date(end.val());

    }, 'Must be before corresponding end date');

    $.validator.addMethod('dateAfter', function (value, element, params) {
        // if start date is valid, validate it as well
        var start = $(params);
        if (!start.data('validation.running')) {
            $(element).data('validation.running', true);
            setTimeout($.proxy(

            function () {
                this.element(start);
            }, this), 0);
            setTimeout(function () {
                $(element).data('validation.running', false);
            }, 0);
        }
        return this.optional(element) || this.optional(start[0]) || new Date(value) > new Date($(params).val());

    }, 'Must be after corresponding...