JQuery user interface autocomplete: cancel request

I am using the reverse version of the source option, which executes an ajax request. I believe that if the user types in a sequence of letters in quick succession before the ajax request is completed, we should abort the old one and use only the new one. I assume that the URL version for the source parameter will do this automatically, but since I use a custom callback, I will have to do it manually.

So here is what I have:

 $('#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 this input (it will be undefined for the first time), and if so, cancel it ( side question: how can I check if the request is complete ? It makes no sense to try to abort requests that have already been completed).

But the docs say :

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

So, at the bottom of my code you will see that I am trying to check if the request has been aborted, and if so, I will return an empty list. But this is "interrupted!" the magazine is never called. He always says β€œsuccess,” even when he is interrupted. Why?


Edit: Just tried the output of $(this).data('xhr').readyState . It seems to be less than 4 , which tells me that source not being called again until the last request returns a response. What a shame, because we can cancel requests earlier and speed up the response time a bit ...

+6
source share
2 answers

bdparrish has the right idea

Increase the timeout for the plugin before sending the request:

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

This way you will only send a request after you suspect that the user has finished typing. It is better to make fewer HTTP requests than do a lot and cancel them.

-Lededje

+4
source

Is there a reason why you cannot set a time interval to wait for the user to β€œshow” as if they had finished typing? The "delay" parameter sets the milliseconds that it will wait after the last letter is printed before the search.

In addition, the response will still be successful, even if you return β€œcancel” from the server. because the request did not fail on the server. you return the value "abort", which I assume.

0
source

Source: https://habr.com/ru/post/891256/


All Articles