16

I have the following:

<input id="user_profile_pic" name="user[profile_pic]" type="file">

On the server I check to make sure it's an image, but I want to check on the clientside first.

How with jQuery can I alert the user if the file input file selected isn't a gif,jpg,png, or bmp?

Thanks

6 Answers 6

30

You want to check what the value of the element is, something along the lines of:

$("#user_profile_pic").change(function() {

    var val = $(this).val();

    switch(val.substring(val.lastIndexOf('.') + 1).toLowerCase()){
        case 'gif': case 'jpg': case 'png':
            alert("an image");
            break;
        default:
            $(this).val('');
            // error message here
            alert("not an image");
            break;
    }
});

Edit

Code changed based on comment - now removes the value of the selected file if not an image.

5
  • Uncaught TypeError: Object #<an Object> has no method 'onchange' Commented Nov 19, 2010 at 6:40
  • .change works. But it's still no good, as while it errors, it still selects and is showing the file on the page. Commented Nov 19, 2010 at 6:42
  • Adding this worked, ".val('');" but I don't know how compliant that is... anyone? Commented Nov 19, 2010 at 6:44
  • 1
    .val(''); is a jQuery call, and all it does is set the value attribute of the element to be '' - which is the same is was on page load. Commented Nov 19, 2010 at 6:50
  • 1
    For googlers; AFAIK not all browsers allow you to reset a file input's value. The most elegant crossbrowser solution I have found is element.wrap('<form>').closest('form').get(0).reset(); element.unwrap();
    – Maurice
    Commented Jan 29, 2013 at 9:45
9

It's pretty simple not needed any JavaScript validations . Just write this and it'll accept only image files.

 <input type="file" multiple accept='image/*'> 
2
  • 3
    that's cool but it doesn't work as validation! it's just for easier handling to select an image from a folder with different extension. as you can see here -> imageshack.us/a/img20/8451/switchzz.jpg
    – bernte
    Commented May 24, 2013 at 17:36
  • One defining it in the HTML can be overridden in some browsers by choosing "all files" in the file dialog. Two, even though it in it of itself is not 100% fool proof, validating it with javascript is yet another appended deterrent in the fight against malicious activities. All in all you want to have your backend validate before accepting, and as an added bonus by checking and validating the first few bytes of the file to validate it is a type you really want, since by extension alone is never a fool proof means.
    – chris
    Commented Jul 9, 2015 at 20:47
7

You could use a regular expression:

var val = $("#user_profile_pic").val();
if (!val.match(/(?:gif|jpg|png|bmp)$/)) {
    // inputted file path is not an image of one of the above types
    alert("inputted file path is not an image!");
}

Of course you could add more formats to the regular expression. There are more complex and comprehensive ways to accomplish this, but this method will accomplish the task as long as the image file path inputted ends in a standard image file extension.

1
  • What if there are three input files and I want to validate them one by one? var val1=..., var val2=... var val3 =... if (!val.match(/(?:gif|jpg|png|bmp)$/)) {
    – alisa
    Commented Jan 27, 2015 at 22:42
1

There may be browsers that allow you to create a <img/> of the given path, by that you could check if it's a real image or not(if not the onerror-event should fire on the image and it will have a width/height of 0).

But as this only works in some browsers and is an security-risk(in my mind) I would'nt suggest to do this, so my answer is: you can't validate there anything.

Checking the file-extensions like suggested by Alex may be an option, but the file-extension does not guarantee if it's a image. However, as a simple pre-check(not validation) it could be useful.

1

How can we to check, that user selects image file?

  • By file extension validation
    It's work as expected, text file with .png extension pass here
  • input[type=file][accept=image/*] It initially hides non-image files from user. But this filter works by extensions too. And user still can manually enter any existing file name.
  • We can check mime type of result dataUrl, it starts with data:mimetype;base64,.... So, we need image/* mimetype.

    var file = $('#uploadfile');
    file.on('change', function (e) {
        var reader = new FileReader();
    
        reader.onload = function() {
            var data = reader.result;
            if (data.match(/^data:image\//)) {
                $('#thumbnail').attr('src', data);
            } else {
                console.error('Not an image');
            }
        };
    
        reader.readAsDataURL(file.prop('files')[0]);
    });
    
3
  • This does not work, change a none image e.g. .a pdf to a .png and it starts with data:image but is not an actual image.
    – Phil
    Commented Sep 9, 2019 at 12:21
  • none image sources have another mime types. pdf mentioned above, has data:application/pdf, for example
    – vp_arth
    Commented Sep 9, 2019 at 13:37
  • @Phil, what browser do you use? My chrome does not use file extension for mime type recognition.
    – vp_arth
    Commented Sep 9, 2019 at 13:41
1

You can try like this

// Image upload validation
$(document).on('change', ':file',function () {
    const file = this.files[0];
    const fileType = file['type'];
    const validImageTypes = ['image/jpeg', 'image/png'];
    if (!validImageTypes.includes(fileType)) {
        alert('Only JPEG and PNG file types are allowed');
        this.value = '';
    }
});

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