How to have jQuery restrict file types on upload?

You can get the value of a file field just the same as any other field. You can't alter it, however.

So to superficially check if a file has the right extension, you could do something like this:

var ext = $('#my_file_field').val().split('.').pop().toLowerCase();
if($.inArray(ext, ['gif','png','jpg','jpeg']) == -1) {
    alert('invalid extension!');
}

No plugin necessary for just this task. Cobbled this together from a couple other scripts:

$('INPUT[type="file"]').change(function () {
    var ext = this.value.match(/\.(.+)$/)[1];
    switch (ext) {
        case 'jpg':
        case 'jpeg':
        case 'png':
        case 'gif':
            $('#uploadButton').attr('disabled', false);
            break;
        default:
            alert('This is not an allowed file type.');
            this.value = '';
    }
});

The trick here is to set the upload button to disabled unless and until a valid file type is selected.


You could use the validation plugin for jQuery: http://docs.jquery.com/Plugins/Validation

It happens to have an accept() rule that does exactly what you need: http://docs.jquery.com/Plugins/Validation/Methods/accept#extension

Note that controlling file extension is not bullet proof since it is in no way related to the mimetype of the file. So you could have a .png that's a word document and a .doc that's a perfectly valid png image. So don't forget to make more controls server-side ;)


For the front-end it is pretty convenient to put 'accept' attribute if you are using a file field.

Example:

<input id="file" type="file" name="file" size="30" 
       accept="image/jpg,image/png,image/jpeg,image/gif" 
/>

A couple of important notes:

  • The accept attribute is supported in Internet Explorer 10, Firefox, Opera, Chrome, and Safari 6.
  • It will show text for file extension differently in the file browser dialog from different browsers.

Don't want to check rather on MIME than on whatever extention the user is lying? If so then it's less than one line:

<input type="file" id="userfile" accept="image/*|video/*" required />