Monday, June 28, 2010

grails-ui autocomplete with "onSelect" event

Today I had my first try in integrating an autocomplete feature. I was more successful than expected due to the very easy to use grails-ui library. You have to put code like that in your controller to serve data to the taglib:
def searchResultsAsJSON = {
     def jsonList = Gene.list().findAll{it.name.startsWith(params.query)}.collect{[id: it.id, label: it.name]}
     
     def jsonResult = [
         results: jsonList
     ]
     render jsonResult as JSON
 }

As you can see you need to provide your data JSON formatted. You also have to use the parameter "query" to filter results that fit what the user has already typed in. Furthermore you can collect only those properties of your domain class that are really necessary for the autocomplete. These are namely an id and a label to display and search. Okay now that we've seen this part, let's have a look at the GSP:

<gui:autoComplete
            minQueryLength="3"
         queryDelay="0.5"
         id="quickSearch"
         resultName="results"
         labelField="label"
         idField="id"
         controller="quickSearch"
         action="searchResultsAsJSON"
  />

Here you can see different options that you can influence, e.g. how many letters one has to type in before the taglib starts AJAX-calling. Although more or less self-explaining, I will say a few words about those properties:
  • idField is the name of the ID field in the JSON output
  • labelField is the name of the label that is displayed for search in the JSON output
  • resultName is the name of the top node used in JSON. In the above example this was results.
At this stage I was already quite happy with my results, but I wanted one more feature that was unfortunately not included. I wanted to define some action when a selection has been made by the user. Therefore I added some javascript to the page:

YAHOO.util.Event.onDOMReady(function() {
   GRAILSUI.quickSearch.itemSelectEvent.subscribe(function(type, args) {
      ${remoteFunction(controller:"quickSearch", action:"showResult", params: '\'name=\'+GRAILSUI.quickSearch.getInputEl().getValue()', update: [success:'body',failure:'body'])};
   });
 });

It took some time to find out how to do this, but finally it worked. What one has to know is:

What event do I have to subscribe to and even more complicated how do I access information about the selected entry? The event's name was itemSelectEvent and I managed to access the DOM element to get the selection's value, but I would be very interested to access the ID of the selected entry, too. Up until now, I could not find the ID anywhere in the DOM. Any comments on this problem are welcome!

No comments:

Post a Comment