Jquery datepicker popup not closing on select date in IE8

前端 未结 10 1291
逝去的感伤
逝去的感伤 2020-12-15 05:46

I\'ve got a web form with a start date field. I\'ve tied a jquery datepicker to the txt field. Now when I choose a date in FF, the selected date is populated in the text box

相关标签:
10条回答
  • 2020-12-15 06:22

    The fix...

    onSelect: function() {}

    ..does not appear to work if the problem is with a CustomValidator that relies on a servewr side event handler to validate input.

    There are a couple of other fixes mentioned here...

    http://dev.jqueryui.com/ticket/4071

    The problem is down to IE's event handling differing from other browsers and the client side validation code supplied by ASP Net not reacting gracefully to a situation not contemplated by it's authors.

    0 讨论(0)
  • 2020-12-15 06:28

    change jquery.ui.datepicker.js line 1504

    '" href="#"  >' + printDate.getDate() + '</a>')
    

    with

    '" href="javascript:DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
           inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);"  >' + printDate.getDate() + '</a>')
    

    test works OK!

    0 讨论(0)
  • 2020-12-15 06:29

    It seems to be a bug of sorts, but adding this line in the datepicker declaration should solve it:

    onSelect: function() {}
    
    0 讨论(0)
  • 2020-12-15 06:29

    The solutions provided above only prevents the error from occurring.

    On the datepicker:

    onSelect : function(dateText, inst){ inst.input.trigger('cValidate')
    

    and bind the event to the calendar input element.

    .bind('cValidate', function (event) { window.ValidatorOnChange(event); });
    

    this will fire the validatorchanged event with the correct event args (input field).

    0 讨论(0)
  • 2020-12-15 06:29

    This is an endemic problem with jQuery datepickers and ASP validation controls. As you are saying, the wrong element cross-triggers an ASP NET javascript validation routine, and then the M$ code throws an error because the triggering element in the routine is undefined.

    I solved this one differently from anyone else I have seen - by deciding that M$ should have written their code more robustly, and hence redeclaring some of the M$ validator code to cope with the undefined element. Everything else I have seen is essentially a workaround on the jQuery side, and cuts possible functionality out (eg. using the click event instead of change).

    The bit that fails is

       for (i = 0; i < vals.length; i++) {
            ValidatorValidate(vals[i], null, event);
        }
    

    which throws an error when it tries to get a length for the undefined 'vals'.

    I just added

    if (vals) {
        for (i = 0; i < vals.length; i++) {
            ValidatorValidate(vals[i], null, event);
        }
    }
    

    and she's good to go. Final code, which redeclares the entire offending function, is below. I put it as a script include at the bottom of my master page or page (so it occurs after the default declarations and replaces the earlier version).

    Yes, this does break upwards compatibility if M$ decide to change their validator code in the future. But one would hope they'll fix it and then we can get rid of this patch altogether.

    //  Fix issue with datepicker and ASPNET validators: redeclare MS validator code with fix
     function ValidatorOnChange(event) {
        if (!event) {
            event = window.event;
        }
        Page_InvalidControlToBeFocused = null;
        var targetedControl;
        if ((typeof (event.srcElement) != "undefined") && (event.srcElement != null)) {
            targetedControl = event.srcElement;
        }
        else {
            targetedControl = event.target;
        }
        var vals;
        if (typeof (targetedControl.Validators) != "undefined") {
            vals = targetedControl.Validators;
        }
        else {
            if (targetedControl.tagName.toLowerCase() == "label") {
                targetedControl = document.getElementById(targetedControl.htmlFor);
                vals = targetedControl.Validators;
            }
        }
        var i;
        if (vals) {
            for (i = 0; i < vals.length; i++) {
                ValidatorValidate(vals[i], null, event);
            }
        }
        ValidatorUpdateIsValid();
    }
    
    0 讨论(0)
  • 2020-12-15 06:32

    The reason

    The root bug (I think it's probably meant to be a feature, or maybe a workaround for a known IE bug?) is in ASP.Net's ValidatorHookupEvent:

    var func;
    if (navigator.appName.toLowerCase().indexOf('explorer') > -1) {
        func = new Function(functionPrefix + " " + ev);
    }
    else {
        func = new Function("event", functionPrefix + " " + ev);
    }
    

    As a result, in the default case that there's no other onchange registered, this sets up the onchange for the input to be the equivalent of

    function() { ValidatorOnChange(event); }
    

    in IE and

    function(event) { ValidatorOnChange(event); }
    

    in other browsers. So iff you're using IE, the event passed to ValidatorOnChange will be window.event (since window is the global object).

    A suggested solution

    If you don't want to hack around with the ASP.Net scripts then I think the nicest way to handle this is to detect the broken event handler and replace it. As with other suggestions here, I offer an onSelect to include in the datepicker options.

    onSelect: function(dateStr, datePicker) {
        // http://stackoverflow.com/questions/1704398
        if (datePicker.input[0].onchange.toString().match(/^[^(]+\(\)\s*{\s*ValidatorOnChange\(event\);\s*}\s*$/)) {
            datePicker.input[0].onchange = ValidatorOnChange;
        }
        datePicker.input.trigger("change");
    }
    

    I'm applying this globally with

    $.datepicker.setDefaults({
        onSelect: function(dateStr, datePicker) {
            etc.
        }
    });
    
    0 讨论(0)
提交回复
热议问题