AutoSuggest Example

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))>

</cffunction>

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.

Archived Comments

Comment 1 by Andrea posted on 7/21/2007 at 2:09 AM

Hi Ray,

very nice the aggregator.
I was on the site new and the autosuggestion looks not working.

Andrea

Comment 2 by Dan Vega posted on 7/21/2007 at 2:41 AM

Just added a new search term to the Auto Suggest, type B! Great example of the new auto suggest feature.

Comment 3 by Raymond Camden posted on 7/21/2007 at 5:07 AM

@Andrea - do you get JS errors? What browser?

Comment 4 by andrea posted on 7/21/2007 at 6:55 AM

Hi Ray,

I made some test.
First : I am using Firefox.

Example if a write the word : "very" I do not get any suggestion.
If I click search and I reload the page and I try again to search "very" I get the suggestion.

Looks almost a cache effect.....strange.

Bye

Andrea

Comment 5 by Raymond Camden posted on 7/21/2007 at 7:02 AM

The suggestion only works if someone already searched for it. So what you saw is what is expected.

Comment 6 by andrea posted on 7/21/2007 at 8:31 AM

HI,

may I ask you way is that?

Thanks

Andrea

Comment 7 by Mikkel Johansen posted on 7/21/2007 at 10:34 AM

Hi Ray,

Nice feature.

Shouldn't it only show previous searches that returned one or more results?

- Mikkel

Comment 8 by Raymond Camden posted on 7/21/2007 at 3:41 PM

Andrea, as I explained, the autosuggest returns suggestions based on previous searches. Therefore, you only see what other people have searched for.

Mikkel: Maybe. :) That would be more work though. Right now I just log everything you search for.

Comment 9 by Chuck posted on 7/21/2007 at 6:18 PM

Ray, looking at your code I see the opml.xml file. Where is the code that auto-retrieves the XML file on a daily or hourly basis? Or am I totally off the mark?

Comment 10 by Raymond Camden posted on 7/21/2007 at 6:42 PM

I don't. I only parsed it once. If I do indeed make this a 'real' site then I plan on having an admin to let me add feeds.

Comment 11 by Chuck posted on 7/21/2007 at 7:04 PM

I see. My vote is for a "real" site. In your opinion, can aggregator type site like this make money thru monetization?

Going to visit the Amazon wish list now. :)

Comment 12 by Raymond Camden posted on 7/21/2007 at 7:10 PM

Um, well, I don't know. I make money off my sites, obviously. I do this to help recoup the costs of the server, my time to write, etc. I'd do it for free, but I figure a few ads don't hurt, right? So can cfbloggers make money? Maybe. :) My thought was - if it took off - if people liked it - then I'd possible add an adsense and Text Link Ad pod.

Would that drive people away?

Comment 13 by Joshua Curtiss posted on 7/24/2007 at 3:15 AM

Ray:

Noob question.. Can you change the autosuggest attribute to:

cfc:components.entries.init().getSearchHelp({cfautosuggestvalue})

And inside, the init sets up the DSN? Or:

cfc:components.entries.init(myDSN).getSearchHelp({cfautosuggestvalue})

Just to avoid having the proxy page? If the JavaScript is just doing a URL method call of the CFC, this wouldn't work..

Comment 14 by Joshua Curtiss posted on 7/24/2007 at 3:18 AM

BTW, my blog just got approved for MXNA today, bugger, I just missed getting into your blog export by a matter of days! :-)

Comment 15 by Raymond Camden posted on 7/24/2007 at 5:03 AM

Joshua, in theory, that would "work", but it isn't helpful. My CFCs _are_ inited, but they are inited with variables, like DSN, to set them up. So this would have zero impact.

Does that make sense?

Now I _am_ curious to see if the syntax will work. I'll give that a try.

As for your blog - I promise - I'm going to add an admin, and if you remind me later, I'll add your blog to it. (I had to remove one manually today, it got taken over by a spammer.)

Comment 16 by Frank Gerritse posted on 8/13/2007 at 11:47 PM

Hi Ray

I have tried several options to use autosuggest but I get always the error "exception thrown and not caught coldfusion" can you tell me what I do wrong

Comment 17 by Frank Gerritse posted on 8/13/2007 at 11:49 PM

sorry the word coldfusion is wrong
error "exception thrown and not caught"

Comment 18 by u posted on 8/13/2007 at 11:55 PM

Do you have an example online where we can see?

I know I'll sound like a broken record, but the #1 tool in the world is Firebug. If you don't have it installed, install it, and see if it tells you something.

Comment 19 by Raymond Camden posted on 8/13/2007 at 11:55 PM

That last post was me - I messed up my name by tabbing too quickly.

Comment 20 by Frank Gerritse posted on 8/13/2007 at 11:58 PM
Comment 21 by Raymond Camden posted on 8/14/2007 at 12:02 AM

So using Firefox I see requests for:

http://www.teamcapeholland2...

Which is returning an empty string. As a quick test, make your CFC ALWAYS return some static data.

Comment 22 by Raymond Camden posted on 8/14/2007 at 12:03 AM

Wait - I alsosee a bunch of JS in the response. The response should ONLY be JSON. Something isn't right with your setup. Are you perhaps using onRequestStart or onRequest?

Comment 23 by Frank Gerritse posted on 8/14/2007 at 12:14 AM

Thnx for the quick responce I appreciate that

I have put a download link on the page so you can see the code. It is an very simple cfc request at this moment and that doesnt work.

I have tried your example but that doesn't work either, the same error.

I don't use onRequestStart or onRequest ...

and I get result from the query see the page agian ..

Comment 24 by Raymond Camden posted on 8/14/2007 at 12:21 AM

Here is what concerns me. Go here:

http://www.teamcapeholland2...

And above thw WDDX, which is expected, there is a bunch of JS includes. You _sure_ you don't have an Application.cfc or cfm in the request anywhere?

Comment 25 by Frank Gerritse posted on 8/14/2007 at 12:29 AM

SOLVED there was an lost <cfajaximport tags="cfwindow">
in the application file. I have removed it and it works ....

So you can put not such tag in the application.cfm file :-)

Thnx Now I can sleep well :-)

Comment 26 by Raymond Camden posted on 8/14/2007 at 12:32 AM

Well sure you can put it in there. Just check the request to see if you are asking for a CFC.

BUT - I wouldn't recommend putting it in anyway. :)

Comment 27 by Frank Gerritse posted on 8/14/2007 at 12:38 AM

Offtopic,
Your WDDX result are all the places in Holland... :-)

Little country ... :-)

Thank you

Comment 28 by Chris posted on 12/12/2007 at 4:41 AM

Using IE7 and I notice that the Autosuggest suggestions hide under your ad that is right below it. Not sure if this is an IE7 thing or a autosuggest thing. I'm having the same issue with my site where the autosuggest from a cfinput hides under a CFGRID instead of showing overtop.

Comment 29 by Kristan posted on 7/11/2008 at 2:57 AM

I was wondering if anyone knows a fix for the issue with Autosuggest and IE7? Thanks much for any help!!

Comment 30 by Ray Meade posted on 3/30/2012 at 12:25 AM

Ray, is there a way to get the autosuggest feature to work on a cfgridcolumn? (preferably in a Flash formatted cfgrid)

Comment 31 by Raymond Camden posted on 3/30/2012 at 3:28 PM

Ray: No idea - but I strongly urge you not to use Flash Forms anymore. The feature is way old and should be considered deprecated.

Comment 32 by JO w posted on 10/29/2012 at 8:23 PM

How do I get it so it doesn't automatically highlight the first value in the drop down. I want to user to select if they want the suggestion otherwise leave the value alone with what they are typing.

Comment 33 by Raymond Camden posted on 10/29/2012 at 8:41 PM

It has been a while since I used this code, but I don't think you can control that. The best I can recommend is what I'd do - check the CFML Syntax guide to see if there is a particular option for this.