hookenz
hookenz

Reputation: 38879

Using jquery validate with multiple fields of the same name

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>

Upvotes: 5

Views: 28746

Answers (2)

Adnan Haider
Adnan Haider

Reputation: 265

@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();
};

Upvotes: 0

Nick Craver
Nick Craver

Reputation: 630379

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"
       }
     });   
   });
});

Upvotes: 9

Related Questions