Reputation: 115
I am attempting to use the JQuery Validation Plugin but am running in to a small problem. My form uses the following method to hide/show the desired content:
<div id="page1" class="page" style="visibility:visible;">
...Page 1 form content...
</div>
<div id="page2" class="page">
...Page 2 form content...
</div>
Form has two pages...here is the button on Page 1 that allows the user to Continue.
<input type="button" id="C1" value="Continue" onClick="showLayer('page2')">
The showLayer() function simply toggles the visibility of the passed element. The only content that needs to be validated is on page 1, where this button is located. What I would like to do is have the Continue button first call .validate() and then upon successful validation proceed to the second page. Research has shown me that it is an easy thing to have the onClick call multiple functions like so:
<input type="button" id="C1" value="Continue" onClick=".validate()";"showLayer('page2')">
While this "technically" works, the user finds himself viewing page 2 content with no clue that he/she is being presented validation errors back on page 1 unless they click the "Go Back" button. Obviously not a very usable situation!
I have tried this but am still faced with the same basic problem.
<input type="button" id="C1" value="Continue" onClick="formValidate()">
function formValidate() {
.validate();
showLayer('page2');
}
What is needed is to determine whether the validation function came back successfully and then conditionally continue on to page 2 assuming all validations pass. After research into the plugin documentation I have come across the following to be my most likely (I think) candidate to achieve this:
"invalidHandler"
$(".selector").validate({
invalidHandler: function(event, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
var message = errors == 1
? 'You missed 1 field. It has been highlighted'
: 'You missed ' + errors + ' fields. They have been highlighted';
$("div.error span").html(message);
$("div.error").show();
} else {
$("div.error").hide();
}
}
});
...but I don't know how to tie it together with the conditional checking needed. I don't need to display the error count as the example shows but it seems to do the proper callback with an error count that (I would think) provide the basis for the success check and the framework for the conditional. I may very well be barking up the wrong tree and there may be a much better way to accomplish this... Any ideas? All help much appreciated!
UPDATE *************** JSFiddle http://jsfiddle.net/uEh3a/ Not sure if I have done this right...first time!
Before I added the code from Sparky the form did some automatic calcs based on the radio buttons selected. After code added no calcs and cannot move between forms. I'm sure I've done something dumb...can anybody see what?
Upvotes: 0
Views: 3207
Reputation: 21226
The thing you need to do is not let them change pages until the form is valid. The default in jQuery Validate is that only "visible" fields are validated, which will work to your advantage.
You're on the right track with doing a validation before showing the next "layer".
First off, see the example from the documentation.
So the equivalent for you would be to do this:
//remember to save the validation object like this
var v = $(".selector").validate({ /* ... */});
//then add a click handler for your button
$("#C1").click(function() {
//this runs the validation and shows errors if it fails
if (v.valid()) {
//only move forward if the validation succeeds
showLayer('page2');
}
});
Upvotes: 1
Reputation: 98738
There are lots of ways to do this, but the demo below also contains a large part of the answer to your question, which would be to use the .valid()
method to programatically test the form. You can use my example below in whole or in part.
When I create multi-step forms, I use a unique set of <form>
tags for each section. Then I use the .valid()
method to test the section before moving to the next. (Don't forget to first initialize the plugin; call .validate()
, on all forms on DOM ready.)
Then on the last section, I use .serialize()
on each form and concatenate them into a data query string to be submitted.
Something like this...
$(document).ready(function() { // <-- DOM ready handler
$('#form1').validate({ // initialize form 1
// rules
});
$('#gotoStep2').on('click', function() { // go to step 2
if ($('#form1').valid()) {
// code to reveal step 2 and hide step 1
}
});
$('#form2').validate({ // initialize form 2
// rules
});
$('#gotoStep3').on('click', function() { // go to step 3
if ($('#form2').valid()) {
// code to reveal step 3 and hide step 2
}
});
$('#form3').validate({ initialize form 3
// rules,
submitHandler: function (form) {
// serialize and join data for all forms
var data = $('#form1').serialize() + '&' + $('#form2').serialize() + '&' + $(form).serialize()
// ajax submit
return false; // block regular form submit action
}
});
// there is no third click handler since the plugin takes care of this
// with the built-in submitHandler callback function on the last form.
});
Important to remember that my click
handlers above are not using type="submit"
buttons. These are regular buttons, either outside of the form
tags or type="button"
.
Only the button on the very last form is a regular type="submit"
button. That is because I am leveraging the plugin's built-in submitHandler
callback function on only the very last form.
"Proof of Concept" DEMO: http://jsfiddle.net/dNPFX/
Also, see for reference:
https://stackoverflow.com/a/19546698/594235
Upvotes: 1