My little grails SMS gateway is powering along. I’ve now integrated Yahoo autocomplete into my "New SMS" page and it works just great. Now my users can begin typing entries from their addressbook, and get that snazzy dropdown happening as they type. Even works with multiple elements when you type in a comma. Sample below:

Autocomplete in CyaThen.com

I’ve been really impressed with how customisable Yahoo have made it. You can wire up the datasource to be Ajax (which is the way I went since Grails makes the xml generation so easy), or an in-page array. You can apply all kinda fades and delays and caching and… well, check out their example page to see all the customise options.

Thought it might be useful to other grails guys to jot down the steps I needed to go through to get it happening. This only applied to Grails 0.2, the file might be already included in a future version.

1. You need to download the Yahoo components from sourceforge since Grails 0.2 didn’t include the autocomplete_min.js file that you need. Track down that file and copy it into the /web-app/js/yahoo directory in your grails app.

2. Edit the JavaScript TagLib.groovy and make sure the yahoo map is edited to include ‘yahoo/autocomplete-min’  (note their is no .js on the end of that one)

3. Inside the view that you want&nbsp;to have an autocomplete field, edit your html <head> element to include <g:javascript library="yahoo" /> which will pull in all the Javascript you need.

4. Add a script element that will tell wire up your input element to your backend XML datasource. Here’s what mine looks like:

<script>
    var myDataSource = new YAHOO.widget.DS_XHR("search", ["person", "name"]);
    myDataSource.responseType = myDataSource.TYPE_XML;
    var myAutoComp = new YAHOO.widget.AutoComplete('numbers','customcontainer', myDataSource);
    myAutoComp.delimChar = ","
</script>

This piece of magic tells the yahoo component to call my "search" action, and expect the returned XML to have an array of "person" elements, each with a "name" field to display. The autocomplete line wires up that datasource to my "numbers" input box using the empty "customcontainer" DIV to display the funky slidy autocomplete list.

5. Finally, you just need to create a Grails on your current controller to create the XML. You’ll get the user’s query is params.query and you need to return some well formed XML that the autocomplete can parse. With a builder that couldn’t be easier.

def search = {

  def str = params.query?.toUpperCase()
  println "Searching for $str";
  // do your custom stuff here
  render(contentType: "text/xml") {
    addressbook() {
        for (c in acc.contacts) {
            if (c.fullName().toUpperCase() =~ /${str}/ || c.mobile =~ /${str}/) {
                person() {
        	    name(c.fullName() + " (" + c.mobile + ")")
        	}
            }
         }
    }
  }
}

If I could work out a better way to make the regexps case insenitive that’d look a lot smoother… but you get the idea. Yahoo gives you some sample CSS which is the look and feel I’m using above, but you can customise with your own CSS class/id/whatever if you have the inclination. Very tunable.

Anyways, I give autocomplete the big tick. Huge props to the Yahoo guys for opening up this stuff. Loving every second of it.