简体   繁体   中英

Parsley image dimensions validation

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:

  • Use a custom remote validator , and have the back-end take care of it. But that causes a small delay and hits the server for something that could be done client-side first.
  • Check the dimensions in my file input on change event listener and manually add a Parsley error by using the 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM