I'm having trouble understanding how JQueryUI's autoplete function deals with repeated keypresses resulting in asynchronous results. I needed something with similar functionality to it, but I can't get the autopleted results to e in properly. An Example:
$(document).ready(function() {
$('#textinput').live('keyup', function() {
$.get('bacon.php', function(data) {
$('#holder').html(data);
});
});
});
The problem is that if type quickly, the results often do not e back in the right order. If I type the word 'KEY', I may get back results for 'K', then 'KEY', and then 'KE', messing up the content of #holder. I notice that the JQueryUI autoplete does not have this issue, but I can't understand how it handles it.
I'm having trouble understanding how JQueryUI's autoplete function deals with repeated keypresses resulting in asynchronous results. I needed something with similar functionality to it, but I can't get the autopleted results to e in properly. An Example:
$(document).ready(function() {
$('#textinput').live('keyup', function() {
$.get('bacon.php', function(data) {
$('#holder').html(data);
});
});
});
The problem is that if type quickly, the results often do not e back in the right order. If I type the word 'KEY', I may get back results for 'K', then 'KEY', and then 'KE', messing up the content of #holder. I notice that the JQueryUI autoplete does not have this issue, but I can't understand how it handles it.
Share Improve this question edited Jan 6, 2012 at 5:32 Sameera Thilakasiri 9,50810 gold badges53 silver badges87 bronze badges asked Jan 5, 2012 at 19:31 grobolomgrobolom 1011 silver badge15 bronze badges 1-
For at least v1.8.17, you can see how jQuery UI handles this where it defines the
source
from the given URL, specifically lines 264-267. – Jonathan Lonowski Commented Jan 5, 2012 at 19:51
3 Answers
Reset to default 8I haven't looked at jQuery's Autoplete functionality with respect to this particular issue, but what I do with my custom autopletion scripts is I abort the XHR request if another keypress has been hit within a certain time frame. Something like this:
var xhr, throttle;
$('.autoplete').keyup(function() {
var $this = $(this);
if (throttle)
clearTimeout(throttle); // Clear the previous request
xhr.abort(); // Abort the last XHR request
throttle = setTimeout( function() {
xhr = $.getJSON('autoplete.php', { data: $this.val() }, function(data) {
// do something with response
});
}, 250); // wait 250 milliseconds before running this
});
Basically, the throttle makes sure we wait 250 milliseconds before sending the request, in case the user is still typing (you can set this to whatever). The "xhr" variable keeps the XMLHttpRequest in a variable, and if we get another keypress and the response hasn't e back yet, then we abort the previous one, making sure that only the latest one actually es back with a response.
Hope that helps.
Good luck :)
I was JUST working on something very much relevant. A simple "delayed" API to convert a function into a delayed delegate.
Function.prototype.delayed = function(ms, reset)
{
var timeout;
var fn = this;
return function()
{
var args = arguments;
var scope = this;
if (reset && timeout) clearTimeout(timeout);
timeout = setTimeout(function() { fn.apply(scope, args) }, ms);
};
};
See fiddle for sample use.
In your case it would be like this
$(document).ready(function() {
$('#textinput').live('keyup', (function() {
$.get('bacon.php', function(data) {
$('#holder').html(data);
});
}).delayed(300, true));
});
Was having exactly the same problem, and stumbled the proxy pattern mentioned by Addy Osmani.
I think it's more relevant for a realtime observer event
$( "button" ).on( "click", function () {
setTimeout( $.proxy( function () {
// "this" now refers to our element as we wanted
$( this ).addClass( "active" );
}, this), 500);
});
Hope that helps