AJAX autocomplete
by ricardoz on Apr.17, 2008, under JavaScript, Tips, Web related
Using a nice AJAX auto completable input box is much nicer (for the user) than a combo box with 100 options. If you use jQuery, you may use a quite easy yet powerful plug-in called jquery.autocomplete (original, eh?). Grab it at http://www.pengoworks.com/workshop/jquery/autocomplete.htm.
Anyway, just to sum it up (you can learn how to use it in detail from the authors web page of course), I use it as follows:
1. First you need to bind the plug-in to the field(s) you want.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <script>
$(document).ready(function() {
$("#login").autocomplete("<html:rewrite page='/auth/users/autocomplete.action'/>", {
delay:10,
minChars:3,
matchSubset:1,
matchContains:1,
cacheLength:1,
autoFill:true,
formatItem:formatItem,
formatResult:formatResult
});
});
</script> |
The most relevant issues here are:
- The URL from where to get the auto-complete values (in this case a Struts action)
- The function to format the value displayed in the auto-complete list (formatItem)
- The function to format the value loaded into the input field once the user selects an option from the auto-complete list (formatResult)
The page that renders the auto-complete results (in this case autocomplete.action) can end in a JSP that looks something like:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><c:forEach items="${autocompleteList}" var="user">${user.name}|${user.login}</c:forEach>As you can see it renders one line per item in the list, printing the users name and login separated by a pipe. The autocomplete plugins parses this list, taking each line as a row and each field (delimited by pipes) as a property.
Then we can write the two format functions:
1 2 3 4 5 6 7 | function formatItem(row) { return row[0]; } function formatResult(row){ return row[1]; } |
Which will result in the plug-in showing the users names as auto-complete options, and when one is selected the users login will be loaded into our form input field.
If you want to be a little more fancy, you can add some highlighting to the text part of each auto-complete option that matches what is currently entered into the input field:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function formatItem(row) { return wrapSubstring(row[0], $("#login").val(), "<span class='autocompleteHighlight'>", "</span>"); } function wrapSubstring(original, substring, prefix, suffix, fromIndex){ var result = original; pos = result.toUpperCase().indexOf(substring.toUpperCase(), fromIndex); if (pos>=0){ result = result.substring(0, pos) + prefix + result.substring(pos, pos+substring.length) + suffix + result.substring(pos+substring.length); fromIndex = pos + suffix.length + prefix.length + substring.length; if (fromIndex<=result.length){ result = wrapSubstring(result, substring, prefix, suffix, fromIndex); } } return result; } |
November 10th, 2008 on 11:48 pm
Hi
This is the best hope I’ve seen that I can do this with Struts!
Do you find that response you get is the entire HTML code rather than just the JSON data?
December 8th, 2009 on 8:23 am
I have problem to implement this with dwr. Is there any way to handle asyc callbacks?
December 8th, 2009 on 1:50 pm
@pea: The jQuery plug-in expects the options in a pre-defined format (line based with pipe separated fields) so it’s not actually HTML.
@schweizer: The AJAX call is handled by jQuery, if you want to use DWR I’m sure you can but you’ll have to use a different approach, probably binding a specific event(s) to the input box and executing your DWR remote function when it happens.
May 1st, 2011 on 5:03 am
Hi, can you please put (or send me at majidnakit@yahoo.com) a war complete example using struts ?
Thanks your help is appreciated.
September 18th, 2011 on 8:41 pm
hello Ricardo, i would like to say that is very interesting and i am trying to undestand what you done, but i can not make it.
Can you the war?