5

I'm designing a website for a printing company. They want an image size/resolution checker that will let their customers upload an image they want to print, and tell them if the image resolution is good enough for printing.

I'm using Adobe Muse, so I need a simple HTML and CSS solution to this without any server-side requirements.

This is what I have so far, based on this question:

window.URL = window.URL || window.webkitURL;
$("form").submit(function(e) {
    var form = this;
    e.preventDefault(); //Stop the submit for now

   //Replace with your selector to find the file input in your form var
   fileInput = $(this).find("input[type=file]")[0];
   file = fileInput.files && fileInput.files[0];
   if (file) {
       var img = new Image();
       img.src = window.URL.createObjectURL(file);

        img.onload = function() {
            var width = img.naturalWidth, height = img.naturalHeight;
            window.URL.revokeObjectURL( img.src );
            if( width == 400 && height == 300 ) {
                form.submit();
            } else { 
                //stop
            } 
        }; 
    } else {
        //No file was input or browser doesn't support client side reading
        form.submit();
    }
});

However, I don't get any popup message. What am I doing wrong?

Community
  • 1
  • 1
George Gibson
  • 71
  • 1
  • 1
  • 5
  • So I can't have a simple code that practically says, if the image is smaller than 400x400 display this text or image but if image is or greater than 400x400 display this text or image? – George Gibson Oct 02 '15 at 17:58
  • Well I found this code that seems to read the dimensions before being uploaded to a server so I assumed it was possible? http://stackoverflow.com/questions/13572129/is-it-possible-to-check-dimensions-of-image-before-uploading – George Gibson Oct 02 '15 at 18:10
  • I didn't know that was possible. I stand corrected! Did you have a specific problem getting that code example to work? – Nate Barbettini Oct 02 '15 at 18:14
  • Well when I added it into muse the pop up with the dimensions didn't appear like it does in the demo... And I really just need to know how to code it so if they upload an image that is or grater than 400 X 400 it says wow you can use this and if it's lower than 400 X 400 it say oops you can't use this. Just don't know how to go about coding this? – George Gibson Oct 02 '15 at 18:26
  • Can you add the code you've tried so far? – Nate Barbettini Oct 03 '15 at 16:54
  • Part 1: window.URL = window.URL || window.webkitURL; $("form").submit( function( e ) { var form = this; e.preventDefault(); //Stop the submit for now //Replace with your selector to find the file input in your form var fileInput = $(this).find("input[type=file]")[0], file = fileInput.files && fileInput.files[0]; if( file ) { var img = new Image(); img.src = window.URL.createObjectURL( file ); – George Gibson Oct 03 '15 at 16:58
  • Part 2: img.onload = function() { var width = img.naturalWidth, height = img.naturalHeight; window.URL.revokeObjectURL( img.src ); if( width == 400 && height == 300 ) { form.submit(); } else { //stop } }; } else { //No file was input or browser doesn't support client side reading form.submit(); } }); – George Gibson Oct 03 '15 at 16:58
  • It's impossible to read code in comments, so I took the liberty of adding it to your question. Hope that's okay. (FYI, use the Edit feature in the future to edit your original question.) – Nate Barbettini Oct 03 '15 at 17:11
  • Yeah tried adding code but wouldn't let me? Did the control+K but still didn't work... Thanks though! – George Gibson Oct 03 '15 at 17:13

1 Answers1

5

Your code contains a number of errors, which is why it isn't working. (I don't think the submit event is even being bound to the form, because your jQuery selector doesn't look right: it should be #form or .form)

Here's a working solution:

HTML

<form id="form" action="destination.html">
    <input type="file" id="filePicker" />
    <br/>
    <input type="submit" value="Submit" />
</form>

JS

var _URL = window.URL || window.webkitURL;

function isSupportedBrowser() {
    return window.File && window.FileReader && window.FileList && window.Image;
}

function getSelectedFile() {
    var fileInput = document.getElementById("filePicker");
    var fileIsSelected = fileInput && fileInput.files && fileInput.files[0];
    if (fileIsSelected)
        return fileInput.files[0];
    else
        return false;
}

function isGoodImage(file) {
    var deferred = jQuery.Deferred();
    var image = new Image();

    image.onload = function() {
        // Check if image is bad/invalid
        if (this.width + this.height === 0) {
            this.onerror();
            return;
        }

        // Check the image resolution
        if (this.width >= 400 && this.height >= 400) {
            deferred.resolve(true);
        } else {
            alert("The image resolution is too low.");
            deferred.resolve(false);
        }
    };

    image.onerror = function() {
        alert("Invalid image. Please select an image file.");
        deferred.resolve(false);
    }

    image.src = _URL.createObjectURL(file);

    return deferred.promise();
}


$("#form").submit(function(event) {
    var form = this;

    if (isSupportedBrowser()) {
        event.preventDefault(); //Stop the submit for now

        var file = getSelectedFile();
        if (!file) {
            alert("Please select an image file.");
            return;
        }

        isGoodImage(file).then(function(isGood) {
            if (isGood)
                form.submit();
        });
    }
});

isSupportedBrowser() makes sure that the user's browser supports the required functions before attempting to check the image.

getSelectedFile() makes sure the user has picked a file, and then passes the file data back.

isGoodImage() takes the file data and attempts to construct an image element from it. If onerror is fired, it's not an image or is a corrupted file. If onload is fired, it does a sanity check to make sure the image has valid dimensions, and then validates that the resolution is above 400x400.

Since onerror and onload events are fired asynchronously, the function needs to pass back a promise indicating the result of the validation.

Finally, the submit handler on the form ties all these method calls together and only allows the form to submit if the resolution check comes back good.

Link to fiddle: http://jsfiddle.net/uwj85m7d/7/

Edit As requested, a variant that shows divs containing error messages instead of alert popups: http://jsfiddle.net/uwj85m7d/8/


Further reading:

Community
  • 1
  • 1
Nate Barbettini
  • 43,095
  • 21
  • 121
  • 135
  • 1
    That is absolutely fantastic! Just one other question... instead of an "alert" and pop up message, could it be linked it to a web page? or even better have an image appear underneath the submit button? – George Gibson Oct 03 '15 at 18:30
  • @GeorgeGibson Sure, that's easy! I added an additional example of showing hidden divs that contain a message. You could easily expand this to include images or styles as you need. If this helped, mind voting up the answer too? :) – Nate Barbettini Oct 03 '15 at 18:59
  • In the edited version i added the web page i wanted it to link to if it was correct, for testing purposes google at the moment and then changed the other two to actions and if no file was input but submitted it would go to yahoo and if the wrong file was submitted to go to bing but they all just want to google? am i doing something wrong there too? (sorry for my lack of knowledge, still learning in a way...) – George Gibson Oct 03 '15 at 19:20
  • actually when i just add a website destination into the top it then overrides all there other option and stops displaying the text and just goes straight to the destination for everything instead of just a correct image size.....? – George Gibson Oct 03 '15 at 19:26
  • @GeorgeGibson I'm confused as to what you are trying to do, sorry. Are you trying to *redirect* the user depending on the image validation, instead of displaying a message on the form? – Nate Barbettini Oct 03 '15 at 19:26
  • Yes, if the image is the correct dimensions i would like them to go to page "x" and if its the wrong dimensions i would like the user to go to page "y" and if their is no file input when submit is pressed display text saying "No file input"... does that make sense? Sorry for being bad at explaining as I said I'm still learning... :) – George Gibson Oct 03 '15 at 19:28
  • @GeorgeGibson And you want this all to happen when the form is submitted via the Submit button, or before? – Nate Barbettini Oct 03 '15 at 19:36
  • Via the submit button. So they upload image press submit then if image is correct size it goes to page "X" if image is wrong size goes to page "Y" and if no image has been uploaded and they press submit it displays "no file uploaded" – George Gibson Oct 03 '15 at 19:39
  • @GeorgeGibson Okay, should be easy. Make the "correct" page the form `action`, and use `window.location.href = "invalid.html"` to navigate to the "invalid" page instead of `$("#imageValidationError").show();`. – Nate Barbettini Oct 03 '15 at 19:50
  • okay so I've changed the $("#imageValidationError").show(); to window.location.href = "invalid.html" but i don't understand what you mean about make the "correct" page the form action? – George Gibson Oct 03 '15 at 20:13
  • @GeorgeGibson `action="destination.html"` means the form, when submitted, will redirect to `destination.html`. Change that to whatever you want your success redirect to be. – Nate Barbettini Oct 03 '15 at 22:52
  • I have done this, how do i change it so when they upload an image thats below the selected resolution it links to another page? As the window.location.href = "invalid.html"thing dosent work.... – George Gibson Oct 03 '15 at 22:59
  • I understand the "action=destination.html" i just don't understand how if the customer uploads a 300x300 image and the minimum image size is 400x400 how to link that to a different page? @NateBarbettini – George Gibson Oct 03 '15 at 23:08
  • @GeorgeGibson `window.location.href` works for me in the sample. Not sure why it's not working for you. Check for any errors in your Javascript console (F12) or post code in a fiddle. – Nate Barbettini Oct 04 '15 at 00:09
  • Do I have to change the the id? And stuff in the HTML? – George Gibson Oct 04 '15 at 00:10
  • @GeorgeGibson Nope, nothing but the aforementioned line of JS. – Nate Barbettini Oct 04 '15 at 00:11
  • Do I add the link address in where it says "invalid.html" ? – George Gibson Oct 04 '15 at 00:12
  • Okay I'm not near a computer at the moment so I will try it tomorrow and see what fiddle says etc. Thanks for all your help! You've been awesome and saved my life pretty much! I will let you know how I get on tomorrow too! – George Gibson Oct 04 '15 at 00:15
  • Okay, I've tried what you said and it still not working? heres a link to what I've done... http://jsfiddle.net/uwj85m7d/8/#&togetherjs=ltFNLVD5m3 – George Gibson Oct 04 '15 at 09:45
  • @GeorgeGibson It is identical to my example...? What did you try? – Nate Barbettini Oct 04 '15 at 22:22