Jquery validation multiple tabs, validate one at a time?

48,041

This 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;
    }
});
Share:
48,041
Jordan
Author by

Jordan

Updated on September 02, 2020

Comments

  • Jordan
    Jordan over 3 years

    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);
    });