AmpersandJS / ampersand-input-view

A view module for intelligently rendering and validating input. Works well with ampersand-form-view.
MIT License
17 stars 19 forks source link

Remote/async validation #18

Closed dignifiedquire closed 8 years ago

dignifiedquire commented 10 years ago

Hey, first of all great work with ampersand, really enjoying what I'm seeing so far. I have one question though, is there a way to do validation calls that are async in nature, i.e. by doing a server request?

wraithgar commented 9 years ago

I recently solved this problem in foundation/aspire and was able to port it over to ampersand:

http://code.gar.zone/?gist=945da953b7b2c0eacb35

codepunkt commented 9 years ago

@wraithgar Looks like an acceptable solution.

I'd still like to have an extended version of ampersand-input-view that allows reuse of valid and message properties in a defined way, adding the ability to have a serverside async validation.

codepunkt commented 9 years ago

My take on this:

http://requirebin.com/?gist=gonsfx/ab2409b11a71802c3da5

The default validation of ampersand-input-view remains unchanged. An asyncTest function can be defined. This function is run on input when there are no validation errors originating from the default synchronous validation.

The validityClass can now be one of validClass, invalidClass, pendingClass or '' - whenever an async test is pending, pendingClass is used (to style the input accordingly, e.g. displaying a loader icon).

When an async validation is started while the previous one is still pending, the previous one can be cancelled with the abortAsyncTest method. It defaults to a noop but can be overwritten to support, amongst others, abortion of xhr:

new AsyncInputView({
    label: 'Username', name: 'username', required: true,
    requiredMessage: 'A username is required',
    tests: [
        function (value) {
            if (value.length < 3) {
                return 'Username has to be at least 3 characters long';
            }
        }
    ],
    asyncTest: function (value, callback) {
        this.xhr = xhr({
            uri: 'http://localhost:8000/users/username/' + value
        }, function (err, resp) {
            callback(resp.statusCode === 404 ? 'Username exists' : '');
        });
    },
    abortAsyncTest: function () { this.xhr.abort(); }
})

What do you think?

cdaringe commented 8 years ago

Something like that could definitely be a good solution. If the code in the end is light we could keep it in this package, otherwise, maybe just make the async bits a mixin (which would require updates here too)