Reputation: 40633
I have an autocomplete text box that needs to respond to 2 events:
focusout
to assume when the user is done typing. So, if a user tabs out of a text box, it means the user is done typing.)select
event to determine that)The Problem:
When the user selects an item in the autocomplete list of values, the chain of event is such that focusout
is called first, then the select
. When in focusout
, I only have access to what the user typed, not what the user selected om the autocomplete list of values -- and that's what I actually need. How do I solve this problem?
Steps to Reproduce the Problem:
a
ActionScript
from the autocomplete list of valuesObserve console.debug messages:
focusout event called a select event called ActionScript
Here's the code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<title>Data Matching</title>
</head>
<body>
<form>
<input id="1" type="text"></input>
<input id="2" type="submit"></input>
</form>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script>
$('#1').autocomplete(
{
select: function (event, ui)
{
"use strict";
console.debug('select event called');
console.debug(ui.item.value);
},
source: ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Scheme"],
minLength: 1
});
$('#1').focusout(function ()
{
"use strict";
console.debug('focusout event called');
console.debug($(this).attr('value')); // At this point, I need the value that was selected from autocomplete. I only get the value that the user typed, though
});
</script>
</body>
</html>
Upvotes: 10
Views: 7137
Reputation: 126042
This is precisely why jQueryUI introduced a special change
event for autocomplete
:
Triggered when the field is blurred, if the value has changed; ui.item refers to the selected item.
This event can do double-duty for both of your requirements:
$("#1").autocomplete({
/* snip */
change: function(event, ui) {
if (ui.item) {
console.log("ui.item.value: " + ui.item.value);
} else {
console.log("ui.item.value is null");
}
console.log("this.value: " + this.value);
}
});
ui.item
will not be defined when the user did not select a value from the list of autocomplete candidates. this.value
will always be correct.Here's an example of this: http://jsfiddle.net/33GJb/
Upvotes: 8
Reputation: 54618
First off, just for educational purposes, it's important for anyone understand that these perticular events will always fire in this order. That being the case, I believe there are a few different ways you can solve the problem and here is what I came up with;
One: Build the application so multiple values selected by the user (type or selected) don't interfere. For instance, if the application is auto-correcting spelling, and someone typed "orphanag" on focusout the code that looked up the closest spelling would replace the value with "orphanage", than if someone actually selected "orphanages" it would then replace the value with the selected value. There most likely isn't an problem here, except the desire for over optimization.
Two: Have a flagged value either in Javascript or in the Html Element ("data-corrected=false") that exists. On FocusOut set a SetTimeout to wait a duration of time. Then if the users had selected a value, set your flagged value equal to true. When the duration is up, check the flagged value, if it is true don't do anything, else use the value in the input field for something.
Upvotes: 0