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
Hi Ray,
very nice the aggregator.
I was on the site new and the autosuggestion looks not working.
Andrea
Just added a new search term to the Auto Suggest, type B! Great example of the new auto suggest feature.
@Andrea - do you get JS errors? What browser?
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
The suggestion only works if someone already searched for it. So what you saw is what is expected.
HI,
may I ask you way is that?
Thanks
Andrea
Hi Ray,
Nice feature.
Shouldn't it only show previous searches that returned one or more results?
- Mikkel
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.
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?
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.
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. :)
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?
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..
BTW, my blog just got approved for MXNA today, bugger, I just missed getting into your blog export by a matter of days! :-)
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.)
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
sorry the word coldfusion is wrong
error "exception thrown and not caught"
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.
That last post was me - I messed up my name by tabbing too quickly.
Online example http://www.teamcapeholland2...
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.
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?
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 ..
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?
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 :-)
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. :)
Offtopic,
Your WDDX result are all the places in Holland... :-)
Little country ... :-)
Thank you
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.
I was wondering if anyone knows a fix for the issue with Autosuggest and IE7? Thanks much for any help!!
Ray, is there a way to get the autosuggest feature to work on a cfgridcolumn? (preferably in a Flash formatted cfgrid)
Ray: No idea - but I strongly urge you not to use Flash Forms anymore. The feature is way old and should be considered deprecated.
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.
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.