jquery validate plugin on dynamic form inputs not working

53,946

Solution 1

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

Solution 2

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

Solution 3

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.

Share:
53,946
SachinGutte
Author by

SachinGutte

Updated on August 19, 2022

Comments

  • SachinGutte
    SachinGutte almost 2 years

    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

  • Sparky
    Sparky over 10 years
    Right idea but seems a little more verbose than necessary.
  • nzn
    nzn over 10 years
    @Sparky in this jsfiddle.net/Yy2gB/9 your example basically you did same thing what i, just it will work only on new elements, not on existing ones.
  • Sparky
    Sparky over 10 years
    My oversight. The existing one can be declared when the page is initialized or via inline HTML. Fixed my answer. Thanks.
  • SachinGutte
    SachinGutte over 10 years
    just to save the time (or for now) I just added data-rule-required="true" in template itself. This also forces validation rules on dynamic elements. And I'm having like 8 fields which gets repeated on single click of Add Employer button ( designation, scope of work, start & end date, appointment letters and so on). So if I want to add rules to these fields as well then I'd have to write same code in Add Employer click listener. It's too much. Instead I chose data attributes method to add validation rules.
  • SachinGutte
    SachinGutte over 10 years
    But adding rules via data attributes does not give more control like if there are any fields that are depend on values of other fields. So your answer does fits all those scenarios as well and gives more control. So it's correct way. Thank you for taking time to solve this.
  • SachinGutte
    SachinGutte over 10 years
    Maybe it's vague question but isn't a plugin like validate should take care of dynamically added fields or adding rules with classes w/o using $.each in first place ? Now I know it's written quite great and have many options but I mean these are basic things that a plugin should be having.
  • Sparky
    Sparky over 10 years
    @SachinG, that's up to each developer. For this plugin, you must you .each().
  • geoidesic
    geoidesic about 8 years
    Can you please expand your answer to show how a custom validation message can be set for these dynamic rules?
  • Sparky
    Sparky about 8 years
    @geoidesic, the OP did not ask for that. Please see examples in the documentation for changing messages using the .rules() method.
  • user3631428
    user3631428 over 7 years
    How to add a function to remove the last add field decrementing? Thanks
  • Sparky
    Sparky over 7 years
    @user3631428, please post a new question rather than within comments.
  • Jordan Enev
    Jordan Enev about 7 years
    If you add array like fields with a same name then the validation don't work. There is an open issue: github.com/jquery-validation/jquery-validation/issues/1774
  • Alex
    Alex about 7 years
    What helped me was Requires that the parent form is validated... It's critical to run .validate() on the form before adding the rules, otherwise it won't work. Thanks, @nzn