0

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?

RCurtis
  • 115
  • 3
  • 11
  • OK...I've seen a couple of examples that have the form being validated "on the fly" using the $(document).ready(function (). I am not stuck on it being performed via the onClick button action but I don't understand how to wrap the $(document).ready(function () around what I am already using with my hidden
    page display method...
    – RCurtis Dec 19 '13 at 15:49

2 Answers2

1

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');
      }
  });
Ryley
  • 21,046
  • 2
  • 67
  • 81
  • Wouldn't it be much more efficient to simply call the `.valid()` method rather than repeatedly calling something that contains the entire validation object? – Sparky Dec 19 '13 at 17:40
  • Yes, of course - I wasn't thinking, just blindly copying from the given example. Whoops! – Ryley Dec 19 '13 at 17:58
1

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

Community
  • 1
  • 1
Sparky
  • 98,165
  • 25
  • 199
  • 285
  • I am still studying your example to see how to integrate it within what I already have...based on your description it sounds to be *exactly* what I'm shooting for! I need to ask a dumb question...(this will show my ignorance LOL). I have read/seen somewhere that you can refer to the $(document).ready(function() using a shortcut method - $(function(). Is this correct? My code already has this defined, so if these two statements are equivalent then I'm pretty sure I can get where I need to go! – RCurtis Dec 19 '13 at 17:59
  • @user3066388, The DOM ready handler can be written in different ways and you can combine all code on the page into one DOM ready handler. So yes, `$(function()` is exactly the same as `$(document).ready(function()`. See: http://api.jquery.com/ready/ – Sparky Dec 19 '13 at 18:06
  • Thanks, I thought so. I have edited my main post to reflect what I've done with your code...I've done something wrong! LOL – RCurtis Dec 19 '13 at 18:56
  • @user3066388, That is a lot of unindented code to expect us to scroll through. I respectfully suggest that you learn how to use jsFiddle. It shouldn't take you long to figure it out; see mine as an example. Otherwise, anyone willing to help would have to take the extra time to construct a very complex jsFiddle before they even start troubleshooting. You have to be willing to help yourself before anyone here. – Sparky Dec 19 '13 at 19:01
  • @user3066388, I see one big mistake. Re-read my answer carefully. Make note of the paragraph just above the "proof of concept" demo line. Is the button on your last form `type="submit"`? – Sparky Dec 19 '13 at 19:07
  • I know I have a problem in that area...but my code as it exists right now won't even get to page 2 so I was just going to take it a step at a time. Unindented? It shows as indented for me...perhaps it is not indented according to established standards...not sure exactly what you mean there. Help me understand so I can ask questions in the correct manner. – RCurtis Dec 19 '13 at 19:15
  • OK...I *think* I have a JSFiddle set up...I took out all that code from my update and listed the fiddle. Of course, it does not work either since the first code didn't. All help truly appreciated! – RCurtis Dec 19 '13 at 19:24
  • @user3066388, your jsfiddle was broken for the following reasons: 1) you failed to include jQuery, 2) you failed to include the jQuery validate plugin, 3) you have a stray brace within your second `.validate()` call, 4) you failed to put _everything_ within the DOM ready handler. See: http://jsfiddle.net/uEh3a/14/ – Sparky Dec 20 '13 at 20:27
  • MANY THANKS! As I said...that was my first crack at constructing a fiddle...I'd referenced quite a few in researching various questions but that was my first. The term "going down in flames" comes to mind!! I will compare the changes you made with my original...I'm certain I can take it from here...Thank you! – RCurtis Dec 22 '13 at 02:54