AdobeStock_455007340

Last Minute ColdFusion Ajax Enhancements

Home » Last Minute ColdFusion Ajax Enhancements

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 responses to “Last Minute ColdFusion Ajax Enhancements”

  1. O?uz Demirkap? Avatar
    O?uz Demirkap?

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

  2. Ben Forta Avatar
    Ben Forta

    Oops! 😉 Fixed.
    — Ben

  3. Gary Gilbert Avatar
    Gary Gilbert

    Freudian slip?

  4. Calvin Avatar
    Calvin

    How would you bind values and IDs associated with the values to the autosuggest control?

  5. Ben Forta Avatar
    Ben Forta

    Gary, maybe, we are very passionate about ColdFusion 😉
    — Ben

  6. Ben Forta Avatar
    Ben Forta

    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

  7. Calvin Avatar
    Calvin

    True, I’m really implying a combo box…

  8. Frank Gerritse Avatar
    Frank Gerritse

    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

  9. Frank Gerritse Avatar
    Frank Gerritse

    sorry teh word coldfuiosn is wrong in the error line
    error "exception thrown and not caught "
    Thnx

  10. Paul Avatar
    Paul

    Ben,
    I take it none of these CF Ajax tags work in CF 7 ?
    Signed,
    Trying to get the boss to upgrade…

  11. Ben Forta Avatar
    Ben Forta

    Paul, these are new CF8 features.
    — Ben

  12. Scott Terrell Avatar
    Scott Terrell

    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

  13. Scott Avatar
    Scott

    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

  14. Mike Corrigan Avatar
    Mike Corrigan

    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.

  15. Jim Avatar
    Jim

    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>

  16. Ben Forta Avatar
    Ben Forta

    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

  17. Jim Avatar
    Jim

    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

  18. Jim Avatar
    Jim

    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

  19. Jim Avatar
    Jim

    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

  20. Mark Avatar
    Mark

    I’m getting the exception thrown and not caught error as we’ll…. looks pretty common

  21. Paul Hopkinson Avatar
    Paul Hopkinson

    as am I – see the code base here – http://forums.digitalpoint.com/showthread.php?p=4857210#post4857210
    It’s driving me up the way – is this a bug in the ajax files?
    A fix would really be appreciated…..

  22. Mike Demahy Avatar
    Mike Demahy

    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

  23. Tom Eldredge Avatar
    Tom Eldredge

    @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

  24. Glenn Avatar
    Glenn

    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.

  25. Paul Avatar
    Paul

    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.

  26. Paul Hopkinson Avatar
    Paul Hopkinson

    The solution for me was to take out everything from my onrequestend.cfm file
    Everythings been working a dream since I did that

  27. Glenn Avatar
    Glenn

    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>

  28. Rainer Avatar
    Rainer

    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.

  29. Rainer Avatar
    Rainer

    @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

  30. Matt McDonald Avatar
    Matt McDonald

    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.

  31. Ben Forta Avatar
    Ben Forta

    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

  32. Kris Avatar
    Kris

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

  33. Chris Avatar
    Chris

    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

  34. Mark Lea Avatar
    Mark Lea

    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>

  35. Mark Lea Avatar
    Mark Lea

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

  36. Rob Avatar
    Rob

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

  37. Michael Kane Avatar
    Michael Kane

    I needed to populate the cfselect box when the user does something, i.e. types in a search string, but NOT onload. We’ve been using our own JavaScripts, and not using the bind at all with select boxes. I found a much better solution that uses the ColdFusion.Bind.assignValue function, at http://cfsilence.com/blog/client/index.cfm/2007/10/22/Refreshing-A-Bound-CFSelect

  38. Anthony Brown Avatar
    Anthony Brown

    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>

  39. Monique Boea Avatar
    Monique Boea

    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?

  40. Monique Boea Avatar
    Monique Boea

    For some reason my autosuggest/bind code is now working.
    It just runs very slow.
    Any suggestions on how to make the CFC part go faster?

  41. Casey Avatar
    Casey

    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!

  42. Guillermo Avatar
    Guillermo

    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.

  43. Mohamad Avatar
    Mohamad

    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?

  44. Hari Avatar
    Hari

    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?

  45. Vikram Avatar
    Vikram

    Thanks man!! that was very helpful!

Leave a Reply