I have an input form that I'm performing client-sided validation on with the jQuery validator plugin. Basic usage is working great, except for a specific scenario:
The form splits up address input fields, allowing separate fields for street number, name, city, state, and zip. The address itself is an optional input to the form (a user may opt to enter no address), but I want to ensure that if any one of these fields are used, the user is prompted to enter all the fields.
This works, except in the case when someone enters in an address and hits submit, and then decides to enter in no address. The ideal behavior in this case would be that, as soon as the text in the inputs they've entered is removed, for the address group to be unhighlighted.
Here is the current scenario:
- User enters information into only one input field, e.g., street name.
- The submit button is clicked.
- The validator plugin highlights the other address inputs with an error message prompting for the full address.
- User decides to enter no address, and removes the prior input, e.g. erases street name
- Ideally: All the other highlighted address inputs are unhighlighted and the error message is removed. Actually: The highlighted address inputs and message remain until form submission.
Here is the javascript that demonstrates the problem and the corresponding JSFiddle.
$("form").validate({
errorClass: 'error',
errorElement: 'label',
submitHandler: function() {
alert("Form submitted");
return false;
},
groups: {
address: "streetNumber streetName city state zipcode"
},
rules: {
streetNumber: {
required: {
depends: function(){
return $("#streetName").val() != '' || $("#city").val() != '' || $("#state").val() != '' || $("#zipcode").val() != '';
}
}
},
streetName: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#city").val() != '' || $("#state").val() != '' || $("#zipcode").val() != '';
}
}
},
city: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#streetName").val() != '' || $("#state").val() != '' || $("#zipcode").val() != '';
}
}
},
state: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#streetName").val() != '' || $("#city").val() != '' || $("#zipcode").val() != '';
}
}
},
zipcode: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#streetName").val() != '' || $("#city").val() != '' || $("#state").val() != '';
}
}
}
},
messages: {
streetNumber: {required: "Must provide full address"},
streetName: {required: "Must provide full address"},
city: {required: "Must provide full address"},
state: {required: "Must provide full address"},
zipcode: {required: "Must provide full address"}
},
highlight: function(element, errorClass, validClass) {
$(element).addClass(errorClass).removeClass(validClass);
},
unhighlight: function(element, errorClass, validClass) {
$(element).removeClass(errorClass);
},
errorPlacement: function(error, element) {
var n = element.attr("name");
if (n == "streetNumber" || n == "streetName" || n == "city" || n == "state" || n == "zipCode")
error.insertAfter("#zipcode");
}
});
Besides trying to get the desired functionality of the highlight, I'm also wondering if there is a smarter way to accomplish the "all or nothing" input groups that doesn't involve the mess of conditional statements. Perhaps I can use a form input group?
unhighlightcallback function to do the opposite of yourhighlightcallback function. More like this:$(element).removeClass(errorClass).addClass(validClass);- Sparkyhighlight/unhighlightare only called when an error is triggered or cleared. In other words, the same time you see the error message appear and disappear. - Sparky