Blog

31May
2007
ColdFusion Ajax Tutorial 1: Auto-Suggest

I plan to post a series of examples demonstrating how to use the new Ajax functionality in ColdFusion 8 (many based on examples used during our recent usergroup tour). The first one I'll start with is the auto-suggest control. Auto-suggest is a modified text input box, one that displays suggestions as the user types. The auto-suggest control in ColdFusion 8 can be used in two ways, with local client-side data, and with asynchronous calls back to ColdFusion.

Here's a simple client-side data example (which uses one of the CF8 example databases, so this should work for you as is):

view plain print about
1<!--- Get data --->
2<cfquery datasource="cfartgallery" name="data">
3SELECT artname
4FROM art
5ORDER BY artname
6</cfquery>
7
8<!--- The form --->
9<cfform>
10Art:
11<!--- Populate auto-suggest control --->
12<cfinput type="text"
13        name="artname"
14        autosuggest="#ValueList(data.artname)#">

15</cfform>

This form displays a simple text box, but as text is entered, suggestions are displayed. The list of suggestions are passed to the autosuggest attribute which accepts a comma delimited list. The list could be hardcoded, but here ValueList() is being used to dynamically build a list based on a prior database lookup.

This is not an Ajax control in that lookups are not asynchronous, there is no communication back to the server to retrieve data, all data is local. This is actually a preferred form of auto-suggest for smaller lists.

For longer lists asynchronous interaction is indeed preferred, and the auto-suggest control supports this by allowing asynchronous calls to a ColdFusion component. Here is a sample CFC:

view plain print about
1<cfcomponent output="false">
2
3<cfset THIS.dsn="cfartgallery">
4
5    <!--- Lookup used for auto suggest --->
6    <cffunction name="lookupArt" access="remote" returntype="array">
7 <cfargument name="search" type="any" required="false" default="">
8
9 <!--- Define variables --->
10 <cfset var data="">
11 <cfset var result=ArrayNew(1)>
12
13 <!--- Do search --->
14 <cfquery datasource="#THIS.dsn#" name="data">
15 SELECT artname
16 FROM art
17 WHERE UCase(artname) LIKE Ucase('#ARGUMENTS.search#%')
18 ORDER BY artname
19 </cfquery>
20
21 <!--- Build result array --->
22 <cfloop query="data">
23 <cfset ArrayAppend(result, artname)>
24 </cfloop>
25
26        <!--- And return it --->
27 <cfreturn result>
28    </cffunction>
29    
30</cfcomponent>

This CFC has a single method named lookupArt which accepts a string and performs a query to find all matches that start with the specified value. Auto-suggest requires that results be returns in a single dimensional array (for now, hopefully this will change before we ship the final product), and so the code populates an array with the results which are then returned.

Now for the modified form code to use this CFC and method:

view plain print about
1<cfform>
2Art:
3<cfinput type="text"
4        name="artname"
5        autosuggest="cfc:art.lookupArt({cfautosuggestvalue})">

6</cfform>

Here the autosuggest points to a CFC, and as the CFC (I named it art.cfc) is in the current folder, no path needs to be specified. When a user enters a value, generated JavaScript code triggers an asynchronous calls to the lookupArt method in art.cfc. {cfautosuggestvalue} gets automatically replaced with whatever value the user has entered, and that value is then used by the CFC in the lookup. When an array of results get returned the auto-suggest list gets populated.

Auto-suggest does not get any cleaner and simpler than this.

Related Blog Entries

Comments (101)



  • Ken Dunnington

    Thanks for the example Ben. This might seem like an odd question, but could you, in theory, replace {cfautosuggestvalue} with some other binding expression? I can't think of a good reason off-hand, but seeing it there makes me curious what would happen. Actually, I suppose I'll go try that out now. :)

    #1Posted by Ken Dunnington | May 31, 2007, 12:36 PM
  • Ben Forta

    Ken, yes, you sure can.

    --- Ben

    #2Posted by Ben Forta | May 31, 2007, 01:20 PM
  • Kevin Sargent

    I've been playing with stuff most afternoon.

    Downright awesome how easy it is to get it to do these things!

    If only there was a cfinput type="file" with a upload progress meter....

    #3Posted by Kevin Sargent | May 31, 2007, 06:16 PM
  • Aylon Glaser

    Nice example. Is the autosuggest customizable? Is the style of the text displayed customizable (font, size, color) etc...?

    #4Posted by Aylon Glaser | Jun 5, 2007, 10:06 PM
  • Michael

    That's what I would like to know. Is the Autosuggest CSS customisable? I noticed in the source code CF puts in some style sheets but is it possible to over-ride these mainly for the reason that I and many others will be on a shared hosting environment and not able to modify the CSS on the server.

    #5Posted by Michael | Jun 6, 2007, 03:52 PM
  • Simon

    Hi Ben,

    I notice that if you put a DIV around all of your code and align it to center only the word Art: is centered. The form field remains on the left. Looks like a CSS issue (not your code's fault though).

    Cheers for being a great CF evangelist.

    Simon

    #6Posted by Simon | Jun 9, 2007, 04:43 PM
  • Ashwin

    The CSS is completely customizable. Copy the directory structure under CFIDE/scripts/ajax/resources to your application folder, and modify the CSS and images in there to suit your needs. Then put this line at the top of your template:
    <cfajaximport cssSrc="path to your resources folder">

    #7Posted by Ashwin | Jun 11, 2007, 12:42 AM
  • Nik

    This fails if you enter a number. The autosuggest bind errors because it is not a string. Is this a bug in the autosuggest? If not, how would one avoid the issue?

    #8Posted by Nik | Jun 25, 2007, 09:20 PM
  • Ashwin

    Thanks, Nik - we are aware of this problem, it's already been fixed for the final release.

    #9Posted by Ashwin | Jun 26, 2007, 04:51 AM
  • Chris

    Is there a way to search within the string instead of from the beginning?

    If I had a list of names with last name, "SMITH", I'd want to type smith within the input field and get a listing of everyone with smith in their name.

    Is this possible? I know it's possible with SPRY Autosuggest, just wondering if they're porting this over to CF8.

    Thanks!
    Chris

    #10Posted by Chris | Jul 10, 2007, 03:25 AM
  • Manuel Vergel E.

    How can i run online this example.

    #11Posted by Manuel Vergel E. | Jul 22, 2007, 11:38 PM
  • Kruse

    Hi Ben,

    I have just tried this Ajax Tutorial.
    But I cannot locate the cfc.
    I have created the Artists.cfc and it is located in the same directory as the cfm code.
    But when it runs I get an
    error:http: Error invoking CFC /Art.cfc : Not Found

    What is wrong?

    #12Posted by Kruse | Jul 31, 2007, 06:51 AM
  • Don

    This CF capability is very very neat. From reading and copying/pasting from one box to another (that has cf8 installed) and everything else, about 15 minutes. It works like a beauty.
    Thanks, man.

    #13Posted by Don | Sep 13, 2007, 10:46 AM
  • David

    Is there a way to use this if you wanted to allow the user to input multiple values into the field, separated by commas, and still have the auto-suggest offer suggestions for each value they type? So if the user were to input "Apples, Oranges, Bananas" into the field. The auto-suggest would display the drop down suggestions for each. Not sure if that's possible or not with the built in functionality. There would need to be a way to have it check against the auto-suggest list each time a comma was typed in the field.

    #14Posted by David | Sep 20, 2007, 05:51 PM
  • Eric Brown

    I'm having trouble implementing the autosuggest feature with a cfc. specifically, while I can make it function - it doesn't function correctly. The autosuggest will only suggest every other keystroke. I can force the lookup on the alternating key strokes if I key the delete key after the stroke that results in no lookup - but this seems counter productive to say the least. I have also noticed that it will throw a bind error occasionally if say I use the arrow key to navigate.
    I'm unsure why any of this occurs. I'd also love to know how to force the bind errors to cease popping up as in a real world environment I'm not likely to want customers seeing errors that they can't do anything about.

  • Marcelo Lewin

    Ok. Here is my issue.

    I created a simple .cfc called suggest.cfc. I store it in this directory:

    c:\websites\sms\cfc\suggest.cfc

    Then I created a simple cfm file with <CFINPUT> and did the autosuggest that you mention calling the cfc. I call it by putting the following:

    <cfinput type="text" name="cust_search" autosuggest="cfc:sms.cfc.suggest.getCustomers({cfautosuggestvalue})">

    I store this .cfm under:
    c:\websites\sms\labs\ajax\autosuggest.cfm

    Then I run this file.

    I get an AJAX error (I used ?cfdebug) that it cannot find the suggest.cfc web service. So I do a view source, and I see the following code:

    ColdFusion.Bind.cfcBindHandler(null, {'bindTo':ColdFusion.Autosuggest.loadAutoSuggest,'bindToAttr':'true','cfc':'/suggest.cfc','cfcFunction':'getCustomers','bindExpr':[['searchstring',cfautosuggestvalue]], 'bindToParams': { 'autosuggestid':"cust_search" }});

    Notice the "/suggest.cfc". When I save the source as a CFM, change the /suggest.cfc to /sms/cfc/suggest.cfc it works like a charm.

    Why is it calling in AJAX /suggest and not the directory path I stated in the dot notation in the CFC.

    Any help would be greatly appreciate it.
    Thanks!
    Marcelo
    marcelo@thedigitalmediadude.com
    http://www.thedigitalmediadude.com/

  • Mark CE

    I am having exactly the same "autosuggest will suggest every other keystroke" problem as Eric Brown posts above. I have to say that in my experience the CF8 autosuggest is the very worst autosuggest I have EVER seen! Does anyone know a reason for the every other keystroke problem? Is it due to slow query in the CFC?

    #17Posted by Mark CE | Oct 31, 2007, 07:02 AM
  • Ed

    We are having the same exact problem that Marcelo describes above...

    The path that we specify in our cfm file does not propogate properly into the the javascript that is built by ColdFusion.

    Perhaps this is a configuration error? (BTW: we are not mapping our cfc directory)

    We use IIS on Windows 2003 Enterprise server.

    Please help.

    #18Posted by Ed | Nov 1, 2007, 10:37 AM
  • Ed

    We found our problem... using 'Virtual Directories' in IIS, the ColdFusion AJAX feature binding won't work (it just can't seem to find the cfc file). When the same files are installed on the web root, it works 100%.

    What really threw us off was that, with our original configuration, the cfc's were accessible via a cfinvoke and via the url...

    Unfortunately, it will be alot of work to re-configure our other webservers so that we can utilize these new features.

    #19Posted by Ed | Nov 1, 2007, 04:51 PM
  • Jesbin

    Hi Ben,
    I'm having the same problem as Kruse. I've the cfc inthe same directory as the cfm but i keep getting:

    Error invoking CFC /<name>.cfc : Not Found

    but when i introduce some error to the function in the cfc (such as a required parameter) the error is immidiately detected and flagged, which indicates that the cfc is being found.
    regards,
    Jesbin

    #20Posted by Jesbin | Nov 11, 2007, 07:54 AM
  • Ben Forta

    Can you invoke the CFC directly using a URL (passing method= as a parameter)?

    --- Ben

    #21Posted by Ben Forta | Nov 11, 2007, 08:17 AM
  • Eric Brown

    We've somewhat addressed the autosuggest feature only suggesting on every other keystroke - however, not being a javascript guru, I'm sure there's more that needs to be addressed.

    Specifically, in the cfautosuggest.js file located in CFIDE/scripts/ajax/package - on or about line 68 - this code is what causes the issue:

    if(!_bf.isContainerOpen()&&_c0.length>0&&(arg.keyCode>31||(arg.keyCode==8&&_bf.valuePresent==true)))

    If you change it to not check the Open Container - as follows:

    if(_c0.length>0&&(arg.keyCode>31||(arg.keyCode==8&&_bf.valuePresent==true)))

    it should now function (at least most of the time).

    Hope that helps.

  • Jesbin

    Hi Ben,
    I can invoke the CFC directly using the URL and also invoke methods using the CreateObject("component",...). Another thing I found out was that if I put the CFC in the webroot it seems to work but if I put it in the virtual directory it says CFC not found. Is that the normal behaviour. I thought CFC's could be placed anywhere and referenced using the path syntax.
    regards,
    Jesbin

    #23Posted by Jesbin | Nov 12, 2007, 11:20 AM
  • Ben Forta

    Jesbin, I'd have thought that if the URL works from the browser than it should work from the JavaScript client side code. If it were outside the web root, then yes, I'd expect it to just be available on the server itself but not from outside the server, which is why I asked you if a direct URL invocation from the browser works. I am going to pass this one on to the engineering team to see if they have any comments or suggestions.

    --- Ben

    #24Posted by Ben Forta | Nov 12, 2007, 12:18 PM
  • Tim

    Our team is trying to get cfajaxproxy to work as well, so far netting the same problem as posted by Jesbin: "Error invoking CFC /xxxx.cfc: Not Found". Invoking the xxxx.cfc from browser works fine. Our mappings are all correct. We're thinking that perhaps the fact that our web server (IIS v6) and CFMX v8/JRun servers are running on separate boxes may be the culprit.

    #25Posted by Tim | Nov 15, 2007, 12:40 PM
  • Jesbin

    Tim,
    Just to let you know, in my case the web server and the CFMX/v8 are on the same machine and still the error exists.
    Jesbin

    #26Posted by Jesbin | Nov 16, 2007, 02:56 AM
  • Ben Forta

    Several of you have run into an issue where web browsers can invoke the CFCs, but the same CFC cannot be invoked from an Ajax call without generating a 'not found' error. The good news is that the engineering team dug into this and has identified this as a bug, and they are working on a fix.

    --- Ben

    #27Posted by Ben Forta | Nov 16, 2007, 10:02 AM
  • Edward pauley

    Autosuggest, i even used the autosuggest2.cfm and movies.cfc down loaded from your website. all i get is an error when i do ANY autosuggest..... HELP!!

    #28Posted by Edward pauley | Nov 21, 2007, 03:33 PM
  • dan plesse

    Can the resulting html file be run on a non cf8 server? I tested the idea and I was getting WDDX error then I retested with return type XML and returned the array as a cfwddx string and I get nothing on both the cf8 and cf6.1 test servers.

  • Jonathan

    In using the sample Autosuggest2.cfm, I couldn't make it work until I deleted the WHERE   UCase(Lastname) LIKE UCase ('#ARGUMENTS.search#%'), which was causing an error: "Error invoking CFC... Error Executing Database Query.
    of course, without that WHERE clause, the autosuggesting is very very slow. strange, i copied the code directly and, except for fixing 1 code error, it's identical to Ben's code, but i get that error if the WHERE clause is there.

    #30Posted by Jonathan | Dec 9, 2007, 03:07 PM
  • Ben Forta

    Jonathan, turn on debugging to see what the SQL query being generated is.

    --- Ben

    #31Posted by Ben Forta | Dec 9, 2007, 04:10 PM
  • Eric Knipp

    Ben,

    Any update on when the fix for the CFC not found error will be forthcoming?

    Thanks,

    Eric

    #32Posted by Eric Knipp | Dec 16, 2007, 11:02 PM
  • Vaughn

    I didn't see an answer to passing multiple parameters to the cfc. I have an autosuggest that allows the user to select a company. What I return is a list of companies, city, state, and the company number prefixed with a ^ so I can find it later using listlast. The next field is another autosuggest that allow the user to select a job record. I need to list only the job records for the company previously selected and that match the title typed in by the user as a suggestion. I'm having a terrible time trying to pass the company number to the "job" autosuggest cfc along with the suggested value.

    #33Posted by Vaughn | Dec 16, 2007, 11:31 PM
  • vaughn

    I actually got it to work. I passed ({autosuggestvalue}.{sfcname}) where sfcname was the input name of the previous autosuggest that contained the company number. It was a bit more complicated in that I had to parse the company number from that string and the field name was dynamic (I added a count number to the end of the field name ie sfcname1).

    #34Posted by vaughn | Dec 22, 2007, 06:16 PM
  • John Comino

    Hi Ben, love the new features in CF8, so much more to learn but great that it makes it all so simple, especially the Ajax features. I would really like to see a book just explaining in depth all the new Ajax stuff, there are so many Php/Ajax books out there so maybe a ColdFusion/Ajax book would be a good idea?

    Anyway I tried your suggestion about copying the resources folder to be able to CSS change the css for the AutoSuggest however I can't get it to find it.

    I have my AutoSuggest template in a folder called AutoSuggest and have copied the resources folder into it and added the <cfajaximport cssSrc> tag at the top of the template.

    I have tried the following to get it to find the css files but none have worked, am I missing something simple here?

    <cfajaximport cssSrc="resources">
    <cfajaximport cssSrc="resources/ext">
    <cfajaximport cssSrc="C:\Inetpub\wwwroot\CF8\AutoSuggest\resources\ext">

    Cheers

    John

    #35Posted by John Comino | Jan 3, 2008, 06:25 PM
  • Gene Godsey

    Ben,

    The "CFC not found error" is really a pain. I see that this may be a bug.
    Do we know what the ETA of the fix is for this?
    Is there a bug page on the Adobe Site like there was on the Macromedia website?

    Thanks,
    Gene

  • Mark Duerden

    We have recently updated to CF8 and our MX code runs well on CF8 and makes extensive use of CFC’s.

    The Problem

    I am running a template (http:// localserver/open/index.cfm) that is calling a cfc from within the same folder and I get the following debug output from the CF Ajax Debugger.

    error:http: Error invoking CFC /open/places.cfc : Internal Server Error

    info:widget: Created grid, id: reportsGrid

    info:http: HTTP GET /open/places.cfc?method=getData&returnFormat=json&argumentCollection=%7B%22page%22%3A1%2C%22size%22%3A10%2C%22sortcol%22%3A%22%22%2C%22sortdir%22%3A%22%22%7D&_cf_nodebug=true&_cf_nocache=true&_cf_rc=0

    info:http: Invoking CFC: /open/places.cfc , function: getData , arguments: {"page":1,"size":10,"sortcol":"","sortdir":""}

    info:LogReader: LogReader initialized

    info:global: Logger initialized

    As you can see, it seems to invoke the cfc initially, but gets an Internal Server Error when trying to retrieve the data. So I thought I would call the cfc directly from the browser - http:// localserver/open/places.cfc?method=getData (this works on my set up of CF7). The error I get this time is a “JRun Servelet Error”.

    500

    java.lang.NullPointerException

    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:283)

    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)

    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)

    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)

    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

    If I try and call a cfc that doesn’t exist, for example http:// localserver/open/places.cfc?method=getData then I get exactly the same error. Which led me to think that for some reason that the CF Server was having problems finding CFC’s. So I tried to call a non existant cfc from the initial template, http:// localserver/open/index.cfm and got the error message i would expect:

    The specified CFC place could not be found.

    The path to the CFC must be specified as a full path, or as a relative path from the current template, without the use of mappings.

    I am now totally confused and would welcome any suggestions...

    #37Posted by Mark Duerden | Jan 10, 2008, 07:15 AM
  • Mark Duerden

    On further investigation, it does seem to be a configuration issue on our development machines. We are running XP Pro, using Apache 2.0.59 as the web server along with a J2EE multi-server CF install.

    When we try and run the cfc (or the template containing the CFGRID), Apache.exe is suffering a Buffer Overflow and I guess this must be the problem.

    #38Posted by Mark Duerden | Jan 10, 2008, 09:08 AM
  • Ben Forta

    I believe that the updater, in beta now, fixes this.

    --- Ben

    #39Posted by Ben Forta | Jan 11, 2008, 10:30 AM
  • Mark Duerden

    Hi Ben,

    Thanks for your reply, but I am unclear which updater you mean. Can you please clarify.

    Regards,
    Mark

    #40Posted by Mark Duerden | Jan 14, 2008, 04:30 AM
  • Mark Duerden

    Just in case anyone has a similar problem, we resolved it by updating to Apache 2.2.6 and re-installed CF8 using Chaz Chumley's excellent article on Community MX. http://www.communitymx.com/content/article.cfm?pag...

    Thanks

    #41Posted by Mark Duerden | Jan 18, 2008, 05:03 AM
  • kurt

    I'm getting the same "error invoking cfc: Internal Server Error" error when doing a cfc/ajax routine within fusebox 4.
    The interesting thing is that on the windows development machine I don't get the error; on the Redhat Linux production machine I do.
    Same exact code structure on both machines.
    Same CF 8 version.

    #42Posted by kurt | Jan 22, 2008, 12:09 AM
  • Shawn

    Does anyone know how to use asynchronous autosuggest in a <cfinput> from a cfc that receives inputs and returns a query? Here is my function:

    ===== START =====

    <cffunction name="getUsers" displayname="getUsers" hint="Method to return users for a specified customer" returntype="query" access="public" output="no">
       <cfargument name="custnum" displayname="custNum" hint="Customer number of users" type="numeric" required="yes" />
       <cfargument name="userid" displayname="userID" hint="Specific ID of a user" type="numeric" required="no" default="0" />
       <cfargument name="orderby" displayname="orderBy" hint="Column to sort records by" type="string" required="no" default="fullname" />
       <cfquery name="getusers" datasource="conCourseGPS">
          SELECT
             userid,
             username,
             firstname,
             lastname,
             lastname + ', ' + firstname AS fullname,
             photopath,
             licensenumber,
             cust_num,
             modby,
             moddate
          FROM users
          WHERE cust_num = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.custnum#" />
          <cfif arguments.userid>
             AND userid = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.userid#" />
          </cfif>
          ORDER BY #arguments.orderby#
       </cfquery>
       <cfreturn getusers>
    </cffunction>

    ===== END =====

    I would like to bind a <cfinput> with an asynchronous autosuggest from getusers.fullname, and I need to pass this function a variable customer number (custnum).

    Is this even possible?

    I may have to resort to calling the cfc and then setting the autosuggest to a valueList() on the column. By doing this, though, I lose the asynchronous functionality.

    Any help would be much appreciated.

    Thanks

    #43Posted by Shawn | Feb 20, 2008, 03:25 AM
  • fdias

    Ben,

    Is there any workaround for the file not found using virtual dirs on IIS? I mean can I somehow use full path?

    Thanks for this great article!

    #44Posted by fdias | Mar 6, 2008, 03:37 PM
  • Ben Forta

    When the updater ships that'll be fixed. No real workaround until then, sorry.

    --- Ben

    #45Posted by Ben Forta | Mar 6, 2008, 03:59 PM
  • fdias

    Thanks for your quick response! I guess we'll have to wait then.
    Btw I too got it to work when the file was inside a real IIS directory (x:\inetpub\wwwroot)

    #46Posted by fdias | Mar 6, 2008, 07:14 PM
  • Mark

    Thanks to the guys that figured out the virtual directory problem! was driving me nuts... Works great once you are inside of the root and no big deal where ya put the code for what is being delivered here with so few lines of code (that we have to write anyway) try taking a look at all that is going on using Firebug and it is quite impressive. Kudus to you Ben and the dev team, looking forward to more of your tutorials.

    #47Posted by Mark | Mar 29, 2008, 01:31 AM
  • Tyler

    I was having the same problem as John when trying to customize the cfinput Autosuggest using <cfajaximport cssSrc="path to your resources folder">

    Figured it out this morning, here’s how I did it.

    Created a folder called “ajaxScripts” under the application directory
    Copied the “resources” directory to it.
    Import using <cfajaximport cssSrc="/myWebApp/ajaxScripts">

    see: http://livedocs.adobe.com/coldfusion/8/htmldocs/he...

    - Ty

    #48Posted by Tyler | Apr 1, 2008, 10:07 AM
  • Dominic Watson

    Hi Ben, great stuff this :) A question was raised on the CF-Talk lists about having the autosuggest collect multiple values in a list (like an email 'to' field). I didn't think this was possible but came up with a pretty neat solution:

    http://fusion.dominicwatson.co.uk/2008/04/tidy-aut...

    If it isn't possible, could it be submitted as a new feature request for 9? A simple autosuggestdelimiter attribute for the cfinput tag would be great ;)

    Dominic

  • Dave Markle

    This is a response to Chris from last July.

    Problem summary: If you write SQL in the bound autosuggest function like this:

    WHERE d_name LIKE '%#srch#%'

    the coldfusion cfinput autosuggest function forces the result to START WITH the search term, where the SQL is looking for containment of the search string. So, for example, my query returns 10 matches, 6 start with the search term and 4 contain the search term but not at the beginning. The cfinput box only lists the 6 that start with the search term. This is actually intended behavior by Coldfusion.

    p658 of the cf8 developers guide reads:

    "You do not have to limit the returned data to values that match the cfautosuggestvalue contents, because the client-side code displays only the values that match the user input."

    Why force a filter on the results when we can do it ourselves? Not good.

    The problem is that is Coldfusion failed to think to pass a parameter to the YUI component AutoComplete. It's defined in /CFIDE/scripts/ajax/yui/autocomplete/autocomplete-min.js.

    Search for this line:
    YAHOO.widget.DataSource.prototype.queryMatchContains=false;

    Change the false to true.

    That fixes the problem.

    I'm not sure what other coldfusion functions use this component or what unexpected side effects this change will introduce.

    However, this change allows the autosuggest feature to to function as it should, where you have the control in your SQL of what results are displayed in the dropdown. If you want the results to start with the search term, then search for

    WHERE d_name LIKE '#srch#%'

    like Mr. Forta does in his example above. You could even return results totally unrelated to the searched term if you wanted to.

    #50Posted by Dave Markle | Apr 9, 2008, 03:02 PM
  • Dominic Watson

    @Dave Markel

    I'll see if I can incorporate that property into my betterautosuggest custom tag on riaforge. At the moment, the tag simply wraps the cfinput tag and adds some javascript to set other autosuggest properties with JS. Hopefully I will be able to set this one

    http://betterautosuggest.riaforge.org/

  • Dominic Watson

    Done (see above)

  • Laz

    I need a little help ..
    I'm using ..
    <cfcomponent output="false">
    <!--- Lookup Mentor--->
    <cffunction name="lookupMentor" access="remote" returntype="array">
    <cfargument name="search" type="any" required="false" default="">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(1)>

    <!--- Do search --->
    <cfquery datasource="lalaher_T8" name="data">
    SELECT       TblMasterLname, TblMasterFname
    FROM          tblMaster
    WHERE       UCase(TblMasterLname) LIKE Ucase '#ARGUMENTS.search#%')
    ORDER BY    TblMasterLname
    </cfquery>

    <!--- Build result array --->
    <cfloop query="data">
    <cfset ArrayAppend(result, TblMasterLname)>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>
    </cfcomponent>
    and I want to include TblMasterFname to the suggest box.
    Not too familiar with Arrays ...
    Thanks for your feedback ..

    #53Posted by Laz | Jun 17, 2008, 10:32 PM
  • Dominic Watson

    @Laz

    Firstly, in you CFC do something like:

    <cfloop query="data">
    <cfset ArrayAppend(result, TblMasterFname & ' ' & TblMasterLname)>
    </cfloop>

    Then, if you really are only allowing search by Lname, download the betterautosuggest custom tag that is on riaforge: http://betterautosuggest.riaforge.org/ and use the tag exactly as you would <cfinput autosuggest="... but add the queryMatchContains attribute so that you have:

    <custom:betterautosuggest autosuggest="..." name="namelookup" queryMatchContains="true" />

    This will allow "Joe Bloggs" to appear in the autosuggest list when the user searches on "Blo", etc.

    HTH

    Dominic

  • Brian

    Nik on 6/25/07 said "This fails if you enter a number. The autosuggest bind errors because it is not a string. Is this a bug in the autosuggest? If not, how would one avoid the issue? "
    Ashwin on 6/26/07 said "Thanks, Nik - we are aware of this problem, it's already been fixed for the final release. "

    However I'm running 8.01 and I am still getting the error when I enter a number. Letters for input work fine with my failing example.

    Error is: "Bind failed for autosuggest diadocfromto, bind value is not a 1D array of strings"

    In the form page:
    ...
    <cfinput type="text" name="diadocfromtoname" id="diadocfromto" autosuggest="cfc:#strcomponentpath#.readSuggestdiadocfromtoname({cfautosuggestvalue})" autosuggestminlength="1" typeahead="no" >
    ...
    in the cfc:
    <cffunction name="readSuggestdiadocfromtoname" returntype="array" ...>
    <cfargument name="selectname" required="true" type="string" />
    ...
    The table data it is referring to is a varchar and consists of values with letters and numbers. Any suggestions?

    #55Posted by Brian | Jul 14, 2008, 01:26 PM
  • Joey

    I am also experiencing the same error on 8.0.1:

    "Bind failed for autosuggest diadocfromto, bind value is not a 1D array of strings"

    #56Posted by Joey | Aug 1, 2008, 03:20 PM
  • Brian Oeding

    ditto same problem

    #57Posted by Brian Oeding | Aug 6, 2008, 07:20 PM
  • Brian Oeding

    Problem resolved: From http://www.experts-exchange.com/Software/Server_So...
    I found this worked for autosuggest fields (using a sting instead of array):

    <cffunction access="remote" name="Cities" returntype="String">
    <cfargument name="Cty" type="string" required="No" default="">
    <cfquery datasource="ZipCodes" name="zc">
    Select City as citi
    From Zips
    Order by City
    </cfquery>
    <cfreturn ValueList(zc.Citi)>
    </cffunction>

    #58Posted by Brian Oeding | Aug 6, 2008, 07:41 PM
  • jt

    Does anyone know why the autosuggest using Dominic's functionality would work in Firefox 3 and not in IE? I also tried the built CF Ajax functionality which again worked in Firefox 3 but not in IE 7?

    #59Posted by jt | Aug 19, 2008, 08:31 AM
  • Dominic Watson

    Not without more info. Ie. what functionality are you trying to use. There is a known issue with using QueryMatchContains with cfc binding but I am not sure that is browser specific. The demo url shows all the features working and works in both IE7 and FF3 but does not use cfc binding.

    http://dev.dominicwatson.co.uk/autosuggest/example...

    Dominic

  • jt

    Thanks for the quick response and really appreciate your time!! I have tried both binding to a cfc and using a simple comma delimited list such as in your example and can only get it to work in ff. I have only recently started using Coldfusion having come from an ASP background.

    I have the following custom tag on a cfm page within a td:

       <custom:betterautosuggest name="search_criteria" value=""
                               autosuggest="apple,banana,lemon,lime,mango,orange,peach,pear"
                               autosuggestbinddelay="1"
                               autosuggestminlength="1"
                               delimchar=";"
                               animhoriz="false"
                               animvert="true"
                               animSpeed="0.4"/>

    I have imported your custom tag with the inclusion of this line within the cfm file and have not amended your betterAutoSuggest file in anyway:

    <cfimport taglib="betterAutoSuggest" prefix="custom">

    So why does this work in ff and not ie? Your examples work in ie so I have ruled out any browser specific settings.

    #61Posted by jt | Aug 19, 2008, 09:04 AM
  • Dominic Watson

    My gut guess would be to suggest that it was something to do with the HTML. Ie. using the table for the form in some way. Perhaps you could experiment with taking the form outside of the table and if successful, narrowing down the cause and posting the problem here on riaforge.

    HTH

    Dominic

  • jt

    There is an include on the page to a header file that itself contains js includes. I have taken the reference out and the Ajax now works in ie. There must have been an ie only conflict in another js file. Thanks for your help on this.

    #63Posted by jt | Aug 19, 2008, 09:27 AM
  • Stacey

    I have been using the dynamic version of the autosuggest box. Except for getting a grey box that hangs around after you make your selection in IE6, I haven't had any problems until today.

    Someone in my office updated to the new Firefox (perhaps 3) and now when she uses the software she get the Bind failed for autosuggest srch, bind value is not a 1D array of strings
    error. This doesn't show up anywhere else - so far.

    Any ideas? Suggestions?

    thanks,Stacey

    #64Posted by Stacey | Sep 29, 2008, 11:43 AM
  • Brian Oeding

    Stacey, See my comment on 8/6.

    #65Posted by Brian Oeding | Sep 29, 2008, 12:19 PM
  • Aaron

    Hi Ben.... I love your work.....very helpfull.

    I have a question regarding autosuggest. I have it up and running fine. The user types in the box and the form communicates with my cfc to return suggestions.

    BUT...heres what I don't get. My users are selecting a contact by surname so they can then edit their details. The autosuggest works, they select the contact and submit the form to another action page, but all that can be sent is the Surname, of which their could be multiple users with the same name. On that action page I can't use the surname string in another query as there could be more than one. How do I return an ID to the autosuggest box as well that can then be submitted with the form?

    I must be missing something simple? PLEASE SOMEONE CAN YOU HELP ME!!!!!!!!!

    #66Posted by Aaron | Oct 14, 2008, 05:34 PM
  • Al

    I love your sample.. so simple and easy.. but have a problem with commas in the data.

    Is there any way to change the delimiter for the drop down box to something other than comma? Commas are pretty popular in company names

    #67Posted by Al | Nov 2, 2008, 11:03 AM
  • Sabine

    @David
    here is a workaround to allow the user to input multiple values into the field just with a couple of lines javascript

    <script type="text/javascript">
    SetDelimiter = function(elId, delim){
    if(!ColdFusion.objectCache[elId])
    alert("Error adding delimiter: Auto suggest item, '" + elId + "', could not be found");
    else
    ColdFusion.objectCache[elId].delimChar = delim;
    }

    </script>
    ...
    <cfinput name="abc" autosuggest="whatever" onfocus="SetDelimiter('abc',';')"/>

    Thx to
    http://fusion.dominicwatson.co.uk/2008/04/tidy-aut...

    #68Posted by Sabine | Nov 20, 2008, 11:33 AM
  • Bob S.

    I echo Al's request above - autosuggest needs to have a way to specify a different delimiter for the data source. Autosuggesting a list of company names is problematic when some of those company names have embedded commas.

    #69Posted by Bob S. | Nov 21, 2008, 07:26 PM
  • CF_Pro

    I noticed when you make the selection of the item in the autosuggest box with your mouse, it will populate the main input box with the entry you selected, however when you submit it, it only has the couple of letters you inputted originally. When you select it using arrow and return key everything is fine.. Anyone else notice that?

    #70Posted by CF_Pro | Nov 24, 2008, 06:53 PM
  • CF_Pro

    FYI: This is happening with OnChange="form.submit()" in the cfinput... When I remove that and just use a seperate submit button this problem goes away, but I rather have it auto submit.

    #71Posted by CF_Pro | Nov 24, 2008, 07:29 PM
  • Seamus

    Hi,

    I'm trying to get auto suggest to work where it searches on surname but also shows first_name and nickname (I have an intranet with many members having same first and surnames)
    I tried concatenating Ben's example ie
    MovieTitle +' '+ RATINGID AS movieDetails
    but get an error. I also think this is the wrong way to go.
    I only need to search on surname but display "surname first_name nickname" in the dropdown list of possibilities.
    Any clues please

    #72Posted by Seamus | Nov 26, 2008, 05:19 AM
  • Seamus

    re my comments above. I did get it working by making an single dimension array with "surname first_name nickname" then using ArrayToList.
    This worked fine but there may be better ways to do it

    #73Posted by Seamus | Nov 26, 2008, 07:38 AM
  • Tim

    Autosuggest works great when no <select> fields reside below the autosuggest dropdown list of suggestions. Similar to the issue with input or select tags directly below a datefield; but this time it seems select tags (and a datefield) display thru the autosuggest list. I attempted to modify the z-index of the autosuggest (which was a work-a-round for the datefield), but cannot find a solution specifically for: IE6 autosuggest with a select tag directly below the autosuggest. (No problems with IE7, FF, Safari)

    Any assistance is greatly appreciated.

    #74Posted by Tim | Dec 11, 2008, 10:24 AM
  • Eric Brancaccio

    I have an ajax issue that I was wondering if anyone could shed some light on. I am using ajax to check username availability as the user is typing it into the form. I am using a cfdiv to either display available or unavailable:
    <cfdiv bind="cfc:cfc.register.usernameCheck({form2:username@keydown})">

    username is the formfield that the user is typing into

    However I try to do it, it is always one keystroke behind. It does not recognize the user input until one additional key is pressed.

    #75Posted by Eric Brancaccio | Dec 16, 2008, 01:12 AM
  • Erik

    Eric,

    Try @keyup

    #76Posted by Erik | Jan 15, 2009, 03:58 PM
  • Bret

    This works great for me if I use a regular cfform. I don't get any suggestions though when I try it in a flash form. Should it work in flash? Is there anything different from the example that needs to be done if using a flash form?

    Thank you.

    #77Posted by Bret | Feb 5, 2009, 12:14 PM
  • Chad Fraser

    "Bind failed for autosuggest diadocfromto, bind value is not a 1D array of strings"

    I figured out this problem even further:

    I found this worked for autosuggest fields (using a sting instead of array) plus add a ",none" to the end of the ValueList result:

    <cffunction access="remote" name="ProductIDs" returntype="String">
    <cfargument name="pIDValue" type="string" required="No" default="">
    <cfquery datasource="myDatasource" name="myQuery">
    Select pID as ProductID
    From products
    </cfquery>
    <cfreturn ValueList(myQuery.ProductID) & ",none">

    ***",none" could be any other string not associated to the search like 'n/a' I suppose.***

    </cffunction>

    I believe the issue is with the JSON file included in CF8.

    I found that when you enter a number in rapidly you would still get the "bind" error so I solved the problem doing this. It tricks the "invocation". It seems the invocation response will return a value like 10020.0 when you enter a value of 10020 quickly?

  • Raj Amirapu

    Hi,
    I used the example. I taken as is and the list is not getting displayed.
    I am doing any thing wrong

    Thanks & Regards.
    Raj

    #79Posted by Raj Amirapu | Mar 16, 2009, 09:38 AM
  • Monique Boea

    Hi ben

    Thanks for the article.

    Is it possible to have the auto suggest search on the input but return a different value.

    EX: If I want students of a university to search for a course, they would type in the course title, but I am looking for the course id to pass in the form.

    is this possible?

    Also, I had to out my CFC in the root and I was not able to get the autosuggest function to work with the cfc. I am using your simpler version and it works fine.

    When i use the cfc, i type one letter and it just freezes.

  • Seamus Campbell

    Hi monique
    I did get it working (with ID) by making an single dimension array with "surname first_name [ID]" then using ArrayToList
    Then get the ID using ListLast.
    I can send you more code if you want.

    #81Posted by Seamus Campbell | Mar 30, 2009, 03:03 AM
  • Monique Boea

    Thanks Seamus
    Yes, please post your code.

  • Mike

    Please help on this. Autosuggest worked fine until I updated to 8.0.1. I tried all suggestions in this thread with no luck.

    Still getting the 1D array error code. Ouch...

    #83Posted by Mike | Mar 30, 2009, 02:30 PM
  • Raja Sekhar

    Hi Ben,
    I am facing an issue with autosuggest. The autosugget is working fine on one page. It is not working on another page. It just comes and disappears.Let me know if any ideas.
    I am using the same approach you suggested.
    Thanks & Regards,
    Raja Sekhar

  • Monique Boea

    Is it possible to do a bind with auto suggest. Like do the auto suggest on one field, populate it while populating another field?

  • Adrian

    Shouldn't the where-statement be: WHERE UPPER(artname) LIKE '#UCASE(ARGUMENTS.search)#%'--"UPPER" for SQL and "UCASE" for CF?

    #86Posted by Adrian | Apr 13, 2009, 07:33 PM
  • guru520

    where are the sample databases used in the tutorials

    #87Posted by guru520 | May 8, 2009, 12:31 PM
  • Bud Hines

    Ben,

    I used the control and it works great when used in a body tag. However, I wanted to use this control in my div id=header for searching within my site. Per the ajax debugger it works. But, the results just will not display in the autosuggest field. If I change the div id to anything else it works. I found a work around for a similar problem adjusting the z-index but that fix did not work for this.

    Can you try and see if you have the same problem. If so, do you have any suggests for debugging this.

    thanks,
    Bud

    #88Posted by Bud Hines | Jun 10, 2009, 09:19 AM
  • Bud HInes

    Ben,

    Never mind on my question above. It turns out that I had a header ul with a position of absolute that was preventing the autosuggest results from displaying.

    thanks,
    Bud

    #89Posted by Bud HInes | Jun 11, 2009, 06:53 AM
  • Adam

    Hi Seamus -

    Could you elaborate on the ID issue? I'm using this method for a client lookup that displays client name, email, and department in the list, but the ID is the part I want posted to the database table.

    Thanks,
    Adam

    #90Posted by Adam | Sep 22, 2009, 03:54 PM
  • Scott Wruble

    Can anyone clarify the correct fix for the issue where the suggesting only works every other keystroke? I have attempted to use the workaround posted by Eric Brown above. This resolves the problem, but then causes a seperate problem when you attempt to arrow down the suggestion list. By the way... I'm shocked at how well this performs even when querying a table of over 1 million accounts.

    #91Posted by Scott Wruble | Nov 17, 2009, 11:02 AM
  • Webeng

    I'm having a similar issue with the "works every other key stroke" prob.
    I'd find it interesting to view Eric Brown's workaround above if I could see it.

    Anyway, is there a resolution to this issue?

    #92Posted by Webeng | Jan 14, 2010, 02:47 AM
  • Trucoop

    I have tried both the example in the book and this example and I was getting the same error. Failed to invoke CFC. It recognized the location of file but for some reason did not want to work. If I moved the query directly to the CFM file it worked just fine. Any thoughts?

    #93Posted by Trucoop | Jan 19, 2010, 11:02 PM
  • ian

    I've found it works with fusebox 5 but not 3. Any ideas why this might be happening?

    #94Posted by ian | Jan 13, 2011, 07:15 AM
  • Sarah

    Very nice examples, thanks

    #95Posted by Sarah | Sep 21, 2011, 12:04 PM
  • Ashish

    Ben: Do you have any autosuggest code that woks on ColdFusion 5 ?

    #96Posted by Ashish | Aug 8, 2013, 01:11 AM
  • Ben Forta

    ColdFusion 5, huh? That's a bit tricky, primarily as that version predates CFC support. But, it is doable. You'll want to use a pure client side option, like a jQuery library, for the control and UI itself. If you want it to be populated dynamically you'll need a .cfm page which accepts the passed value and manually formats the result. I don't have an example of this, but it should work.

    --- Ben

    #97Posted by Ben Forta | Aug 8, 2013, 09:00 AM
  • Riad

    When I use it I get an error message
    Invalid CFML construct found on line 37 at column 1.
    ColdFusion was looking at the following text:

    <

    The CFML compiler was processing:

    < marks the beginning of a ColdFusion tag.Did you mean LT or LTE?

    I copied your code exactly the way it is here.

    Do you know what could be the issue?

    #98Posted by Riad | Aug 15, 2013, 03:00 PM
  • Sharath

    The specified CFC art could not be found.
    Pls Help

    Thanks

    #99Posted by Sharath | Sep 26, 2013, 07:58 AM
  • teaEi

    Thanks Dave Markle for your post #50!
    I was trying for hours and hours... This bug still exists in Coldfusion 10.

    #100Posted by teaEi | Aug 20, 2014, 09:15 AM
  • Robin

    The CFC invoke bug is still in CF10! Any ideas on when this will be fixed?

    #101Posted by Robin | Sep 5, 2014, 10:40 AM