Reputation: 3282
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"
},
}
});
Upvotes: 7
Views: 15304
Reputation: 21482
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">
</form>
<div id="imgContainer"></div>
Next, define a custom Validator method:
$.validator.addMethod('minImageWidth', function(value, element, minWidth) {
return ($(element).data('imageWidth') || 0) > minWidth;
}, function(minWidth, element) {
var imageWidth = $(element).data('imageWidth');
return (imageWidth)
? ("Your image's width must be greater than " + minWidth + "px")
: "Selected file is not an image.";
});
Notes:
.data('imageWidth')
on the file input element. We will be setting that value in code shown below. .data('imageWidth')
returns undefined
, the selected file is not an image.You can now use the minImageWidth
method like this:
var validator = $('.some_form').validate({
rules: {
photo: {
required: true,
minImageWidth: 500
}
},
messages: {
photo: {
required: "You must insert an image"
},
}
});
Finally, add a change-event handler for the file input that creates the <img>
element and adds it to the container. It will also set the .data('imageWidth')
value on the file input element.
var $submitBtn = $('.some_form').find('input:submit'),
$photoInput = $('#photoInput'),
$imgContainer = $('#imgContainer');
$('#photoInput').change(function() {
$photoInput.removeData('imageWidth');
$imgContainer.hide().empty();
var file = this.files[0];
if (file.type.match(/image\/.*/)) {
$submitBtn.attr('disabled', true);
var reader = new FileReader();
reader.onload = function() {
var $img = $('<img />').attr({ src: reader.result });
$img.on('load', function() {
$imgContainer.append($img).show();
var imageWidth = $img.width();
$photoInput.data('imageWidth', imageWidth);
if (imageWidth < 500) {
$imgContainer.hide();
} else {
$img.css({ width: '400px', height: '200px' });
}
$submitBtn.attr('disabled', false);
validator.element($photoInput);
});
}
reader.readAsDataURL(file);
} else {
validator.element($photoInput);
}
});
Notes:
.data('imageWidth')
value on the file input element.validator.element()
.<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.References:
Upvotes: 10