I'm using jquery ui autocomplete widget with ajax, and on noticed the following problem.
Background: In order for the user to be able to focus on the autocomplete and get the options without typing anything, I use the focus event:
autoComp.focus(function() { $(this).autocomplete("search", "");}
However this produces the following effect: when the user clicks, an ajax request is being sent. While waiting for the response, the user then clicks elsewhere and the autocomplete is blurred. But as soon as the response returns, the options menu pops out, even though the autocomplete has no focus. In order to make it go away the user has to click once inside, and again outside the autocomplete, which is a bit annoying.
any ideas how I prevent this?
EDIT: I solved this in a very ugly way by building another mediator function that knows the element's ID, and this function calls the ajax function with the ID, which on success check the focus of the element, and returns null if it's not focused. It's pretty ugly and I'm still looking for alternatives.
EDIT#2: Tried to do as Wlliam suggested, still doesn't work.. the xhr is undefined when blurring. Some kind of a problem with the this keyword, maybe it has different meanings if I write the getTags function outside of the autocomplete?
this.autocomplete = $('.tab#'+this.id+' #tags').autocomplete({
minLength: 0,
autoFocus: true,
source: getTags,
select: function(e, obj) {
tab_id = $(this).parents('.tab').attr('id');
tabs[tab_id].addTag(obj.item.label, obj.item.id, false);
$(this).blur(); // This is done so that the options menu won't pop up again.
return false; // This is done so that the value will not stay in the input box after selection.
},
open: function() {},
close: function() {}
});
$('.tab#'+this.id+' #tags').focus(function() {
$(this).autocomplete("search", "");
});
$('.tab#'+this.id+' #tags').blur(function() {
console.log('blurring');
var xhr = $(this).data('xhr'); // This comes out undefined... :(
if (xhr) {
xhr.abort();
};
$(this).removeClass('ui-autocomplete-loading');
});
and this is the getTags function copied to the source keyword:
function getTags(request, response)
{
console.log('Getting tags.');
$(this).data('xhr', $.ajax({
url: '/rpc',
dataType: 'json',
data: {
action: 'GetLabels',
arg0: JSON.stringify(request.term)
},
success: function(data) {
console.log('Tags arrived:');
tags = [];
for (i in data) {
a = {}
a.id = data[i]['key'];
a.label = data[i]['name'];
tags.push(a);
}
response(tags);
}
}));
console.log($(this).data('xhr'));
}