AdobeStock_455007340

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


SELECT artname
FROM art
ORDER BY artname



Art:



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:










SELECT artname
FROM art
WHERE UCase(artname) LIKE Ucase('#ARGUMENTS.search#%')
ORDER BY artname









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:

Art:


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.

104 responses to “ColdFusion Ajax Tutorial 1: Auto-Suggest”

  1. Dominic Watson Avatar
    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

  2. Dominic Watson Avatar
    Dominic Watson

    Done (see above)

  3. Laz Avatar
    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 ..

  4. Dominic Watson Avatar
    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 L

  5. Brian Avatar
    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?

  6. Joey Avatar
    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"

  7. Brian Oeding Avatar
    Brian Oeding

    ditto same problem

  8. Brian Oeding Avatar
    Brian Oeding

    Problem resolved: From http://www.experts-exchange.com/Software/Server_Software/Web_Servers/ColdFusion/Q_23173313.html
    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>

  9. jt Avatar
    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?

  10. Dominic Watson Avatar
    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.cfm
    Dominic

  11. jt Avatar
    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.

  12. Dominic Watson Avatar
    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

  13. jt Avatar
    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.

  14. Stacey Avatar
    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

  15. Brian Oeding Avatar
    Brian Oeding

    Stacey, See my comment on 8/6.

  16. Aaron Avatar
    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!!!!!!!!!

  17. Al Avatar
    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

  18. Sabine Avatar
    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[

  19. Bob S. Avatar
    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.

  20. CF_Pro Avatar
    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?

  21. CF_Pro Avatar
    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.

  22. Seamus Avatar
    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

  23. Seamus Avatar
    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

  24. Tim Avatar
    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.

  25. Eric Brancaccio Avatar
    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.

  26. Erik Avatar
    Erik

    Eric,
    Try @keyup

  27. Bret Avatar
    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.

  28. Chad Fraser Avatar
    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?

  29. Raj Amirapu Avatar
    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

  30. Monique Boea Avatar
    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.

  31. Seamus Campbell Avatar
    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.

  32. Monique Boea Avatar
    Monique Boea

    Thanks Seamus
    Yes, please post your code.

  33. Mike Avatar
    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…

  34. Raja Sekhar Avatar
    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

  35. Monique Boea Avatar
    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?

  36. Adrian Avatar
    Adrian

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

  37. guru520 Avatar
    guru520

    where are the sample databases used in the tutorials

  38. Bud Hines Avatar
    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

  39. Bud HInes Avatar
    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

  40. Adam Avatar
    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

  41. Scott Wruble Avatar
    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.

  42. Webeng Avatar
    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?

  43. Trucoop Avatar
    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?

  44. ian Avatar
    ian

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

  45. Sarah Avatar
    Sarah

    Very nice examples, thanks

  46. Ashish Avatar
    Ashish

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

  47. Ben Forta Avatar
    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

  48. Riad Avatar
    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?

  49. Sharath Avatar
    Sharath

    The specified CFC art could not be found.
    Pls Help
    Thanks

  50. teaEi Avatar
    teaEi

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

Leave a Reply to LazCancel reply

Discover more from Ben Forta

Subscribe now to keep reading and get access to the full archive.

Continue reading