Autocomplete More Than Just Text

Ryan Sonnek bio photo By Ryan Sonnek

If you run the scriptaculous autocomplete demo you’ll notice that one of the coolest features is that the results are not just plain text. They display a thumbnail image along with two pieces of text in a great looking layout. You might not realize it, but the current Wicket AutocompleteTextField in wicket-stuff already supports this behavior.

Now, you might be thinking, “That’s crazy? How can this be when the API only returns a String?”

protected abstract String[] getResults(String input);

Well, why not just return an HTML formatted string? Here’s some example code:

public AdvancedAutocompleteExampleForm(String id) {
    super(id);
    add(new AutocompleteTextField("emailAddress") {
        public String[] getResults(String input) {
      return new String[] {
          buildAutoCompleteContent("bill.gif", "Bill Gates", "bill.gates@microsoft.com")
    , buildAutoCompleteContent("ryan.gif", "Ryan Sonnek", "ryansonnek@notvalid.com")
            };
        }
    });
}

private String buildAutoCompleteContent(String image, String name, String emailAddress) {
  StringBuffer content = new StringBuffer();
  content.append("<div class=\"imageContent\">");
  content.append("<img src=\"" + image + "\" alt=\"" + name + "\"/>");
  content.append("</div>");
  content.append("<div class=\"nameContent\">");
  content.append(name);
  content.append("</div>");
  content.append("<div class=\"informal\">");
  content.append(emailAddress);
  content.append("</div>");

  return content.toString();
}

Yep, that’s it. Now in order for it to look good, you’ll have to attach some custom style sheet similar to scriptaculous.

public final void printHeadInitContribution(HtmlHeaderContainer container) {
  container.getResponse().write(
      "<style type=\"text/css\">\n" +
      " li.contact div.imageContent {\n" +
      "   float:left;\n" +
      "   width:32px;\n" +
      "   height:32px;\n" +
      "   margin-right:8px;\n" +
      " }\n" +
      " li.contact div.nameContent {\n" +
      "   font-weight:bold;\n" +
      "   font-size:12px;\n" +
      "   line-height:1.2em;\n" +
      " }\n" +
      " li.contact div.informal {\n" +
      "   font-size:10px;\n" +
      "   color:#888;\n" +
      " }\n" +
        "</style>\n");
}

Now for a bit more of scriptalicious magic. You might be wondering how the autocomplete text box figures out what text to use when a user selects the text from the drop down. After all, there are two separate text chunks to choose from. This is where the informal class name comes into play. When the user selects an auto complete entry, all informal chunks are ignored. This means that there should only be one piece of text content that is not informal.

I have committed this example example into wicket-stuff for anyone to use and to keep up to date with the ever changing AutocompleteTextField API.