简体   繁体   中英

jquery validate ignores dynamically added fields

Jquery validate validates the form fields that are already in the DOM as well as fields that are added dynamically. But if the fields that are NOT dynamically added pass validation, the form submits ignoring the dynamically added fields.

Here is a snapshot: 快照

Here is my code:

 $('#milestone-form').validate({ // initialize the plugin
        rules: {
            "milestone[]": {
                required: true,
                minlength: 3,
            },
            "deadline[]": {
                required: true,
                minlength: 3,
            },
            "amount[]": {
                required: true,
                minlength: 2,
            },

        },
        submitHandler: function(form) {
              var data = $("#milestone-form").serialize();
                $.ajax({
                    type:"POST",
                    url:"ajax/scripts/crt_ms.php",
                    data:data,
                    success:function(data){ 
                        if(!data){alert("Something went wrong")}else{alert("Success")}
                        $(document).off();
                        },  
                    });
            },
    });
    //Validation End

  $(document).on('click', ".add", function(){
  $(flieds).insertAfter($(this).closest("#fields"));
  $('.field').each(function() {
  $(this).rules('add', {
    required: true,
        });
    });
}); 

$(".save-ms").click(function(){
    if($('#milestone-form').valid()){
        //$("#milestone-form").submit();
        alert("POSTED");
         return false;
    } else { alert("ERROR");}
});

All my <input> elements have a class=".field" attribute.

Also, I noticed one thing that all the dynamic fields do not get a error LABEL instead only have a class to define it as invalid.

I have been trying the whole day to do this but just not happening.

It is simple. Jquery validate doesn't validate multiple elements with the same name.

So the solution I found is here , originally from here

I just had to add this.

$(document).ready(function(){
$.validator.prototype.checkForm = function () {
            //overriden in a specific page
  this.prepareForm();
  for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) {
      if (this.findByName(elements[i].name).length != undefined && this.findByName(elements[i].name).length > 1) {
          for (var cnt = 0; cnt < this.findByName(elements[i].name).length; cnt++) {
              this.check(this.findByName(elements[i].name)[cnt]);
          }
      } else {
          this.check(elements[i]);
      }
  }
  return this.valid();
},
};

In your own answer you used a lot of repeated searches through the DOM elements. Per loop iteration you did at least four dom searches, sometimes even just for the simple length variable.

This puts an unecessary load on the browser. Also I'd suggest making use of the native jQuery functions to help you iterate these loops and then use some scopeing to help you store relevenant references, like one to the validator.

Suggested reading:

What is the scope of variables in JavaScript?
Performance of jQuery selectors vs local variables

$.validator.prototype.checkForm = function () {
        //overriden in a specific page
        this.prepareForm();
        // Scoped variable.  
        var that = this;
        $(this.elements).each(function(index,elem) {
            // Search only once. big speed improv
            var seek = that.findByName(elem.name);
            // undefined and 0 is false by default
            if (seek.length && seek.length > 1) {
                seek.each(function(index,duplicate) {
                    // Notice the use the reference that from the outerscope. 
                    // `that` int his case refers to the the validator object.
                    that.check(duplicate);
                });
            }
          else {
              that.check(seek);
          }
       });
    };

 $(document).ready(function(){ $('#milestone-form').validate({ // initialize the plugin rules: { "milestone[]": { required: true, minlength: 3, }, "deadline[]": { required: true, minlength: 3, }, "amount[]": { required: true, minlength: 2, }, }, submitHandler: function(form) { var data = $("#milestone-form").serialize(); $.ajax({ type:"POST", url:"#", data:data, success:function(data){ if(!data){alert("Something went wrong")}; $(document).off(); }, }); }, }); // =========================================================================== $.validator.prototype.checkForm = function () { //overriden in a specific page this.prepareForm(); // Scoped variable. var that = this; $(this.elements).each(function(index,elem) { // Search only once. big speed improv var seek = that.findByName(elem.name); // undefined and 0 is false by default if (seek.length && seek.length > 1) { seek.each(function(index,duplicate) { // Notice the use the reference that from the outerscope. // `that` int his case refers to the the validator object. that.check(duplicate); }); } else { that.check(seek); } }); }; // =========================================================================== var form= "<div id='fields'> <input type='text' name='milestone[]' placeholder='Milestone'> <input type='text' name='deadline[]' placeholder='Deadline'> <input type='text' name='amount[]' placeholder='Amount'> <input type='text' name='p[]' value='1' style='display:none;'> <span class='add halflings-icon plus'>+</span> <span class='remove halflings-icon minus'>-</span> </div>" $(document).on('click', ".add", function(){ $(form).insertAfter($(this).closest("#fields")); }); $(document).on('click', ".remove", function(){ $(this).closest('div').remove(); }); $(".save-ms").click(function(evt){ evt.preventDefault(); if($('#milestone-form').valid()){ alert("POSTED"); return false; } else { alert("All Fields are required");} }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.js"></script> <form method="post" id="milestone-form"> <div id="fields" style="width:100%;"> <input type="text" name="milestone[]" placeholder="Milestone"> <input type="text" name="deadline[]" placeholder="Deadline"> <input type="text" name="amount[]" placeholder="Amount"> <input type="text" name="p[]" value="1" style="display:none;"> <span class="add halflings-icon plus">+</span> </div> <input type="submit" name="save-ms" class="btn btn-primary save-ms" value="Create"> </form> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM