A while back I posted examples of using ColdFusion 8 Ajax support to power an auto-suggest control and related controls. Both examples required that the back-end CFC methods create arrays (1 dimension for the former, 2 dimensions for the latter). And I pointed out that I hoped we’d be able to tighten that syntax before we ship.
Well, we did. In the final CF8, the CFC method bound to auto-suggest can return a simple list (a string), and the CFC bound to a can return a query. This makes the code orders of magnitude simpler. I am not going to update those entries just yet (as these enhancements won’t work with the public beta), but …
The CFC method to power an auto-suggest could be simplified like this:







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




The CFC method to power a could now just return a query. And the control would then use the existing VALUE and DISPLAY attributes to specify the query columns to be used, like this:

These are great little enhancements, and I am glad the team was able to get them in just in time.

45 thoughts

  1. Hi Ben, I think you mean ValueList when you use "<cfreturn ValueLust(result.artname)>".
    Thanks for the update.

  2. Calvin,
    An auto-suggest control is a text control, there is no separate id and value, what gets submitted is the text, just like any other <input type="text">.
    — Ben

  3. When using binding on cfselect w/ a cfc. I get the "exception thrown and not caught". I see that a few have reported it, but no resolution. The cfc I can manually call and it returns the expected data set. I’m attempting to create a country, state, county select box series.
    Thanks

  4. Hello Ben,
    Great stuff. I’m loving the new CF8 features and your site is incredibly helpful in learning how to use them.
    Is there any way I could talk you into giving an example (or mabey a future tutorial) on querying Exchange with the new cfexchange and cfexchangecontact tags to create an auto suggest box of someone’s email contacts?
    Regards,
    Scott

  5. Scott – We were getting the "exception thrown and not caught" js error too and it turned out that we had html commented code in application.cfm and that was the source of the issue. Once we corrected that, it worked fine. Hope this helps.

  6. Hi Ben,
    I just installed CF8 last week and I’m having trouble with the relatled select controls. My cfc return a query with two fields: rank & Product (value & display). The error I’m getting is: [Bind failed for select box a_proc, bind value is not a 2D array or valid serialized query]
    CFC:
    <cffunction name="lookupClarifyList" access="remote" returntype="query"
    hint="Returns Clarify List given the list title">
    <cfargument name="thisTitle" type="string" required="true">
    <cfquery datasource="clarifySMST" name="getList">
    SELECT e1.title as Product, e1.rank
    FROM
    table_hgbst_lst l1,
    table_hgbst_show s1,
    table_hgbst_elm e1,
    mtm_hgbst_elm0_hgbst_show1 m1
    WHERE l1.title LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="#thisTitle#">
    AND s1.objid = l1.hgbst_lst2hgbst_show
    AND s1.objid = m1.hgbst_show2hgbst_elm
    AND e1.objid = m1.hgbst_elm2hgbst_show
    AND e1.state != ‘Inactive’
    Order by RANK
    </cfquery>
    <cfdump var="#getlist#">
    <cfreturn getList>
    </cffunction>
    CODE:
    <cfform name="test" >
    <select name="a_orig" required="yes">
    <option value="Internal Document Source" selected>Internal</option>
    <option value="3rd Party PP Product">External</option>
    </select>
    <cfselect name="a_proc" bind="docmgmt.pww.lookupClarifyList({a_orig})" bindonload="true"
    value="rank" display="product"/>
    </cfform>

  7. Jim, first of all, get the <CFDUMP> out of there. Then try to invoke the CFC method from another CFM page using <CFINVOKE>, just to make sure it is working and returning a valid query.
    — Ben

  8. Hi Ben,
    I was able to call the cfc with CFInvoke and get the results. The reason the cfdump was there was if I used cfdebug in the url it shows the results of the click on an item in the first select box.
    Since my post I have tried numerous changes and have even cut and pasted your examples from this blog and from the white paper an the Adobe site and I can’t even get the ajax auto complete example to work.
    I have checked that the CFIDE mappings in the CFAdmin is in place: C:InetpubwwwrootCFIDE and I have the same mappings in place in IIS.
    I’m looking kind of foolish to my management as I told they how CF8 was going to make coding easier and faster and this is my third day trying to solve this ajax problem. My CF8 install was over CF7 and I didn’t have any ajax code in place, but used CFC’s extensively. I get the same results in IE6/7 and FF2.0. I had one of my CNYCFUG members try my code on his CF8 install and it worked. This seems to be a settings problem. Do you have any configuration points that I can check?
    thanks, Jim

  9. Ben,
    This is the outout from the cddebug window on my related select problem. If I understand this correctly it shows the cfc was called and the data was is being returned. It’s just not loading it into the control. — Jim
    info:http: CFC invocation response: {"COLUMNS":["PRODUCT","RANK"],"DATA":[["Please Specify",0],["WinVisa",1],["ICVerify",2],["PcCharge",3],["Monetra",4],["Verifone",5],["Hypercom",6],["911 Payment",7],["Precidia",8],["DataCap",9]]}
    info:http: HTTP GET /docmgmt/pww.cfc?method=lookupClarifyList&returnFormat=json&argumentCollection=%7B%22thisTitle%22%3A%223rd%20Party%20PP%20Product%22%7D&_cf_nodebug=true&_cf_nocache=true&_cf_clientid=84FA3E126422CA5AA58E6C7C0EBE96DD&_cf_rc=1
    info:http: Invoking CFC: /docmgmt/pww.cfc , function: lookupClarifyList , arguments: {"thisTitle":"3rd Party PP Product"}
    info:http: CFC invocation response: {"COLUMNS":["PRODUCT","RANK"],"DATA":[["SOW",0],["Quote",1],["Sales Order",2],["Addendum",3]]}
    info:http: HTTP GET /docmgmt/pww.cfc?method=lookupClarifyList&returnFormat=json&argumentCollection=%7B%22thisTitle%22%3A%22Internal%20Document%20Source%22%7D&_cf_nodebug=true&_cf_nocache=true&_cf_clientid=84FA3E126422CA5AA58E6C7C0EBE96DD&_cf_rc=0
    info:http: Invoking CFC: /docmgmt/pww.cfc , function: lookupClarifyList , arguments: {"thisTitle":"Internal Document Source"}
    info:LogReader: LogReader initialized
    info:global: Logger initialized

  10. Ben,
    I know your a busy man but I really could use some direction. I cannot find any solution to the bind option not working in my CF8 install. Is this a bug? Does bind only work with certain doc type declarations?
    Jim

  11. I found that the Google Analytics javascript code in my application.cfm caused the Global:execption thrown and not caught error. once i commented it out i had no problem

  12. @Jim:
    I got Ben’s examples working on a local database the first time, so was curious about your problems.
    If you look at your <cfselect …> line, you will see that you missed the "cfc:" prefix in the bind= attribute. If I t

  13. Hi all,
    I’m also getting the "exception thrown and not caught" javascript error message when I implement an autosuggest cfinput tag in my application.
    If I have a clean standalone test, the autosuggest works great!
    Anyone managed to get to the bottom of this yet?
    Thanks.

  14. Look at the data your using to populate the Autosuggest with.
    ie: if it’s a database of last names and you have an O’Donnel in there, it’ll die.

  15. Hi,
    Thanks for your suggestions Paul & Paul.
    I have checked the data and there are no apostrophies coming back in the data and I haven’t implemented an onRequestEnd.cfm file.
    As I stated previously, a clean test version works correctly. However, upon further investigation, the clean version fails with the javascript exception error if the CFC file is not in the same directory as the CFM file.
    My cfm page contains the following line, pointing to the cfc in a different directory:
    <cfinput type="text" name="country" autosuggest="cfc:glenn.brilig.country.ajaxCountry({cfautosuggestvalue})">
    My component code is:
    <cfcomponent displayname="country" hint="Return information regarding countries">
    <cffunction name="ajaxCountry" access="remote" output="true" returntype="array" returnformat="JSON" hint="For AJAX autocomplete of the country.">
    <cfargument name="country" required="false" type="string" default="">
    <cfset var result = ArrayNew(1)>
    <cfquery name="getCountry" datasource="DSSOURCE" username="DSUSER" password="DSPASSWORD">
    set nocount on
    select description
    from country
    <cfif arguments.country neq "">
    where description like ‘#arguments.country#%’
    </cfif>
    order by description
    set nocount off
    </cfquery>
    <!— Build result array —>
    <cfloop query="getCountry">
    <cfset ArrayAppend(result, getCountry.description)>
    </cfloop>
    <cfreturn result>
    </cffunction>
    </cfcomponent>

  16. Hi Ben,
    I have tried all suggestions from the other posters above, but I still get the Javascript error ‘Exception thrown and not caught at line 787’ when I try to bind a cfc in a <cfselect>. I found out that this line 787 is probably in c:InetpubwwwrootCFIDEscriptsajaxpackagecfajax.js, but I don’t know how to fix it.
    What do I do wrong? Or is this a know bug and is there a fix for it?
    @Jim: make sure the name of your cfselect is exactly the same as the value, otherwise you get the very misleading error ‘Bind failed for select box a_proc, bind value is not a 2D array or valid serialized query’.
    Rainer.

  17. @All,
    I do recall my post here above because I found the reason why I had the ‘Exception thrown and not caught at line 787’ error!
    It turned out that our company has a rewrite in the httpd.ini which rewrites all ‘.cfc’ to ‘.cfc?wsdl’. After

  18. Ben,
    RE: CFSELECT with cfc binding.
    Either I’m doing something wrong or there is a bug in this functionality.
    First, I can’t get your example to work unless I remove the method onRequest from Application.cfc. With that method the cfc returns nothing. This is both by calling the cfc directly in the URL or through the CFSELECT bind= call.
    Second, if I place the CFC in a directory that is mapped (ie not in the website root directory) I get the AJAX error Error invoking CFC NOT FOUND. For example I am calling the cfc: cacfc.database.school.getStates(). When I look at the source that coldfusion is generating it’s looking for just /school.cfc. As soon as I move the cfc to a directory under the website root everything works fine.

  19. Matt,
    The mapped directory problem is a known one, and I believe is to be addressed in the updater due out shortly.
    The onRequest() issues sounds sounds like the same limitation with Web Services and more, and is documented as a restriction.
    — Ben

  20. Thanks to this ongoing discussion I was able to verify that this bug is what is preventing my solution from working. I have to use mapped path for the CFC, so updater when? (I know you can’t give specific dates, but would you say, oh, this quarter?)

  21. I was wondering if there is a way to bind the select field to a query on the same page and not in an external cfc?
    I have a local query tat returns two fields. When I run the cfselect like this ..
    <cfselect name="Type"
    bind="rsTypes"
    value="typeid"
    display="type"
    bindonload="true" />
    I get the following error…
    Bind Failed …. bind value is not a 2D array or valid serialized query. It’s got me stumped unhuh it does.
    Chris

  22. I am getting the same error – code for my .cfm and .cfc files are below, both in same directory, mapped, component shows up in DW fine running under wwwroot et all…. HELP!
    <cfform>
    <table>
    <tr>
    <td>Select the Client</td>
    <td><cfselect name="client_number"
    bind="cm.getClient()"
    value="client_number"
    display="client_name"
    bindonload="true">
    </cfselect>
    </td>
    </tr>
    <tr>
    <td>Select the Matter</td>
    <td><cfselect name="matter_number"
    value="matter_number"
    display="matter_name"
    bind="cm.getMatter({client_number})">
    </cfselect>
    </td>
    </tr>
    </table>
    </cfform>
    <cfcomponent displayName="Client Matter" hint="cm" output="false">
    <cfset THIS.dsn = "Monet">
    <cffunction name="getClient" displayName="Get Client" hint="gc" access="remote" returnType="query">
    <cfset var data = "">
    <cfquery name = "data" datasource="#THIS.dsn#">
    SELECT client_number,client_name
    FROM dbo.client_matter
    ORDER BY client_name
    </cfquery>
    <cfreturn data>
    </cffunction>
    <cffunction name="getMatter" displayName="Get Matter" hint="gm" access="remote" returnType="query">
    <cfargument name="client_number" displayName="Client Number" hint="cn" type="string" required="true">
    <cfset var data = "">
    <cfquery name = "data" datasource="#THIS.dsn#">
    SELECT matter_number,matter_name
    FROM dbo.client_matter
    WHERE client_number = #ARGUMENTS.client_number#
    ORDER BY matter_name
    </cfquery>
    <cfreturn data>
    </cffunction>
    </cfcomponent>

  23. reworked the query and some other tweaks and it is working now. The ?debug feature really comes in handy!

  24. Similar to the onRequest() issue, I found that having onRequestEnd() in your Application.cfc causes this to not work as well. The only thing you can have, it seems, is onRequestStart().

  25. I also recevied the thrown but not caught error. I had some code in my application.cfm so I could use it on my test server or live without adjusting some variables (see below). I believe the CompareNoCase function was doing it. Took it out and autosuggest worked like a charm.
    <!— Which SQL database? Automatically figure it out —>
    <CFIF CompareNoCase(cgi.SERVER_NAME,"testintranet.XXXXX.com") is 0>
    <CFSET datasourcename = "Test_Intranet_SQL">
    <SPAN STYLE="font-size:10px;font-family:arial;color:red;">Test_Intranet_SQL DS</SPAN><BR>
    <CFELSE>
    <CFSET datasourcename = "Intranet_SQL">
    </CFIF>

  26. Why wont this work?
    So I am using Ben autosuggest example and it works fine.
    Here is my code:
    <cfinput type="text"
    name="courseTitle"
    size="65"
    autosuggest="#ValueList(getCourses.courseTitle)#"><br /><br />
    What i’d like to add is a bind that will get the course id based on the course title that the user types in:
    Here is the second piece:
    <cfinput type="text" name="courseID"
    bind="cfc:getCourseID.getCourseID({courseTitle@blur})">
    And here is my CFC
    <cfcomponent>
    <cffunction name="getCourseID" access="remote">
    <cfargument name="courseTitle">
    <cfquery name="getCourseID" datasource="#APPLICATION.reporting_dsn#">
    SELECT DISTINCT courseID
    FROM dbo.ccac_courses
    WHERE courseTitle = ‘#arguments.courseTitle#’
    </cfquery>
    <cfreturn "#getCourseID.courseID#">
    </cffunction>
    </cfcomponent>
    It is not returning an error but it doesn’t populate that second field with the courseID.
    Any suggestions?

  27. Using this example, I wrote a pair of select boxes, the first one to select a state, and the second one to select a county which is dynamically populated after the state is selected. Everything works great for the form being submitted and getting to the next page. The problem is that when the user clicks the back button on their browser the "Bind on load" attribute seems to clear out their selections and presents a new form. Is there a way to preserve the selected values when a user comes back to the page?
    Thanks!

  28. I know this sounds elementary but make sure that your path to your grid is set correctly.
    <cfajaxproxy cfc="[mypath].QuotesGrid" jsclassname="jQuotesGrid" />
    how I resolved the "…not caught" issue.

  29. I am also having the exception thrown not caught error. I have addcfm and getGamecfc inside another folder called manager in my site root folder.
    When I moved my CFC file into the server root, the feature worked fine. How can I make it work inside another directory, though?

  30. Ben,
    Since the ‘bind’ attribute in <cfselect> replacing/equivalent to ‘query’ attribute, I tried to
    use ‘selected’ attribute to select an option and it doesn’t work.
    Is there a workaround?

Leave a Reply