dstefani dstefani - 3 months ago 27
jQuery Question

jQuery .validate: get number of invalids onfocusout

onsubmit I'm displaying the number of errors in my form at the top of the form.

What I would like to do is update that number after a user fixes an error and focus's out of a field. It seemed like using onfocusout: was the way to go.

I'm trying to use validator.numberOfInvalids() inside my onfocusout: function but seems that it only works onsubmit.

Is there a way to recount the number of errors without resubmitting the form?

EDIT: well after I posted I got an idea, which works. All but for the last error fix. The error message still says 1. Getting number of errors would be a great way to do this.

EDIT: there are a number of $.validator.addMethod()'s used and a number of functions that support those. The whole thing is written using Box T3. I hope this helps.

function billing_form_setup(billingForm) {

validator = $(billingForm).validate({
debug: true,
meta: "validate",
ignore: [],
errorPlacement: function(error, element) {
// this sets the error placement for jquery UI select menu's
if (element.is("select")) {
$(element)
.closest( "div" )
.find( ".ui-selectmenu-button" )
.css('border', '2px solid #d11515')
.css('box-shadow', ' 0px 0px 16px -8px rgba(209,21,21,1)');
}
else { // default error placement
$( element )
.closest( "form" )
.find( "span[class='" + element.attr( "id" ) + "']" )
.append( error );
}
},
rules: {
p_card_number: {
required: true,
creditCheck: true,
minlength: 12
},
p_exp_date: {
required: true,
dateCheck: true,
checkDateExpired: true
},
p_card_code: {
required: true,
minlength: 3,
digits: true
}
},
errorElement: "p",
invalidHandler: function (event, validator) {
// set up for showing one error message above form
errors = validator.numberOfInvalids();
if (errors) {
message = errors == 1
? 'There is a problem 1 field'
: 'There is a problem with ' + errors + ' fields.';
$(".pmnt-type-form div.error span").html(message);
$(".pmnt-type-form div.error").show();
} else {
$(".pmnt-type-form div.error").hide();
}
},
onfocusout: function(element, event) {
// don't do this! ;-)
//$("#billing-form").submit();
}

});
};


EDIT: new showErrors code:

showErrors: function(errorMap, errorList) {
var errors = this.numberOfInvalids();
if (errors) {
message = 'There is a problem with ' + errors + ' field';
$(".pmnt-type-form div.error span").html(message);
$(".pmnt-type-form div.error").show();
} else {
$(".pmnt-type-form div.error").hide();
}
}

Answer

onsubmit I'm displaying the number of errors in my form at the top of the form.

This should be done using the showErrors function. And we have no idea if this is what you're doing because you've shown us very little.

The onfocusout callback is the function that merely triggers validation when the user leaves an input... it was never meant for triggering other things.

You should also never be putting a jQuery .submit() inside of any of the jQuery Validate plugin's callback handler functions.

Why? Because the plugin is already automatically capturing the click, blocking the submit, checking for validation errors, showing/hiding messages, and then allowing the submit only if/when valid. You are breaking this whole process by inserting a .submit().

The .numberOfInvalids() method is most commonly used inside of the showErrors callback.

What I would like to do is update that number after a user fixes an error and focus's out of a field.

It's working for me when I put .numberOfInvalids() where it belongs: jsfiddle.net/yLjrL8ay/

showErrors: function(errorMap, errorList) {
    $("#summary").html("Your form contains " + this.numberOfInvalids() + " errors");
}

EDIT:

Currently, you have the relevant code within the invalidHandler. However, the invalidHandler only fires when the form is invalid... therefore, if you fix all errors, the invalidHandler is not going to fire again.

As stated in the original answer, use showErrors instead.

EDIT 2:

There was also a problem with your logic here...

if (errors) {
    // construct message
    ....

When errors goes to 0, the condition will be false, and your message could never update.

Comments