jtheman
jtheman

Reputation: 7491

jQuery validation with unknown array key

Looking at the documentation here: http://docs.jquery.com/Plugins/Validation/Reference#Fields_with_complex_names_.28brackets.2C_dots.29 the syntax for attaching rules to input arrays is like this:

rules: {
"user[email]": "email",

However in my case the array keys are number values and could have any value, but still I'd like to attach the rule to the fields. I dynamically add input fields with jQuery (key is a global variable):

 $('a#addfield').click(function(e)
 {
    e.preventDefault();
    var data = '<p><input type="file" name="field['+key+']"></p>';
    $('div#inputcontainer').append(data);
 });

Sample HTML output:

<p><input name="field[19]" type="file"></p>
<p><input name="field[22]" type="file"></p>
<p><input name="field[25]" type="file"></p>

I have tried defining the rules like this:

rules: 
{
   'field[]': {
         required: true,
         extension: "pdf|doc|docx"
    }
}

(taken from this answer: jquery validate add rules for an array input EDIT: This suggested way of setting rules with 'field[]' is not working with the validation plugin. See answer and comments below. )

But there is no validation error when I try to add other filetypes... Any suggestions?

Upvotes: 3

Views: 2556

Answers (3)

Sparky
Sparky

Reputation: 98728

EDIT: My answer was posted on the original version of the question, where without reading comments, it was unknown that these fields are dynamically created. Otherwise, it may be preferred to simply add the rules as each field is created:

var myRule = { // save some code... put the common rule into a variable
    required:true,
    extension: "pdf|docx?"
};

$('a#addfield').click(function(e) {
    e.preventDefault();
    var data = '<p><input type="file" name="field['+key+']"></p>';
    $('div#inputcontainer').append(data);
    $('[name="field['+key+']"]').rules("add", myRule); // add the rule to the new field
});

(Nested brackets handled as per this answer.)

original answer follows:


The accepted answer gets you halfway there.

Also, my answer does not require an additional class or any other changes to your existing HTML structure. This is all jQuery...

The first half is to use the built-in rules('add') method.

$(element).rules("add", {
    required:true,
    extension: "pdf|docx?"
});

The second half is to get that method applied to all elements with named "field[19]", "field[20]", "field[21]", etc.

You simply use a jQuery .each() with a jQuery "starts with" selector.

$('[name^="field"]').each(function() {
    $(this).rules("add", {
        required:true,
        extension: "pdf|docx?"
    });
});

DEMO: http://jsfiddle.net/cWABL/

Upvotes: 1

Fabr&#237;cio Matt&#233;
Fabr&#237;cio Matt&#233;

Reputation: 70149

You can apply .rules("add", rules) to each generated element:

$(element).rules("add", { required:true, extension: "pdf|docx?" });

jQuery.validate does provide a way to validate elements with the same name (foo[] nor foo[N]) through the rules set on a form (at least up to v1.11).

There are some other ways for adding dynamic rules, for example, to add a required check without calling .rules('add') you can simply use class="required" in the element and the validation plugin should pick it up dynamically.

However, there is no built-in equivalent to the extension option so you'd have to add a class to all inputs and create your own class rules with addClassRules. This ends up mixing a bit of behavior with HTML and possibly CSS though.


Note for future readers: both .rules('add') and addClassRules do not work for repeated names (e.g. foo[]) but these do work if the name is not exactly the same (e.g. foo[index]) which is OP's case.

I believe inputs with the exact same name is off-topic for this question, but for these you either have to add your own validation method with addMethod, or add your own validation inside the form's submit handler or try this related answer.

Upvotes: 2

politus
politus

Reputation: 6086

I think the answer given is right, but it is also worth considering creating a class rule combining your two rules, then give your inputs this class. That way you don't have to call addMethod each time you dynamically add a new element to the DOM.

$.validator.addClassRules("myinput", { required:true, extension: "pdf|docx?" });

html

<input name="field[19]" type="file" class="myinput"> 
<input name="field[22]" type="file" class="myinput"> 
<input name="field[25]" type="file" class="myinput">

Upvotes: 1

Related Questions