Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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?

share|improve this question
    
From what I remember, jQuery.validate does not support validation of multiple fields with the same name like that, not even if you'd remove the numbers between brackets (which you can do when sending it to most back-end languages). Try using $('input').rules("add", { required:true, extension: "pdf|docx?" }) –  Fabrício Matté Mar 12 '13 at 13:56
    
Thanks! The input fields are added dynamically so I can't use your suggestion as the inputs are not in DOM. Also I'm using the array key to keep track of many things in the form so I can't just set name="field[]" which would work with the validation... –  jtheman Mar 12 '13 at 14:01
    
Use .rules("add", {}) for each dynamically generated field. There is no other option that doesn't involve uglier hacks. –  Fabrício Matté Mar 12 '13 at 14:02
    
Thanks. It worked. Add as your answer and I will accept. My solution was to add the rule for each dynamically added inputfield: $('input[name="field['+key+']"]').rules("add", { required:true, extension: "pdf|doc|docx" }); (key was my variable with the number...) –  jtheman Mar 12 '13 at 14:06

3 Answers 3

up vote 1 down vote accepted

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.

share|improve this answer
    
Whats the question mark in "pdf|docx?" ? –  jtheman Mar 12 '13 at 14:09
    
@jtheman In regex, ? makes the character preceding it optional. –  Fabrício Matté Mar 12 '13 at 14:10
1  
@jtheman Yes it is possible. =] addMethod is very handy if you need some custom validation. –  Fabrício Matté Mar 12 '13 at 14:17
1  
@jtheman Yes, I never got that syntax to work. It gives a false impression that it is working because the validation picks in the first element, but not the rest if you have more than one with the same name. –  Fabrício Matté Mar 12 '13 at 14:26
2  
@jtheman, Yes, in general "chameleon-questions" are a bad practice. However, in this case, simply editing your modest clarifications into your question would have been preferred over placing them in comments. Otherwise, one answer may be more relevant to solving your problem than a different answer that's more relevant to your OP. –  Sparky Mar 12 '13 at 18:05

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">
share|improve this answer
    
Thanks, this was what I initially was looking for! However now I stick to the previous solution (noone is paying me for changing it again...) :D +1 to you! –  jtheman Mar 12 '13 at 15:04

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/

share|improve this answer
    
Remember that fields are added dynamically. With this, if you plan to use this code whenever an input is added, you'd query the DOM multiple times unnecessarily re-adding rules that already exist for those elements. –  Fabrício Matté Mar 12 '13 at 15:30
    
@FabrícioMatté, you are correct. However, my answer only applies to the OP as it's presently written. If the OP could show the code that actually adds the field, perhaps a better answer can be provided. –  Sparky Mar 12 '13 at 15:38
    
Yes, your answer can help future visitors that have an issue to similar to the questioner's code. As for dynamically generated inputs that OP has, it is just a simple matter of replacing the loop with applying the .rules('add') to each generated input. –  Fabrício Matté Mar 12 '13 at 15:41
1  
@jtheman, I'm glad you got it figured out. I posted my answer, after you accepted the other, mostly as a service to the casual reader who may simply take the OP as written, without reading the comments. Thank-you! –  Sparky Mar 12 '13 at 18:08
1  
@jtheman, and in that same spirit, I've edited my answer to be more relevant to your specific situation. –  Sparky Mar 12 '13 at 18:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.