12

I have a form that can have 0-hundreds of <input type="file"> elements. I have named them sequentially depending on how many are dynamically added to the page.

For example:

<input type="file" required="" name="fileupload1" id="fileupload1">
<input type="file" required="" name="fileupload2" id="fileupload2">
<input type="file" required="" name="fileupload3" id="fileupload3">
<input type="file" required="" name="fileupload999" id="fileupload999">

In my JQuery I want to validate these inputs on acceptable MIME/file type. Like this:

$("#formNew").validate({
    rules: {
        fileupload: {
            required: true, 
            accept: "image/jpeg, image/pjpeg"
        }
    }

Immediately my problem is that the name attribute of the input file elements is dynamic. It has to be dynamic so that my web application can deal with each upload correctly. So obviously using "fileupload" isn't going to work in the rules section.

How do I set the rules for all inputs which have a name like "fileupload"?

This is the code that dynamically adds the inputs:

var filenumber = 1;
$("#AddFile").click(function () { //User clicks button #AddFile
    $('<li><input type="file" name="FileUpload' + filenumber + '" id="FileUpload' + filenumber + '" required=""/> <a href="#" class="RemoveFileUpload">Remove</a></li>').prependTo("#FileUploader");
    filenumber++;
    return false;
});
$("#FileUploader").on('click', '.RemoveFileUpload', function () { //Remove input
    if (filenumber > 0) {
        $(this).parent('li').remove();
        filenumber--;
    }
    return false;
});

3 Answers 3

8

One the elements are added, use the rules method to add the rules

//bug fixed thanks to @Sparky
$('input[name^="fileupload"]').each(function () {
    $(this).rules('add', {
        required: true,
        accept: "image/jpeg, image/pjpeg"
    })
})

Demo: Fiddle


Update

var filenumber = 1;
$("#AddFile").click(function () { //User clicks button #AddFile
    var $li = $('<li><input type="file" name="FileUpload' + filenumber + '" id="FileUpload' + filenumber + '" required=""/> <a href="#" class="RemoveFileUpload">Remove</a></li>').prependTo("#FileUploader");

    $('#FileUpload' + filenumber).rules('add', {
        required: true,
        accept: "image/jpeg, image/pjpeg"
    })

    filenumber++;
    return false;
});
13
  • Thanks Arun really great. But the elements are added/removed dynamically whenever the user presses a button. There could be none, or 1, or whatever. When/where would I add the to the rules method? I tried adding it within the form submit event but its not working.
    – volume one
    Commented Jan 5, 2014 at 2:54
  • @volumeone can you share the code which is adding the element Commented Jan 5, 2014 at 2:59
  • 1
    Arun, it's a known condition. Maybe you should post a bug report to the jQuery Validate developer at GitHub... the methods for this plugin have always required containment within an .each() when targeting more than one: jsfiddle.net/8dAU8/3 ~ meanwhile, you should fix or delete the first half of your answer.
    – Sparky
    Commented Jan 5, 2014 at 4:47
  • 1
    As per documentation for .rules('add') method: "Adds the specified rules and returns all rules for the first matched element." ~ Also see this GitHub thread.
    – Sparky
    Commented Jan 5, 2014 at 4:54
  • 1
    @volumeone, minor details aside, the only relevant point here is that you use .rules('add') within your click handler immediately after creating the element. That's essentially the whole answer.
    – Sparky
    Commented Jan 5, 2014 at 20:00
3

So, I had the same issue and sadly just adding to the rules didn't work. I found out that accept: and extension: are not part of JQuery validate.js by default and it requires an additional-Methods.js plugin to make it work.

So for anyone else who followed this thread and it still didn't work, you can try adding additional-Methods.js to your tag in addition to the answer above and it should work.

2
  • Been scratching my head trying to get file validation to work, thank you for this answer! Commented May 28, 2016 at 4:06
  • I may be wrong but as of today (12/3/21) it seems like you don't need that extra "additional-methods.js" file. At least not in my case. Commented Dec 3, 2021 at 14:12
2

Simply use the .rules('add') method immediately after creating the element...

var filenumber = 1;
$("#AddFile").click(function () { //User clicks button #AddFile

    // create the new input element
    $('<li><input type="file" name="FileUpload' + filenumber + '" id="FileUpload' + filenumber + '" /> <a href="#" class="RemoveFileUpload">Remove</a></li>').prependTo("#FileUploader");

    // declare the rule on this newly created input field        
    $('#FileUpload' + filenumber).rules('add', {
        required: true,  // <- with this you would not need 'required' attribute on input
        accept: "image/jpeg, image/pjpeg"
    });

    filenumber++; // increment counter for next time

    return false;
});
  • You'll still need to use .validate() to initialize the plugin within a DOM ready handler.

  • You'll still need to declare rules for your static elements using .validate(). Whatever input elements that are part of the form when the page loads... declare their rules within .validate().

  • You don't need to use .each(), when you're only targeting ONE element with the jQuery selector attached to .rules().

  • You don't need the required attribute on your input element when you're declaring the required rule using .validate() or .rules('add'). For whatever reason, if you still want the HTML5 attribute, at least use a proper format like required="required".

Working DEMO: http://jsfiddle.net/8dAU8/5/

5
  • I've tried this and Firebug is showing an error of "TypeError: s is undefined" and the form breaks so the submit button doesn't work. No error is showing on the webpage itself.
    – volume one
    Commented Jan 5, 2014 at 21:01
  • 1
    i updated jsfiddle so you can see the issue jsfiddle.net/8dAU8/4 Try adding a txt or zip file and it doesn't show any error.
    – volume one
    Commented Jan 5, 2014 at 21:05
  • @volumeone, my mistake. You cannot increment counter until after the rule is declared. Take note that I removed a bunch of superfluous code.... see: jsfiddle.net/8dAU8/5
    – Sparky
    Commented Jan 5, 2014 at 21:21
  • stackoverflow.com/users/594235/sparky - So I notice that the validation does not updated on change of adding a file... It updates if the input is activated again or if the submit button is clicked. Is there a way to update the validation message on change to not be in an error state? Commented Sep 22, 2014 at 5:40
  • 1
    @isaacweathers, you would manually call the .valid() method when you need to trigger a new validation test.
    – Sparky
    Commented Sep 22, 2014 at 15:05

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