输入值不存在于parsley.js addAsyncValidator方法参数中

I'm having a hard time getting the value (live) of an input and pass it on addAsyncValidator method as a data. The addAsyncValidator always gets the value that has been set on the value attribute of an input when the page is rendered instead of the value of the input when it is changed. Here's my code:

Markup

        <form action="/edit/email" method="POST" id="my_form">
            <div class="row">
                <div class="col-lg-4">
                    <div class="form-group">
                        <label for="email">Email</label>
                        <input type="text"
                               class="form-control"
                               name="email"
                               id="email"
                               {{/* value="{{.User.Email}}" */}}
                               value="foo@bar.com"
                               data-parsley-required="true"
                               data-parsley-type="email"
                               data-parsley-whitespace="trim"
                               data-parsley-trigger="change"
                               data-parsley-remote
                               data-parsley-remote-validator="checkEmailTaken"
                               data-parsley-remote-message="">
                    </div>
                </div>
            </div>
            <button role="button" type="submit" class="btn btn-primary">Submit</button>
        </form>

JQuery

    $(function () {
        $("#my_form").parsley();

        $("#my_form").on("submit", function (e) {
            e.preventDefault();
            makeFormRequest(this); // Ajax call
        });

        Parsley.addAsyncValidator("checkEmailTaken", function (xhr) {
            if (404 === xhr.status) {
                r = $.parseJSON(xhr.responseText);
                this.addError("remote", { message: r.error });
            }
            return 200 === xhr.status;
        }, "/check/email/taken", {
                "data": {
                    "email": $("#email").val(), // The problem here is the val is always "foo@bar.com" even when input value is changed by the user
                    "id": "{{.User.ObjectID.Hex}}"
                }
            });
    });

The reason the email is always the same as what's in the input when your app is first loaded is because that's the value that you are passing in the options object as the last argument to addAsyncValidator.

That means that this code

{
    "data": {
        "email": $("#email").val(),
        "id": "{{.User.ObjectID.Hex}}"
    }
}

Is evaluated to this

{
    "data": {
        "email": "foo@bar.com",
        "id": "some hex value"
    }
}

...and then passed to the addAsyncValidator as the last argument.

To put in another way, $("#email").val() is evaluated only once and that's at the time when your js app starts, it is not evaluated every time the validator makes the xhr request.


Now as to how to do what you want, please note that I'm not a user of Parsley.js so I may be mistaken here, but from looking at the documentation it seems to me that:

The email's value that you want is already being sent automatically but because you're passing the options object with the same email key you're effectively overwriting the value you want with the value you don't want.

The docs on data-parsley-remote say (emphasis mine):

Define the url that will be called to validate the entered content. e.g. data-parsley-remote="http://url.ext". If the url contains the string "{value}", the value will replace it in the URL (typical of RESTful APIs), otherwise the value will be passed as a data parameter, with the key being the input's name or ID.

So if I understand the docs correctly it should be enough to do this:

$(function () {
    $("#my_form").parsley();

    $("#my_form").on("submit", function (e) {
        e.preventDefault();
        makeFormRequest(this); // Ajax call
    });

    Parsley.addAsyncValidator("checkEmailTaken", function (xhr) {
        if (404 === xhr.status) {
            r = $.parseJSON(xhr.responseText);
            this.addError("remote", { message: r.error });
        }
        return 200 === xhr.status;
    }, "/check/email/taken", {
        "data": {
            "id": "{{.User.ObjectID.Hex}}"
        }
    });
});