2

So I'm trying to validate a JQM form that has 4 parts and are divided in different pages so after I validate the first part I want to go to the second, if the form it's valid. I'm trying to validate with the JQuery.validate plugin but it doesn't respond in any way with the form.

PS:IT MUST BE WITH JQuery.validation plugin

 <div data-role="page" id="page2" data-add-back-btn="true">
        <div data-role="header" data-position="fixed">
                <h1 id="page2Header"></h1>

        </div>
        <div data-role="content">

    <form id="sampleProperties">
                    <label for="station">Select Station:</label>
                    <select  name="station" id="station" onBlur="storeData(this.id,this.value)" required="true">
                        <option value="50028000">Tanama River</option>
                        <option value="50010500">Rio Guajataca, Lares</option>
                        <option value="60008002">Example River2</option>
                        <option value="60008003">Example River3</option>
                        <option value="60008004">Example River4</option>
                    </select>
                    <div class="hide">
                    <div class='suspendedAdditionalFields'>
                    <label for="sampleMediumDropdown">Select sample medium:</label>
                    <select name="sampleMediumDropdown" id="sampleMediumDropdown" onBlur="storeData(this.name,this.value)">
                        <option value="WS">WS(Surface Water)</option>
                        <option value="WSQ">WSQ(Surface Water QC)</option>
                    </select>
                    </div>
                    <div class='bottomAdditionalFields'>
                    <label for="sampleMediumDropdownBottom">Select sample medium</label>
                    <select name="sampleMediumDropdown" id="sampleMediumDropdownBottom" onBlur="storeData(this.name,this.value)">
                        <option value="SB">SB (bottom material)</option>
                        <option value="SBQ">SBQ (bottom material QC)</option>
                    </select>
                    </div>
                    </div>
                    <label for="date">Begin Date:</label>
                    <input name="date" id="beginDate" type="date" onChange="storeData(this.id,this.value)" />

                    <div class="hide">
                    <label for='EVENT'>Hydrologic event:</label>
                    <select name="EVENT" id="EVENT" onBlur="storeData(this.name,this.value)">
                        <option value="1">1- Drought</option>
                        <option value="2">2- Spill</option>
                        <option value="3">3- Regulated Flow</option>
                        <option value="4">4- Snowmelt</option>
                        <option value="5">5- Earthquake</option>
                        <option value="6">6- Hurricane</option>
                        <option value="7">7- Flood</option>
                        <option value="8">8- Volcanic activity</option>
                        <option value="9" selected>9- Routine Sample</option>
                        <option value="A">A- Spring breakup</option>
                        <option value="B">B- Under ice cover</option>
                        <option value="C">C- Glacial lake outbreak</option>
                        <option value="D">D- Mudflow</option>
                        <option value="E">E- Tidal action</option>
                        <option value="F">F- Fire, affected by fire prior sampling</option>
                        <option value="H">H- Dambreak</option>
                        <option value="J">J- Storm</option>
                        <option value="K">K- Backwater</option>
                        <option value="X">X- Not applicable</option>
                    </select>
                    </div>
                    <div class="ui-grid-a">
                     <label for="containerCuantity">Add a group of single container or sets of multiple samples: </label>    
                     <div class="ui-block-a">
                        <input type="number" min="1" value="1" max="40" id="containerCuantity" name="containerCuantity" onBlur="storeData(this.id,this.value)"/></div>
                     <div class="ui-block-b">
                        <select id="singleMultiContainer" name="singleMultiContainer"  onChange="storeData(this.id,this.value)">
                            <option value="" selected>--Select Container or Set--</option>
                            <option value="single">Single container sample</option>
                            <option value="multi">Multiple sets container</option>
                        </select>
                        </div>
                    </div>
                 <input id='addSampleParameters'type="submit"  value="Next"/>
                </form>
</div>
    <div data-role="footer" data-position="fixed">
        <div data-inline="true" data-type="horizontal"><a href="#" data-icon="bars" data-iconpos="notext" data-inline="true" data-mini="false" data-role="button">Menu</a><a id="addSampleParameters" data-icon="arrow-r" data-iconpos="right" data-inline="true" data-role="button" data-mini="false" data-theme="e">Next</a>
        </div>
    </div>
</div>

The js:

$('#page2').bind('pageinit',function(){
  $('#sampleProperties').validate({
    rules:{
        station: 'required',
        date: 'required',
        singleMultiContainer: 'required',
        containerCuantity:{
            required:'true',
            minlength:1,
            maxlength:40
        }
    },
     submitHandler: function(form) {
                    alert('Success!');
                    }

  });
 });
Sparky
  • 98,165
  • 25
  • 199
  • 285
falgranado
  • 97
  • 1
  • 11
  • just replace this `$('#page2').on('pageinit', function () {` with this `$(document).on('pageinit', '#page2', function () {` http://jsfiddle.net/Palestinian/VTQjs/ – Omar Oct 23 '13 at 15:57

2 Answers2

4

There are various approaches to stepped forms.

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).on('pageinit', function() { // dom ready handler for jQuery Mobile

    $('#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/8bnZV/

BTW, notice how I replaced your outdated .bind() with the more modern .on() method.

Also, see for reference:

https://stackoverflow.com/a/17975061/594235

Community
  • 1
  • 1
Sparky
  • 98,165
  • 25
  • 199
  • 285
  • Note that as of jQM 1.3.0 and later, jQM wraps `input` inside a div. Error msg is being appended inside that div/input. It requires a special handlers to append error msg outside the wrapping div. Have you found a way to overcome this? http://jsfiddle.net/Palestinian/VTQjs/ – Omar Oct 23 '13 at 16:06
  • 1
    @Omar, you should really post that as a new question because the comments section is not the proper way to ask for help. However, I will say that this plugin gives you total control over message placement with various options described in the documentation. See `errorPlacement` for one way. (also, your jsFiddle is broken) – Sparky Oct 23 '13 at 16:14
  • 1
    It worked great until the first page, does using `$(document).ready(...)` makes a difference than `.on('pageinit',...)` using the `.validate`? – falgranado Oct 25 '13 at 18:41
  • @falgranado, it has nothing in particular to do with `.validate()`. It has to do with using the proper DOM ready event handler. For regular jQuery, you use `document.ready` and for jQuery Mobile you use `document.pageinit`. – Sparky Oct 25 '13 at 20:08
  • BTW, if I put `.on(...)` i get `Uncaught TypeError: Object [object Object] has no method 'on' ` is it a bug or something in particular ? – falgranado Oct 29 '13 at 21:15
  • @falgranado, I have no good idea what you could be doing wrong. As you can see, it's working fine in the jsFiddle demo. http://jsfiddle.net/8bnZV/ ~ Are you using modern versions of jQuery, etc? – Sparky Oct 29 '13 at 21:37
  • @Sparky i'm currently using `jquery-1.6.4.min.js` – falgranado Oct 30 '13 at 12:35
  • @Sparky sorry it was outdated, Thanks a lot! – falgranado Oct 30 '13 at 12:40
-2

Edit: clearly not a valid answer since the pages are in individual divs ;)

Is there any reason you're using .bind like that?

This section of validate code looks fine:

$('#sampleProperties').validate({
  rules:{
    station: 'required',
    date: 'required',
    singleMultiContainer: 'required',
    containerCuantity:{
        required:'true',
        minlength:1,
        maxlength:40
    }
  },
  submitHandler: function(form) {
     alert('Success!');
  }
});

Conversely (your title is ambiguous) if you're wanting a way to validate the form without jquery.validate, you could simply bind some validation functions to the keyUp event on the various input boxes.

brandonscript
  • 68,675
  • 32
  • 163
  • 220
  • It must be done with the JQuery validation, and i'm using `.bind` because I wanted to do it only when that specific page is loaded. Thank you for your answer – falgranado Oct 23 '13 at 15:02
  • OK, makes more sense - rereading your original post, by "page" loading do you actually that div coming into view? Your question suggestions on page load (document.ready). – brandonscript Oct 23 '13 at 15:08