I have a file input field for which I want to validate minimum image dimensions (amongst other things). I'm using Parsley as my front-end validation library, so I'm trying to add a custom validator to do this.
Here is my custom validator code:
window.Parsley.addValidator('imagemindimensions', {
requirementType: 'string',
validateString: function (value, requirement, parsleyInstance) {
let file = parsleyInstance.$element[0].files[0];
let [width, height] = requirement.split('x');
let image = new Image();
image.src = window.URL.createObjectURL(file);
image.onload = function() {
return image.width >= width && image.height >= height;
};
},
messages: {
en: 'Image dimensions have to be at least %s px'
}
});
My HTML:
<input type="file"
name="upload-photo"
accept="image/*"
class="js-photo-upload"
data-parsley-validate
data-parsley-trigger="change"
data-parsley-imagemindimensions="300x300">
JS code to handle the file input change:
$(document).on('change', '.js-photo-upload', function() {
if ($(this).parsley().isValid()) {
// process image
}
});
Right now when running my validator, it always passes. I suspect that this is because Parsley can't deal with the asynchronous code block in image.onload
. Any ideas on how to solve this within the Parsley lib?
So far the solutions I've found are:
addError
method. But that's a bit of a hack and requires me to remove the error manually as well the next time the field gets validated. validateString
needs to return a Promise
. The onload
should fullfil or reject it instead of returning true/false
Based on Marc-André's answer I've updated my validator:
window.Parsley.addValidator('imagemindimensions', {
requirementType: 'string',
validateString: function (value, requirement, parsleyInstance) {
let file = parsleyInstance.$element[0].files[0];
let [width, height] = requirement.split('x');
let image = new Image();
let deferred = $.Deferred();
image.src = window.URL.createObjectURL(file);
image.onload = function() {
if (image.width >= width && image.height >= height) {
deferred.resolve();
}
else {
deferred.reject();
}
};
return deferred.promise();
},
messages: {
en: 'Image dimensions have to be at least %spx'
}
});
I then adapted my file input event listener in the following way:
$(document).on('change', '.js-photo-upload', function() {
$(this).parsley().whenValid({}).done(function () {
// process image
});
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.