I gather this must be a very common use case: user types into a textbox and lookups are made against a database displ开发者_StackOverflow社区aying choices. when the user is done (leaves the textbox), a determination is made as to whether the value entered was picked from the list (and therefore already exists in the database) and if it was nothing is done, otherwise the value entered is inserted into the database (since it's new).
problem is, clicking on the list of choices causes a /focusout/ which means that I don't know whether the user is leaving the textbox because he's done, or because he's choosing a value. therefore I don't have a good way of knowing when I should make my database insertion. If he types two characters and finds a match, clicking on the list of items will cause an insertion of the two characters.
I've opened a bug about it and found various others with similar problems but no resolution.
I can't think of a way around this problem. I'm using version 1.8.10 of jquery-ui. can anyone help?
The loss of focus is only momentary, you can start a timeout to delay submitting and cancel it if the field regains focus. The following example waits for 0.5 seconds before processing:
function BindTimeout($elem){
$elem.data('timer', setTimeout(function(){
$elem.removeData('timer');
if($elem.hasClass('autocomplete-open')){
BindTimeout($elem);
} else {
// Do whatever you need to do with the field value
}
}, 1000));
}
$('input').bind({
focus: function(){
clearTimeout($(this).data('timer'));
},
blur: function(){
BindTimeout($(this));
},
autocompleteopen: function(){
$(this).addClass('autocomplete-open');
},
autocompleteclose: function(){
$(this).removeClass('autocomplete-open');
}
});
Edit: When the focus is lost, it keeps checking wether the suggestion box is still open.
ok, after much wailing and gnashing of teeth, here's the answer:
- don't bother with the /select/ event of the autocomplete (it's completely useless when issued after a change (for the purpose of this exercise))
- set a flag when the list gets clicked on. use the /mousedown/ instead of /focus/ since this happens before the /blur/ of the textbox
- hook the database insertion code on the /change/ event of the text box, instead of the /blur/ (better semantics)
- implement a semaphore check on the change event
- implement a database existence check if semaphore check succeeds
- insert into database!
// step 2 $(".ui-autocomplete").mousedown(function() { ListExit = true; }) // step 3 $("#MyTextBox").change(function() { // step 4 if (ListExist) { ListExit = false; return; } // step 5 $.ajax({ url: "@Url.Action("List", "MyController")", data: {term: $(this).val()}, success: function(ls) { if (ls.length > 0) return; // step 6: do database insertion } }); });
精彩评论