17

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

4
  • But the validation in the example you have giving is not working. Commented Jul 15, 2016 at 5:39
  • @SukhwinderSodhi it does work. Commented Jul 15, 2016 at 6:08
  • it works fine on First one but when new employer is added and you save it without filling the another employee it save the data Commented Jul 15, 2016 at 10:47
  • 1
    @SukhwinderSodhi please refer the answer as what you are saying was the problem to which I needed solution. Commented Jul 15, 2016 at 10:49

3 Answers 3

36

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
        }
    }
});
Sign up to request clarification or add additional context in comments.

9 Comments

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.
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.
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.
@SachinG, that's up to each developer. For this plugin, you must you .each().
Can you please expand your answer to show how a custom validation message can be set for these dynamic rules?
|
3

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

4 Comments

Right idea but seems a little more verbose than necessary.
@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.
My oversight. The existing one can be declared when the page is initialized or via inline HTML. Fixed my answer. Thanks.
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
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.