Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Autocomplete: Aborting the request

I'm using the callback version of the source option which performs an ajax request. I figure if a user types a bunch of letters in rapid succession before an ajax request completes, we should abort the old one and only use the new one. I'm assuming the URL version for the source parameter would do this automatically, but since I'm using a custom callback, I'd have to do that manually.

So here's what I've got:

$('#myselector').autocomplete({
    source: function(request, response) {
        var data = {};
        if($(this).data('xhr')) {
            console.log('aborting...');
            $(this).data('xhr').abort();
        }
        // *snip* add some stuff to data
        $(this).data('xhr', $.ajax({
            url: '/ajax/major_city',
            dataType: 'json',
            data: data,
            success: function(data, textStatus, $xhr) {
                response(data);
            },
            complete: function($xhr, textStatus) {
                console.log(textStatus);
                if(textStatus === 'abort') {
                    console.log('aborted!');
                    response([]);
                }
            }
        }));
    },
// ....

So, whenever the "source" callback is triggered, it checks if the XHR element exists for that input (will be undefined the first time), and if so, aborts it (side question: how can I check if the request is complete? No sense trying abort requests that have already completed).

But the docs say:

It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.

So, towards the bottom of my code you'll see that I (attempt to) check if the request has been aborted, and if so, I return an empty list. But that "aborted!" log never seems to be called. It always says "success" even when it gets aborted. Why's that?


Edit: Just tried outputting $(this).data('xhr').readyState. It never seems to be less than 4 which suggests to me that source isn't called again until the last request returns a response. Which is a shame, because we could abort the requests early and speed up the response time a bit...

like image 457
mpen Avatar asked Jun 24 '11 01:06

mpen


1 Answers

bdparrish has the right idea

Increase the time the plugin waits before sending the request:

$( ".selector" ).autocomplete({ delay: 500 }); //default is 300

This way you will only send the request once you suspect the user has finished typing. It's better to make less http requests than make many and cancel them.

-Lededje

like image 163
lededje Avatar answered Oct 04 '22 04:10

lededje