Rabadash8820 Rabadash8820 - 3 years ago 249
Javascript Question

jQuery valid() Gives Wrong Value in Delegated Blur Handler

I am creating an ASP.NET Core web app, which uses jQuery Validate for client-side validation, and jQuery Unobtrusive Validation to configure validation using HTML5 data-* attributes. I have a text input, and I am handling its

event via event delegation. The code looks something like this:

$(document).ready(() => {
$('#my-container').on('blur', '.my-input-class', (event) => {
var isValid = $(event.target).valid();
// Do stuff with isValid's boolean value

Unfortunately, if I enter an invalid value in the input then tab out, then
is still set to
. But if I click the input and click off again, then this second blur event correctly sets

I think somehow my blur handler is happening before the jQuery Validate blur handler, presumably because I'm using event delegation rather than directly handling
. Event delegation is necessary though because the input is generated dynamically, after
has already been called. I've seen some posts suggest calling
, but because ASP.NET Core uses the unobtrusive validation library, I never have access to the validator object returned by
. So...


How do I ensure that
returns the correct value in a delegated event handler when using the unobtrusive validation library?


While trimming up my page's HTML to post, I got an idea for what the issue might be. My input is actually using remote validation with the
attribute. Perhaps my blur handler is just being called before the remote validation has sent a response, so the plugin thinks the input is still valid?

Answer Source

It looks like the issue was indeed with mixing remote validation with a blur handler. I have since started using a more event-driven approach to validation.

    highlight: (element, errorClass, validClass) =>
        onValidating(element, false, errorClass, validClass),
    unhighlight: (element, errorClass, validClass) =>
        onValidating(element, true, errorClass, validClass)

function onValidating(element, valid, errorClass, validClass) {
    var e = new CustomEvent("validating", {
        detail: {
            valid: valid,
            errorClass: errorClass,
            validClass: validClass
        bubbles: true

The highlight and unhighlight callbacks provided to jQuery Validate's setDefaults() method each raise a synthetic validating event, with the valid property set to false or true, respectively. These events can then be subscribed to anywhere else in the app, allowing one to move onblur actions to those new handlers. In my case:

$('#my-container').on('validating', e => {
    var isValid = e.detail.valid;
    // Do stuff with isValid's boolean value

Because this technique uses setDefaults() and not validate(), it can be used with ASP.NET Core's unobtrusive validation plugin!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download