I'm new to jQuery and I'm trying to use it and the validation plugin () to create a multi-part form with multiple tabs for different sections. Right now I have it where there are multiple tabs and the "Next" button switches to the next tab.
The problem I'm having is that when I finally submit on the last page, the form validates properly but if there are errors on the other page the user isn't notified, and validation really only happens once "submit" is clicked.
How would I validate each individually when I click "Next"? I don't really want to create multiple forms or keep track of hidden fields :S Any suggestions?
Thanks!
<script type="text/javascript">
$(document).ready(function() {
//....stuff
//tabs
var tabs = $("#tabs").tabs();
$(".nexttab").click(function() {
//var selected = $("#tabs").tabs("option", "selected");
//$("#tabs").tabs("option", "selected", selected + 1);
$("#tabs").tabs("select", this.hash);
});
//use link to submit form instead of button
$("a[id=submit]").click( function(){
$(this).parents("form").submit();
});
//form validation
var validator = $("#myForm").validate();
});
</script>
<form class="cmxform" id="myForm" method="post" action="">
<div id="tabs">
<ul>
<li><a href="#general">General</a></li>
<li><a href="#tab2"></a></li>
</ul>
<div id="general">
....stuff...
<p>
<a class="nexttab navbutton" href="#tab2"><span>Next</span></a>
</p>
</div>
<div id="tab2">
<h2>Tab2</h2>
<p>
<a class="nexttab navbutton" href="#general"><span>Prev</span></a>
<a class="submit navbutton" id="submit" href="#"><span>Submit</span></a>
</p>
</div>
</div>
</form>
Edit:
@Andrew:
I did some combination of your 2nd example and disabling tabs. Seems to work, aside from having the page refresh re-disable the tabs.
var tabs = $("#tabs").tabs({
disabled: [1,2,3,4,5],
select: function(event, ui) {
var valid = true;
var current = $(this).tabs("option", "selected");
var panelId = $("#tabs ul a").eq(current).attr("href");
if(ui.index > current)
{
$(panelId).find("input").each(function() {
//console.log(valid);
if (!validator.element(this) && valid) {
valid = false;
}
});
}
return valid;
}
});
In combination with:
$(".nexttab").click(function() {
var selected = $("#tabs").tabs("option", "selected");
$("#tabs").tabs("enable", selected+1);
$("#tabs").tabs("option", "selected", selected + 1);
});
I'm new to jQuery and I'm trying to use it and the validation plugin (http://docs.jquery.com/Plugins/Validation) to create a multi-part form with multiple tabs for different sections. Right now I have it where there are multiple tabs and the "Next" button switches to the next tab.
The problem I'm having is that when I finally submit on the last page, the form validates properly but if there are errors on the other page the user isn't notified, and validation really only happens once "submit" is clicked.
How would I validate each individually when I click "Next"? I don't really want to create multiple forms or keep track of hidden fields :S Any suggestions?
Thanks!
<script type="text/javascript">
$(document).ready(function() {
//....stuff
//tabs
var tabs = $("#tabs").tabs();
$(".nexttab").click(function() {
//var selected = $("#tabs").tabs("option", "selected");
//$("#tabs").tabs("option", "selected", selected + 1);
$("#tabs").tabs("select", this.hash);
});
//use link to submit form instead of button
$("a[id=submit]").click( function(){
$(this).parents("form").submit();
});
//form validation
var validator = $("#myForm").validate();
});
</script>
<form class="cmxform" id="myForm" method="post" action="">
<div id="tabs">
<ul>
<li><a href="#general">General</a></li>
<li><a href="#tab2"></a></li>
</ul>
<div id="general">
....stuff...
<p>
<a class="nexttab navbutton" href="#tab2"><span>Next</span></a>
</p>
</div>
<div id="tab2">
<h2>Tab2</h2>
<p>
<a class="nexttab navbutton" href="#general"><span>Prev</span></a>
<a class="submit navbutton" id="submit" href="#"><span>Submit</span></a>
</p>
</div>
</div>
</form>
Edit:
@Andrew:
I did some combination of your 2nd example and disabling tabs. Seems to work, aside from having the page refresh re-disable the tabs.
var tabs = $("#tabs").tabs({
disabled: [1,2,3,4,5],
select: function(event, ui) {
var valid = true;
var current = $(this).tabs("option", "selected");
var panelId = $("#tabs ul a").eq(current).attr("href");
if(ui.index > current)
{
$(panelId).find("input").each(function() {
//console.log(valid);
if (!validator.element(this) && valid) {
valid = false;
}
});
}
return valid;
}
});
In combination with:
$(".nexttab").click(function() {
var selected = $("#tabs").tabs("option", "selected");
$("#tabs").tabs("enable", selected+1);
$("#tabs").tabs("option", "selected", selected + 1);
});
Share
Improve this question
edited Aug 29, 2012 at 20:46
Andrew Whitaker
126k32 gold badges295 silver badges308 bronze badges
asked Apr 13, 2011 at 1:33
JordanJordan
9,1149 gold badges38 silver badges48 bronze badges
2 Answers
Reset to default 12This is possible using the .element(selector)
function of validator
. What you're going to do is iterate through each element on the active tab and call that function on the input. This will trigger validation on each element in turn, showing the validation message.
$(".nexttab").click(function() {
var valid = true;
var i = 0;
var $inputs = $(this).closest("div").find("input");
$inputs.each(function() {
if (!validator.element(this) && valid) {
valid = false;
}
});
if (valid) {
$("#tabs").tabs("select", this.hash);
}
});
Additionally, you'll probably want to run similar code when a user clicks a tab to go to a new set of inputs, instead of clicking "next".
Here's a working example: http://jsfiddle.net/c2y6r/
Update: Here's another way you could do it, canceling the select
event upon invalid form elements:
var validator = $("#myForm").validate();
var tabs = $("#tabs").tabs({
select: function(event, ui) {
var valid = true;
var current = $(this).tabs("option", "selected");
var panelId = $("#tabs ul a").eq(current).attr("href");
$(panelId).find("input").each(function() {
console.log(valid);
if (!validator.element(this) && valid) {
valid = false;
}
});
return valid;
}
});
However, now you have to consider allowing the user to go back when they've entered invalid data into the current page. On the other hand, you get the bonus of keeping all the validation code inside of one function which gets fired if the person clicks a tab or your next link.
Example: http://jsfiddle.net/c2y6r/1/
Update 2, if you want to allow people to navigate backwards through the tab interface:
var tabs = $("#tabs").tabs({
select: function(event, ui) {
var valid = true;
var current = $(this).tabs("option", "selected");
var panelId = $("#tabs ul a").eq(current).attr("href");
if (ui.index > current) {
$(panelId).find("input").each(function() {
console.log(valid);
if (!validator.element(this) && valid) {
valid = false;
}
});
}
return valid;
}
});
The existing code didn't work for me (maybe it's dated) so i came up with the following. This example is assuming using jquery tabs and jquery validator.
$('#tabs').tabs(
{
beforeActivate: function( event, ui )
{
var valid = $("#myForm").valid();
if (!valid) {
validator.focusInvalid();
return false;
}
else
return true;
}
});