jquery validate plugin on dynamic form inputs not working

I've a form where I'm having some fields and then if needed user can add more fields of same type. Im using http://jqueryvalidation.org/ validate plugin to validate fields.

As I read somewhere jquery validate plugin requires unique names to fields for validating them. So i'm naming each field uniquely. First I hoped that validate plugin will take care of dynamically added element's validation if I add rules using classes. But it turns out it does not.

So even if name of each field is unique, validate plugin validates only first input which was rendered initially.

I even tried using $.clone() in hope that it'll take care of all event bindings. But it did not worked for me. So I moved to underscore to repeat the markup as there are number of fields and I don't want to write templates in JS and name accordingly.

I can't find a solution to this and stuck here. Can't more on until this issue is resolved.

Here's JS that I've written.

$("#work_form").validate();

$(".work_emp_name").rules("add", {
    required: true
});

_.templateSettings.variable = "element";
var tpl = _.template($("#form_tpl").html());

var counter = 1;

$("form").on("click", ".add_employer", function (e) {
    e.preventDefault();
    var tplData = {
        i: counter
    };
    $("#word_exp_area").append(tpl(tplData));
    counter += 1;
});

Please find markup in fiddle set up.

example and code set up here


When using one of the methods from this plugin, like .rules(), and targeting more than one element, like a class, you must also use the jQuery .each() method.

$('.work_emp_name').each(function () {
    $(this).rules("add", {
        required: true
    });
});

And you cannot use .rules() on elements that don't yet exist in the DOM. Simply move the .rules() method to inside the function that creates your new inputs.

$("form").on("click", ".add_employer", function (e) {
    e.preventDefault();
    var tplData = {
        i: counter
    };
    $("#word_exp_area").append(tpl(tplData));
    counter += 1;
    $('.work_emp_name').each(function () { 
        $(this).rules("add", {
            required: true
        });
    });
});

Working DEMO: http://jsfiddle.net/Yy2gB/10/


However, you can make it more efficient by only targeting the one new field, instead of all fields with the work_emp_name class.

$("form").on("click", ".add_employer", function (e) {
    e.preventDefault();
    var tplData = {
        i: counter
    };
    $("#word_exp_area").append(tpl(tplData));   // <- add new field
    $('input[name="work_emp_name['+counter+']"]').rules("add", {  // <- apply rule to new field
        required: true
    });
    counter += 1;
});

Working DEMO: http://jsfiddle.net/Yy2gB/11/


Both of my examples above are for adding rules to the dynamically created fields. You'll still need to declare any rules for your static fields upon dom ready as follows...

$("#work_form").validate({
    rules: {
        "work_emp_name[0]": {
            required: true
        }
    }
});

Returns the validations rules for the first selected element or Adds the specified rules and returns all rules for the first matched element. Requires that the parent form is validated, that is, $( “form” ).validate() is called first or

Removes the specified rules and returns all rules for the first matched element. more info

function addRule(id){
    $("[name='work_emp_name["+id+"]']").rules("add", {
        required: true
    });
}
$("#work_form").validate();
addRule(0);

_.templateSettings.variable = "element";
var tpl = _.template($("#form_tpl").html());

var counter = 1;

$("form").on("click", ".add_employer", function (e) {
    e.preventDefault();
    var tplData = {
        i: counter
    };
    $("#word_exp_area").append(tpl(tplData));
    addRule(counter);
    counter += 1;
}); here

That's because jQuery Validation only validates the first occurrence of the array currently.

You can check my commit on the plugin that will just work fine on any occurrence of the named array.