validation

validation

I created a test page for using the validate plugin and date picker. Everything works great except for one test case.

I have a required field which is a date. If I go in and enter a bunch of numbers I get one of my error messages. If I go to another field and return to the field with the error, the datepicker pops up. If I select a date, I now see I have a valid date, however if I leave by tabbing the error message still shows. If I change the value by hand it works correctly.  

How can I force validation to occur from the datepicker?

My sample is a mix of old javascript code not nicely done up in the style of jquery. But its worked for years

My sample:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>New Web Project</title>
        <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js" type="text/javascript">
        </script>
        <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript">
        </script>
        <script src="http://jquery-ui.googlecode.com/svn/trunk/ui/i18n/jquery.ui.datepicker-fr.js" type="text/javascript">
        </script>
        <script src="http://ajax.microsoft.com/ajax/jquery.validate/1.6/jquery.validate.min.js" type="text/javascript">
        </script>
        <link REL="StyleSheet" HREF="lib/test.css" TYPE="text/css">
    </head>
    <body>
        <form action="index.html" id="myform">
            <script type="text/javascript">
                
                $.validator.setDefaults({
                    submitHandler: function(){
                        alert("submitted!");
                    }
                });
                
                $(document).ready(function(){
                    // Handler for .ready() called.
                    window.onbeforeunload = confirmExit;
                    
                    var isdirty = false;
                    
                    //$( ".selector" ).datepicker( "option", "buttonImage", '/images/datepicker.gif' );                   
                    $.datepicker.setDefaults($.datepicker.regional['']);
                    //$.datepicker.setDefaults($.datepicker.regional['fr']);
                    
                    $.datepicker.setDefaults({
                        // showOn: 'both',
                        gotoCurrent: true,
                        dateFormat: 'yy-mm-dd',
                        autoSize: true,
                        numberOfMonths: 2,
                        // buttonImageOnly: true,
                        changeYear: true,
                        changeMonth: true
                        // buttonImage: 'images/icon_calendar.gif',
                        //regional: 'fr'
                        //regional: ''
                    });
                    
                    $('input.datepicker').datepicker();
                    
                    jQuery.validator.addMethod("gooddate", function(value, element, params){
                        return isValidDate2(value);
                    }, jQuery.format("Please enter a valid date"));
                    
                    
                    $(function(){
                        var dates = $('#from, #to').datepicker({
                            onSelect: function(selectedDate){
                                var option = this.id == dates[0].id ? "minDate" : "maxDate";
                                var instance = $(this).data("datepicker");
                                var date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
                                dates.not(this).datepicker("option", option, date);
                            }
                        });
                    });
                    
                    $("#myform").validate({
                        rules: {
                            xx: {
                                dateISO: true,
                                minlength: 8,
                                gooddate: true
                            }
                        },
                        messages: {
                            xx: {
                                dateISO: '* Date format is YYYY-MM-DD',
                                minlength: 'Dates need at least 8 characters'
                            },
                            errorPlacement: function(error, element){
                                error.insertAfter(element);
                            },
                            debug: true
                        }
                    });
                    
                    
                });
                
                function markDirty(){
                    isdirty = true;
                }
                
                
                function confirmExit(e){
                    if (!e) {
                        e = window.event;
                    }
                    if (isdirty === false) {
                        e = window.event;
                    }
                    
                    //e.cancelBubble is supported by IE - this will kill the bubbling process.
                    e.cancelBubble = true;
                    e.returnValue = 'You sure you want to leave?'; //This is displayed on the dialog
                    //e.stopPropagation works in Firefox.
                    if (e.stopPropagation) {
                        e.stopPropagation();
                        e.preventDefault();
                    }
                }
                
                // My date validation function
                function isValidDate2(value){
                    var sdt = value.split(" ");
                    var userDate = sdt[0];
                    // Checks for the following valid date formats:
                    
                    // Also separates date into month, day, and year variables
                    // MM/DD/YY   MM/DD/YYYY   MM-DD-YY   MM-DD-YYYY
                    //var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;
                    
                    // YYYY-MM-DD, YYYY/MM/DD, YYYY.MM.DD
                    // To require a 4 digit year entry, use this line instead:
                    var datePat = /^(\d{4})(\/|-|.|\s|\\)(\d{1,2})\2(\d{1,2})$/;
                    var result = true;
                    
                    var matchArray = userDate.match(datePat); // is the format ok?
                    if (matchArray === null) {
                        //alert("Date is not in a valid format.");
                        result = false;
                    }
                    
                    try {
                        month = matchArray[3]; // parse date into variables
                    } 
                    catch (err) {
                        month = 0;
                    }
                    try {
                        day = matchArray[4];
                    } 
                    catch (err) {
                        day = 0;
                    }
                    try {
                        year = matchArray[1];
                    } 
                    catch (err) {
                        year = 0;
                    }
                    
                    if (month < 1 || month > 12) { // check month range
                        result = false;
                    }
                    if (day < 1 || day > 31) {
                        result = false;
                    }
                    if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
                        result = false;
                    }
                    if (month == 2) { // check for february 29th
                        var isleap = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0));
                        if (day > 29 || (day == 29 && !isleap)) {
                            result = false;
                        }
                    }
                    if (result === true && userDate.length > 0) {
                        result = isDate(userDate);
                    }
                    return result;
                }
                
                // existing function from aansims
                var dtCh = "-";
                var minYear = 1900;
                var maxYear = 2100;
                
                function isDate(dtStr){
                    var daysInMonth = DaysArray(12);
                    var pos1 = dtStr.indexOf(dtCh);
                    var pos2 = dtStr.indexOf(dtCh, pos1 + 1);
                    
                    var strMonth = dtStr.substring(pos1 + 1, pos2);
                    var strDay = dtStr.substring(pos2 + 1);
                    var strYear = dtStr.substring(0, pos1);
                    
                    strYr = strYear;
                    if (strDay.charAt(0) == "0" && strDay.length > 1) {
                        strDay = strDay.substring(1);
                    }
                    if (strMonth.charAt(0) == "0" && strMonth.length > 1) {
                        strMonth = strMonth.substring(1);
                    }
                    for (var i = 1; i <= 3; i++) {
                        if (strYr.charAt(0) == "0" && strYr.length > 1) {
                            strYr = strYr.substring(1);
                        }
                    }
                    month = parseInt(strMonth, 10);
                    day = parseInt(strDay, 10);
                    year = parseInt(strYr, 10);
                    if (pos1 == -1 || pos2 == -1) {
                        return false;
                    }
                    if (strMonth.length < 1 || month < 1 || month > 12) {
                        return false;
                    }
                    if (strDay.length < 1 || day < 1 || day > 31 || (month == 2 && day > daysInFebruary(year)) || day > daysInMonth[month]) {
                        return false;
                    }
                    if (strYear.length != 4 || year === 0 || year < minYear || year > maxYear) {
                        return false;
                    }
                    if (dtStr.indexOf(dtCh, pos2 + 1) !== -1 || isInteger(stripCharsInBag(dtStr, dtCh)) === false) {
                        return false;
                    }
                    return true;
                }
                
                function daysInFebruary(year){
                    // February has 29 days in any year evenly divisible by four,
                    // EXCEPT for centurial years which are not also divisible by 400.
                    return (((year % 4 === 0) && ((!(year % 100 === 0)) || (year % 400 === 0))) ? 29 : 28);
                }
                
                function DaysArray(n){
                    for (var i = 1; i <= n; i++) {
                        this[i] = 31;
                        if (i == 4 || i == 6 || i == 9 || i == 11) {
                            this[i] = 30;
                        }
                        if (i == 2) {
                            this[i] = 29;
                        }
                    }
                    return this;
                }
                
                function isInteger(s){
                    var i;
                    for (i = 0; i < s.length; i++) {
                        // Check that current character is number.
                        var c = s.charAt(i);
                        if (((c < "0") || (c > "9"))) {
                            return false;
                        }
                    }
                    // All characters are numbers.
                    return true;
                }
                
                function stripCharsInBag(s, bag){
                    var i;
                    var returnString = "";
                    // Search through string's characters one by one.
                    // If character is not in bag, append to returnString.
                    for (i = 0; i < s.length; i++) {
                        var c = s.charAt(i);
                        if (bag.indexOf(c) == -1) {
                            returnString += c;
                        }
                    }
                    return returnString;
                }
            </script>
            <h1>New Web Project Page</h1>
            <h2>Single Date</h2>
            <div>
                <input id="singledate" class="datepicker" type="text" maxlength="10" onchange="markDirty();">
            </div>
            <br/>
            <select>
                <option value="volvo">Volvo</option>
                <option value="saab">Saab</option>
                <option value="mercedes">Mercedes</option>
                <option value="audi">Audi</option>
            </select>
            <h2>Simple text</h2>
            <input id="mytb" type="text" onchange="markDirty();"><h2>Default Date</h2>
            <h2>Single Date Read only</h2>
            <input id="singledate2" type="text" class="datepicker" maxlength="10" value="1963-01-05" disabled="true" onchange="markDirty();"><h2>Default Date</h2>
            <input id="singledate3" type="text" class="datepicker" maxlength="10" value="2009-09-29" onchange="markDirty();"><h2>Required date</h2>
            <input id="singledate4" type="text" class="datepicker" name="xx" title="Invalid Date" maxlength="10" onchange="markDirty();"><h2>Date Range</h2>
            <div>
                <input type="text" maxlength="10" id="from" onchange="markDirty();">to <input type="text" id="to" maxlength="10" onchange="markDirty();">
            </div><h2>Exit tests</h2>
            <a href="http://www.adga.ca">ADGA</a>
            <input type="submit" value="test" />
        </form>
    </body>
</html>