Brenden
Brenden

Reputation: 8764

jQuery UI Autocomplete Cancel last query when typing

I am using jQuery UI autocomplete for a city search on my site. It starts to search after the user has entered 3 characters.

I'm wondering how to change this script to abort the last query if the user continues typing.

function enableCitiesAutocomplete() {
    var url = LIST.urls.api_cities_search;

    $('#txt_search_city').autocomplete({
        source: url,
        minLength: 3,
        select: function( event, ui ) {
            $(this).val( ui.item.value );
            $( "#id_city" ).val( ui.item.id );
            $(this).closest('form').submit();
        }
    });
}

Upvotes: 2

Views: 5650

Answers (1)

Cheeso
Cheeso

Reputation: 192507

I don't know if you can "abort" a completion that has already begun. But you may be able to get what you want by interrupting the render part of the autocomplete. This might work if the autocomplete consists of a query and a render, and the query involves a network transaction.
If there's a query and a render, and the query is just a search through a locally-stored list, then this probably won't work, because the latency is too low.

This SO question describes how to monkey-patch the renderMenu and renderItem fns in the jQuery autocomplete package. I'm thinking you can use the same monkey-patch approach.

You'd need to specify, as the source, a function, not a URL. This SO question describes how. Then, in that function, increment a count variable that says "a search is in process". Then perform the search by doing an "ajax get". Also patch the renderMenu to (a) only render if a single search is in process, and (b) decrement the search count.

It will probably look something like this:

var queriesInProcess = 0;
var ac = $('#txt_search_city').autocomplete({ 
    minLength: 3, 
    select : .... ,
    // The source option can be a function that performs the search, 
    // and calls a response function with the matched entries. 
    source: function(req, responseFn) { 
        var url = baseUrl + req.term;
        queriesInProcess++;
        $.ajax({
          url: url,
          //data: data,
          success: function(json,xhr) {
              queriesInProcess--;
              var a = ....retrieve from the json .... 
              responseFn( a ); 
            },
            errpr : function () { queriesInProcess--; },
          dataType: 'json'
        });
    } 
}); 

ac.data( "autocomplete" )._renderMenu = function( ul, items ) { 
  if (queriesInProcess > 0) return; 
  var self = this; 
  $.each( items, function( index, item ) { 
    self._renderItem( ul, item ); 
  }); 
}; 

If you want to get more sophisticated, you can also try to abort the pending ajax request. This would need to happen in the source function; you'd need to cache/stash the XHR returned from the $.ajax() call, and call abort() when a new one comes through.

Upvotes: 1

Related Questions