Question

I have a question regarding parsley.js v2.0.0 and the remote validation lib.

I'd like to custom remote validate a field and I don't know how to properly show the error message that is returned from my remote source.

The response from the server is a JSON formated string that is returned as plain text like this:

{ "error": "my custom error message" }

This is my form input and script:

<input type="text" id="UserLogin" maxlength="32" data-ajax-name="login" data-parsley-remote-options='{ "type": "POST",  "data": { "field": "login" } }' data-parsley-remote-validator="validateUsername" data-parsley-remote="1" data-parsley-trigger="focusout" name="data[User][login]" data-parsley-id="2315">

<script>
jQuery('#UserLogin').parsley().addAsyncValidator(
  'validateUsername', function (xhr) {
    return 200 === xhr.status;
    return 404 === xhr.status; 
  }, '/api/validationMethod'
);
</script>

In the parsley error container the default message "This value seems to be invalid" from the pattern property is shown but not the response from the server. How can I achieve that?

Était-ce utile?

La solution

Problem was solved by using the ParsleyUI methods.

<input type="text" id="UserLogin" maxlength="32" data-ajax-name="login" data-parsley-remote-options='{ "type": "POST",  "data": { "field": "login" } }' data-parsley-errors-messages-disabled="1" data-parsley-remote-validator="validateUsername" data-parsley-remote="1" data-parsley-trigger="focusout" name="data[User][login]" data-parsley-id="2315">

<script>
jQuery('#UserLogin').parsley().addAsyncValidator(
  'validateUsername', function (xhr) {
       var UserLogin = $('#UserLogin').parsley();
       window.ParsleyUI.removeError(UserLogin,'errorUsername');
       if(xhr.status == '200')
           return 200;
       if(xhr.status == '404')
           response = $.parseJSON(xhr.responseText);
           window.ParsleyUI.addError(UserLogin,'errorUsername',response.error);
  }, '/api/validationMethod'
);
</script>

Autres conseils

Currently, there is no standard built-in way in parsley remote to retrieve backend error message and show it frontend side. You'll have to work it yourself using maybe ParsleyUI here http://parsleyjs.org/doc/index.html#psly-ui-for-javascript to retrieve your ajax call content and attach the error to the validated field.

Doing some research and find more native/bulletproof solution.

Solution 1

Add async validator and return deferred object with error message from response.

import Parsley from "parsleyjs";

Parsley.addAsyncValidator('remoteMessage', function (xhr) {
    const response = xhr.responseJSON;
    if (typeof xhr.responseJSON.error !== 'undefined') {
        return $.Deferred().reject(xhr.responseJSON.error);
    }

    return true;
}, false, {
    type: 'POST'
});

HTML:

<input name="email" type="email" data-parsley-remote="http://127.0.0.1/validate_email.php" data-parsley-remote-validator="remoteMessage" />

Disadvantage of this, you have not enough control about ajax call(e.g. you can't cancel them to prevent multiple requests simultaneously).

Solution 2

More customizable ajax call with cancelling previous pending requests.

import Parsley from "parsleyjs";
import axios from "axios";

const cancelTokenSources = {};
Parsley.addValidator('ajax', {
    validateString: function(value, url, parsleyInstance) {
        const name = parsleyInstance.$element.attr('name');
        const data = new FormData();
        data.append(name, value);

        const cancelTokenSource = cancelTokenSources[parsleyInstance.__id__];
        if (typeof cancelTokenSource !== 'undefined') {
            cancelTokenSource.cancel();
        }

        cancelTokenSources[parsleyInstance.__id__] = axios.CancelToken.source();
        const deferred = $.Deferred();
        axios.post(url, data, {
            cancelToken: cancelTokenSources[parsleyInstance.__id__].token
        }).then(result => {
            if (typeof result.data.error !== 'undefined') {
                deferred.reject(result.data.error);
                return;
            }

            deferred.resolve();
        }).catch(() => {});

        return deferred;
    }
});

HTML:

<input name="email" type="email" data-parsley-ajax="http://127.0.0.1/validate_email.php" />

Resources:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top