I've added autusuggest to ColdFusionBloggers.org and thought I'd talk a bit about how I did it (and about the problems I ran into).

First off - using autosuggest is extremely simple. All you have to do is take a standard input tag and switch it to a cfinput tag instead. Then just add the autosuggest attribute and your done. Thats it. Well, ok, you have to hook up the autusuggest to either a static list of suggestions, or to a dynamic data source.

For ColdFusionBloggers.org I decided the autusuggest would be based on previous searches. I added a logSearch() method to my entries CFC. This logged the search term and the time. I then added a method to return results based on what you type in the search box:

<cffunction name="getSearchHelp" access="remote" returnType="array" output="false"> <cfargument name="term" type="string" required="true">

<cfquery name="q" datasource="#variables.dsn#"> select distinct searchterm from search_log where searchterm like <cfqueryparam cfsqltype="cf_sql_varchar" value="#left(arguments.term,255)#%"> limit 0,10 </cfquery>

<cfreturn listToArray(valueList(q.searchTerm))>


Notice I used #term#% for my search, not %#term#%. Why? Remember that autusuggest is based on what you type. If you type "R", you should see suggestions that start with R.

Then I ran into my first problem. Notice the datasource is variables.dsn. My Application.cfc file had created and initialized an instance of entries.cfc. Guess what happened when I hooked up ColdFusion directly to the CFC? Because I was accessing the CFC directly, variables.dsn wasn't set properly. I fixed it by changing to application.dsn, which worked, but I wanted a nicer solution.

The cool thing about binds in ColdFusion 8 is that you can link to CFCs, JavaScript functions, and random URLs. So my cfinput which had been using a CFC:

<cfinput name="search_query" autosuggest="cfc:components.entries.getSearchHelp({cfautosuggestvalue})" maxResultsDisplay="10">

Was switched to this version:

<cfinput name="search_query" autosuggest="url:searchhelpproxy.cfm?term={cfautosuggestvalue}" maxResultsDisplay="10" showAutoSuggestLoadingIcon="false" size="10" />

I then added searchhelpproxy.cfm:

<cfif structKeyExists(url, "term") and len(trim(url.term))> <cfinvoke component="#application.entries#" method="getSearchHelp" term="#url.term#" returnVariable="result"> <cfoutput>#serializeJSON(result)#</cfoutput><cfabort> </cfif>

This file simply invokes the method I built but uses the Application scoped CFC instead. Notice that I have to format the result into JSON. Also note that Ben has blogged about some nice modifications made to autosuggest and cfselect bound controls.

If I have to do this again, I'll most likely create a more generic file that can handle different operations.

One last issue. I noticed that when I used the autusuggest control, it broke my layout a bit. I've pinged Adobe about this, but for now I've tried to make it work better by adding some style to my cfinput. In general I do not see a good reason why this should have any impact on layout, but maybe I did something wrong.

I've updated the code base again. You can download it on the FAQ at the site.