16

Sorry if I did not explain my problem clearly.

  1. I have a form with multiple tables for users inputs.
  2. I use next and back buttons to hide and show different tables in order to guide users.

Now the problem is: How do I use next button to validate current active table inputs? For example, every time a user click next, it will check if all the fields are filled?

Here is a broken DEMO. Thanks for any comments!

HTML

<form method="post" id="form1" action=index.html>
    <table>
        <H4 align="center" id="id_tab">
            |<a href="#" class="Chemical"> Chemical </a>|
             <a href="#" class="Crop"> Crop </a>|
             <a href="#" class="Physical"> Physical </a>|
            </H4>
    </table><br>
    <table class="tab tab_Chemical" border="0">
        <tr>
            <th><label for="id_wat_hl">Water Column Half life (days):</label></th>
            <td><input type="text" name="wat_hl" id="id_wat_hl" /></td>
        </tr>
    </table>
    <table class="tab tab_Crop" border="0" style="display:none">
        <tr>
            <th><label for="id_zero_height_ref">Zero Height Reference:</label></th>
            <td><input type="text" name="zero_height_ref" id="id_zero_height_ref" /></td>
        </tr>
    </table>
    <table class="tab tab_Physical" border="0" style="display:none">
        <tr>
            <th><label for="id_mas_tras_cof">Mass Transfer Coefficient (m/s):</label></th>
            <td><input type="text" name="mas_tras_cof" id="id_mas_tras_cof" /></td>
        </tr>
    </table>
    <table align="center">
        <tr>
            <td><input class="back" type="button" value="Back" /></td>
            <td><input class="next" type="button" value="Next" /></td>
            <td><input class="submit" type="submit" value="Submit" /></td>
        </tr>
    </table>
</form>

JS

$(document).ready(function() {
    var tab_pool = ["tab_Chemical", "tab_Crop", "tab_Physical"];
    var visible = $(".tab:visible").attr('class').split(" ")[1];
    var curr_ind = $.inArray(visible, tab_pool);
    $(".submit").hide();
    $(".back").hide();

    $('.next').click(function() {
        if (curr_ind < 2) {
            $(".tab:visible").hide();
            curr_ind = curr_ind + 1;
            $("." + tab_pool[curr_ind]).show();
            $(".submit").hide();
            $(".back").show();
        }
        if (curr_ind == 2) {
            $(".submit").show();
            $(".next").hide();
        }
    });

    $('.back').click(function() {
        if (curr_ind > 0) {
            $(".tab:visible").hide();
            curr_ind = curr_ind - 1;
            $("." + tab_pool[curr_ind]).show();
            $(".submit").hide();
            $(".next").show();
        }
        if (curr_ind == 0) {
            $(".back").hide();
        }
    });
    $(".next").click(function() {
        $(".tab tab_Chemical").validate({
            rules: {
                wat_hl: "required"
            }
        })
    })
    $(".next").click(function() {
        $(".tab tab_Crop").validate({
            rules: {
                zero_height_ref: "required"
            }
        })
    })
    $(".next").click(function() {
        $(".tab tab_Physical").validate({
            rules: {
                mas_tras_cof: "required"
            }
        })
    })
});
Milap
  • 6,915
  • 8
  • 26
  • 46
TTT
  • 4,354
  • 13
  • 73
  • 123
  • I'm not sure I have the ambition to take this on tonight, but I see two ways to go about it. Either change/append classes on the next button to link it to the appropriate .tab for validation, or check each tab for its display attribute before validating. – isherwood Feb 28 '13 at 03:01
  • @isherwood: Thanks for your reply. Either way works as long as I can use the jQuery validation plugin, since I need to add some methods for other type of inputs. – TTT Feb 28 '13 at 03:05
  • Here's a start on what I'm thinking: http://jsfiddle.net/Pz9NR/2/ Notice that all the .next click functions are together. – isherwood Feb 28 '13 at 03:10
  • This one uses better logic and fixes your table class selector: http://jsfiddle.net/Pz9NR/5/ – isherwood Feb 28 '13 at 03:22

4 Answers4

17

Add validation using the form

var validator = $('form').validate({
    ignore: 'input[type="button"],input[type="submit"]',
    rules: {
        wat_hl: {
            required: true
        },
        zero_height_ref: {
            required : true
        },
        mas_tras_cof: {
            required: true
        }
    }
});

Then in the next handler

$('.next').click(function () {
    var tab = $(".tab:visible");

    var valid = true;
    $('input', tab).each(function(i, v){
        valid = validator.element(v) && valid;
    });

    if(!valid){
        return;
    }

    if (curr_ind < 2) {
        $(".tab:visible").hide();
        curr_ind = curr_ind + 1;
        $("." + tab_pool[curr_ind]).show();
        $(".submit").hide();
        $(".back").show();
    }
    if (curr_ind == 2) {
        $(".submit").show();
        $(".next").hide();
    }
});

Demo: Fiddle

Explanation

  1. var valid = true: a flag to keep the state of the tab through the iteration process
  2. $('input', tab).each: Iterate through each inputs element in the current tab
  3. validator.element(v) validate each element in the tab
  4. valid = validator.element(v) && valid: update the state of the tab
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Thanks for much! Could you explain ` $('input', tab).each(function(i, v){ valid = validator.element(v) && valid; });` a little bit? – TTT Feb 28 '13 at 03:31
  • @tao.hong added some explanation, let me know whether it is enough – Arun P Johny Feb 28 '13 at 03:43
  • So the index `i` is not used? Sorry for the dumb question – TTT Feb 28 '13 at 03:59
  • last question. What is the difference between `$('input', tab)` and `$('input')` Thanks! – TTT Feb 28 '13 at 04:14
  • No `i` is not required in this scenario, `$('input', tab)` fetches only `input` elements within the current tab, while `$('input')` fetches all input elements within the document – Arun P Johny Feb 28 '13 at 04:24
  • 1
    It's actually a little easier than looping through inputs. You can use `var valid = $('input', tab).valid();` [Demo](http://jsfiddle.net/arunpjohny/Pz9NR/6/) – Flyn San Mar 20 '14 at 00:54
  • perfect. Thanks a lot (y) – Junaid Masood Dec 03 '19 at 12:44
5

What about this ?

var isOpenedTabValid = $(".tab:visible :input").valid();
Tom Esterez
  • 21,567
  • 8
  • 39
  • 44
3

I have an implementation to get this same result. I have added div elements with role="form" parameter. And then validates elements on each div as it is like a form while the main form is still wrapping around.

<form action="#" id="myForm" role="form" data-toggle="validator" method="post">

    <div id="form-step-0" role="form" data-toggle="validator"><!-- Input elemets --></div>
    <div id="form-step-1" role="form" data-toggle="validator"><!-- Input elemets --></div>
    <div id="form-step-2" role="form" data-toggle="validator"><!-- Input elemets --></div>

</form>

And this jQuery code to check if there is any error in a particular div

var elmForm = $("#form-step-0");
elmForm.validator('validate'); 

The following code will check if there is any error input raised in a particular div

var elmErr = elmForm.children('.has-error');
if(elmErr && elmErr.length > 0){
    // Error elements found, Form validation failed
    return false;    
}

And when you want to validate the whole form just use the normal code

var elmForm = $("#myForm");
elmForm.validator('validate'); 
var elmErr = elmForm.find('.has-error');
if(elmErr && elmErr.length > 0){
    alert('Oops we still have error in the form');
    return false;    
}else{
    alert('Great! we are ready to submit form');
    elmForm.submit();
    return false;
}                

Here is the source file on GitHub
Here is a Demo implemeation

Dipu Raj
  • 1,784
  • 4
  • 29
  • 37
1

You are calling the validate method for each table every time the next button is clicked. Instead, you only want to call validate if the table is visible. Since you are already tracking which table should be visible with your curr_ind, I'd suggest using it to know which table to validate and only calling validate for the visible table.

Marshmellow1328
  • 1,205
  • 3
  • 18
  • 27
  • I agree with your suggestion. I tried to use $('.table class').validate() method, which failed. However, once I change it into $('#form ID').validate(), everything works fine... – TTT Feb 28 '13 at 03:13
  • Call `validate()` to initialize the plugin on a form. Then call `valid()` to test validity. – Sparky Feb 28 '13 at 03:26