AutoSuggest Example

I’ve added autusuggest to 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 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">

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

&lt;cfreturn listToArray(valueList(q.searchTerm))&gt;

</cffunction> </code>

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.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA