5

I am trying to get jquery validate to work on multiple fields. Reason being I have dynamically generated fields added and they are simply a list of phone numbers from none to as many as required. A button adds another number.

So I thought I'd put together a basic example and followed the concept from the accepted answer in the following link:

Using JQuery Validate Plugin to validate multiple form fields with identical names

However, it's not doing anything useful. Why is it not working?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/lib/jquery.delegate.js"></script>
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/jquery.validate.js"></script>


<script>
  $("#submit").click(function(){
    $("field").each(function(){
      $(this).rules("add", {
        required: true,
        email: true,
        messages: {
          required: "Specify a valid email"
        }
      });   
    })
  });


  $(document).ready(function(){
    $("#myform").validate();
  });
</script>

</head>
<body>

<form id="myform">
  <label for="field">Required, email: </label>
  <input class="left" id="field" name="field" />
  <input class="left" id="field" name="field" />
  <input class="left" id="field" name="field" />
  <input class="left" id="field" name="field" />
  <br/>
  <input type="submit" value="Validate!" id="submit" name="submit" />
</form>

</body>
</html>
Community
  • 1
  • 1
hookenz
  • 36,432
  • 45
  • 177
  • 286

2 Answers2

9

This: $("field").each(function(){
Should be: $("[name=field]").each(function(){

Also your IDs should be unique, you'll get unpredictable behavior when this isn't true. Also, you should move the rule adding inside the document.ready, like this (this is now all your script):

$(function(){
  $("#myform").validate();
  $("[name=field]").each(function(){
     $(this).rules("add", {
       required: true,
       email: true,
       messages: {
         required: "Specify a valid email"
       }
     });   
   });
});
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • your solution just worked for me to select inputs in this way: $("[name^=foo][name$=bar]").each(function(). That would select the inputs whose name attribute starts with "foo" AND end with "bar", for example "foo_bar", but it doesn't work with "foobar"...:) – tirenweb Mar 30 '11 at 15:15
  • 1
    @user248959 - It should work fine for `name="foobar"` as well (since it meets the criteria), you can test it here: http://jsfiddle.net/nick_craver/fM52H/ – Nick Craver Mar 30 '11 at 16:50
  • @NickCraver , but it validates my first textbox only – Pratik Joshi Jul 01 '14 at 09:33
  • @PratikJoshi do you have the textboxes in individual forms, all with the same ID? That would have this behavior, but is not valid HTML - IDs should be unique. – Nick Craver Jul 01 '14 at 10:15
  • 1
    For this structure i tried , but did not work => – Pratik Joshi Jul 01 '14 at 10:23
  • I added This code but only first one (txtbox) gets validated => jQuery("input[type=submit]").click(function(){ //For custom Validation jQuery('input[name="videoTag[]"]').each(function(){ jQuery(this).rules("add", { required: true, messages: { required: "Add video URL" } }); //alert("counter"); }); //For Custom validation jQuery("#frmAddPlaylist").validate(); }); // validate the comment form when it is submitted – Pratik Joshi Jul 01 '14 at 10:23
  • @PratikJoshi the rules shouldn't be added inside the click handler, they should be there when the form anytime after the form elements are created/available. You should post a new question with the source of all your forms/fields along with that JavaScript - I can't see the structure from your comment, which is likely the actual issue. – Nick Craver Jul 01 '14 at 10:33
  • http://stackoverflow.com/questions/24508638/jquery-validate-for-multiple-fields-having-same-name – Pratik Joshi Jul 01 '14 at 11:02
  • Your answer is wrong . There is NO Solution . See What Sprky(Gold medal in jQuery-Validate) said "You cannot have multiple fields sharing the same name". Check http://stackoverflow.com/questions/24508638/jquery-validate-for-multiple-fields-having-same-name?noredirect=1#comment37953232_24508638 – Pratik Joshi Jul 02 '14 at 02:47
  • @PratikJoshi, actually, this answer shows a valid way to assign rules to multiple fields at once. However, since the selector, `$("[name=field]")`, is targeting a single `name`, it's technically incorrect. If the selector was tweaked, this answer would be 100% correct. However, everyone keep in mind that no matter how rules are assigned to fields, every field MUST contain a _unique_ `name` as that's how this plugin keeps track of each input. – Sparky Jul 02 '14 at 03:14
  • @PratikJoshi, See [this broken jsFiddle](http://jsfiddle.net/Lm3gz/) which demonstrates that you cannot have the same `name` on multiple fields. Now look at this [working jsFiddle](http://jsfiddle.net/D49MD/) where all fields have a unique `name`. Same technique from this answer is used in both. – Sparky Jul 02 '14 at 03:22
  • What to do if all field should share common error message instead of individual? – Shashank Bhatt Oct 11 '17 at 06:16
  • its targeting the first one only there is no solution with each function..only solution is if you change the function in jquery.vaidate.js file – Soubhagya Kumar Barik Jun 20 '18 at 05:10
0

@pratik JqueryValidation maintaining rulesCache, You need to modify core library.

elements: function() {
    var validator = this,
        rulesCache = {};

    // select all valid inputs inside the form (no submit or reset buttons)
    return $(this.currentForm)
        .find("input, select, textarea")
        .not(":submit, :reset, :image, [disabled]")
        .not(this.settings.ignore)
        .filter(function() {
            if (!this.name && validator.settings.debug && window.console) {
                console.error("%o has no name assigned", this);
            }

            // select only the first element for each name, and only those with rules specified
            if (this.name in rulesCache || !validator.objectLength($(this).rules())) {
                return false;
            }

            rulesCache[this.name] = true;
            return true;
        });
},

Just comment the rulesCache[this.name] = true;

elements: function() {
    var validator = this,
        rulesCache = {};

    // select all valid inputs inside the form (no submit or reset buttons)
    return $(this.currentForm)
        .find("input, select, textarea")
        .not(":submit, :reset, :image, [disabled]")
        .not(this.settings.ignore)
        .filter(function() {
            if (!this.name && validator.settings.debug && window.console) {
                console.error("%o has no name assigned", this);
            }

            // select only the first element for each name, and only those with rules specified
            if (this.name in rulesCache || !validator.objectLength($(this).rules())) {
                return false;
            }

            // rulesCache[this.name] = true;
            return true;
        });
},

If you don't want to change in core library file. there is another solution. Just override existing core function.

$.validator.prototype.checkForm = function (){
  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();
};
Adnan Haider
  • 265
  • 5
  • 16