user2896120 user2896120 - 4 months ago 140
Javascript Question

Validating image dimensions using jQuery plugin

I have a form where validation occurs in jQuery's validation plugin. My form contains two elements, an input type=file and a submit button. The user will select an image, and if that image is less than 500px, it won't be accepted and an error message should be shown. I have made a new method for this called width, but it's not working for some reason. The error message is not shown when I try to submit an image less than 500px. Here's my jsfiddle.

HTML

<form class="some_form" enctype="multipart/form-data" method="post" action="">
<input type="file" name="photo" id="photoInput" />
<input type="submit">
</form>


jQuery

$.validator.addMethod('width', function(value, element) {
if ($(element).data('width')) {
return $(element).data('width') >= 500;
}

return true;
}, 'Image needs to be wider than 500px');

$(".some_form").validate({
rules: {
photo: {
required: true,
width: 500
}

},

messages: {
photo: {
required: "You must insert an image",
width: "Your image's width must be greater than 500px"
},
}

});

Answer

You can load the image file into an <img> element, and then get the width of that element.

First add a container element to your HTML to hold the <img> element:

<form class="some_form" enctype="multipart/form-data" method="post" action="">
  <input type="file" name="photo" id="photoInput" />
  <input type="submit" id="submitBtn">
</form>
<div id="imgContainer">
</div>

Now you can add a change-event handler for the file input that creates the <img> element.

var $submitBtn = $('submitBtn'),
  $photoInput = $('#photoInput'),
  $imgContainer = $('#imgContainer');

$('#photoInput').change(function() {
  $submitBtn.attr('disabled', true);
  $imgContainer.hide().empty();
  $photoInput.removeData('imageWidth');

  var file = this.files[0];

  if (file.type.match(/image\/.*/)) {
    var reader = new FileReader();

    reader.onload = function() {
      var $img = $('<img />').attr({ src: reader.result });

      $imgContainer.append($img).show();

      $img.on('load', function() {
        var imageWidth = $img.width();
        $photoInput.data('imageWidth', imageWidth);
        if (imageWidth < 500) {
          $imgContainer.hide();
        }
        $submitBtn.attr('disabled', false);
      });
    }

    reader.readAsDataURL(file);
  }
});

Notes:

  1. When the image is loaded, its width is placed as a .data() value on the file input element.
  2. While the image is loading, the submit button is disabled so the user cannot submit the form.
  3. You cannot get the width of the <img> element until it is added to the DOM. It must also be visible, but the code above shows how it can be hidden right after if desired.

Now you can set up a JQuery Validator method for testing the width of the element. Here's a generic method that calls a callback function:

$.validator.addMethod('callbackTest', function(value, element, params) {
  return params.callback(value, element);
}, 'Callback test failed');

And here's how it can be used for your situation:

$(".some_form").validate({
  rules: {
    photo: {
      required: true,
      callbackTest: {
        callback: function() {
          return ($photoInput.data('imageWidth') || 0) >= 500;
        }
      }
    }
  },
  messages: {
    photo: {
      required: "You must insert an image",
      callbackTest: "Your image's width must be greater than 500px"
    },
  }
});

jsfiddle


References: