Blog

31May
2007
ColdFusion Ajax Tutorial 2: Related Selects

Many of us have built related select controls, forms with two (or more) drop down <SELECT> controls, where making a change in one control causes the available selections in the related control to change. For example, selecting a category in one control displays category products in a related control, or selecting a state in one control updates a related control with the cities in that state.

These controls are typically implemented using client side JavaScript to process arrays of data embedded in the page itself. Every possible combination and option is embedded in JavaScript in the page, and client side scripts update controls based on selection changes in other controls.

ColdFusion 8's new Ajax functionality makes this kind of interface really easy, without requiring any client-side scripting, and without requiring that all of the data be embedded in the generated page. Rather, <CFSELECT> controls may be bound to ColdFusion Component methods that are asynchronously invoked as needed.

To demonstrate this, here is a complete working example which uses one of the example databases that comes with ColdFusion. First the ColdFusion Component:

view plain print about
1<cfcomponent output="false">
2
3    <cfset THIS.dsn="cfartgallery">
4
5    <!--- Get array of media types --->
6    <cffunction name="getMedia" access="remote" returnType="array">
7        <!--- Define variables --->
8        <cfset var data="">
9        <cfset var result=ArrayNew(2)>
10        <cfset var i=0>
11
12        <!--- Get data --->
13        <cfquery name="data" datasource="#THIS.dsn#">
14        SELECT mediaid, mediatype
15        FROM media
16        ORDER BY mediatype
17        </cfquery>
18
19        <!--- Convert results to array --->
20        <cfloop index="i" from="1" to="#data.RecordCount#">
21            <cfset result[i][1]=data.mediaid[i]>
22            <cfset result[i][2]=data.mediatype[i]>
23        </cfloop>
24
25        <!--- And return it --->
26        <cfreturn result>
27    </cffunction>
28
29    <!--- Get art by media type --->
30    <cffunction name="getArt" access="remote" returnType="array">
31        <cfargument name="mediaid" type="numeric" required="true">
32
33        <!--- Define variables --->
34        <cfset var data="">
35        <cfset var result=ArrayNew(2)>
36        <cfset var i=0>
37
38        <!--- Get data --->
39        <cfquery name="data" datasource="#THIS.dsn#">
40        SELECT artid, artname
41        FROM art
42        WHERE mediaid = #ARGUMENTS.mediaid#
43        ORDER BY artname
44        </cfquery>
45    
46        <!--- Convert results to array --->
47        <cfloop index="i" from="1" to="#data.RecordCount#">
48            <cfset result[i][1]=data.artid[i]>
49            <cfset result[i][2]=data.artname[i]>
50        </cfloop>
51
52        <!--- And return it --->
53        <cfreturn result>
54    </cffunction>
55
56</cfcomponent>

This CFC contains two methods. getMedia returns all of the media types in the art catalog database, and getArt accepts a media id and returns any art that is associated with that passed id. Both methods convert their results into two dimensional arrays, with the first dimension containing the id (to be used as the value in the <SELECT> control) and the second containing the display text. (For now, this two dimensional array is the format required by <CFSELECT>).

Now for the form itself:

view plain print about
1<cfform>
2
3<table>
4    <tr>
5        <td>Select Media Type:</td>
6        <td><cfselect name="mediaid"
7                bind="cfc:art.getMedia()"
8                bindonload="true" />
</td>
9    </tr>
10    <tr>
11        <td>Select Art:</td>
12        <td><cfselect name="artid"
13                bind="cfc:art.getArt({mediaid})" />
</td>
14    </tr>
15</table>
16
17</cfform>

The form contains two <CFSELECT> controls, one named "mediaid" and the other named "artid".

"mediaid" is bound to cfc:art.getMedia(), and so to obtain the list of media types to populate the control, the client makes an asynchronous call to the getMedia method in art.cfc, and populates the list with the returned array. As we'd want this control to be automatically populated when the form loads, bindonload is set to "true", this way the getMedia() call is fired automatically at form load time.

"artid" is bound to the getArt method in art.cfc. This method requires that a mediaid be passed to it, and so {mediaid} is used so as to pass the currently selected value of control mediaid (the first <CFSELECT>). Because these two controls are bound together, the second dependant on the first, ColdFusion automatically generates JavaScript code that forces artid to be repopulated with newly retrieved data whenever mediaid changes.

This example binds just two controls, but this mechanism can be used to relate as many controls as needed, and not just <CFSELECT> controls either.

Related Blog Entries

Comments (161)



  • Mark Ireland

    Could there be a JSON version of this? (Where it didnt matter which application server returned the data)

  • Ryan Mac Donalld / ColdFusion openings in Kansas

    Position: Cold Fusion Developer



    Location: Kansas City, MO


    Salary: $70,000/year



    Benefits: group health insurance, dental insurance, vision insurance, fitness reimbursement, 401(k) plan, paid vacation and sick time and holidays.



    Work hours are generally 9:00 AM - 5:00 PM. Payroll is paid semi-monthly.

    Start Date: 06/11/07

    Experience:

    Two years of experience designing, developing, maintaining and enhancing Internet site content and applications



    using Web development tools Macromedia's Dreamweaver or Cold Fusion Studio MX. Must be highly proficient



    with HTML, XHTML, JavaScript, CSS. Experience with Cold Fusion server MX. Experience working in a multi-server



    environment using development, testing, staging and production servers. Experience using FTP,



    VPN, and terminal services clients. Must be experienced with common web browsers, web standards and platform



    specific development issues.



    General Skills:



    Must be self-motivated and able to work with minimal direction.



    Work quickly and efficiently.



    Excellent analytical skills.



    Knowledge of Intel based PC systems.



    Excellent verbal and written communication skills.





    Technical Skills:



    Required skills:



    -ColdFusion MX



    -SQL Server



    -JavaScript



    -AJAX



    -CSS



    -HTML



    Desirable skills:



    -Cold fusion certified



    -Flash MX



    -Flex 2.0



    -ActionScript







    CONTACT INFORMATION:

    Ryan Mac Donald
    MegaForce LLC
    7450 West 130th Street / Suite 300
    Overland Park, Kansas 66213
    1-800-676-6625 Ext.309
    913-402-0800 #309
    913-402-8454 - Fax
    http://www.megaforceusa.com
    rmac@megaforceusa.com





    EOE/M/F/H/V

  • Sam Farmer

    You can also bind to a URL, so bind="url:getStates.cfm" just return the array with this:

    <cfoutput>#SerializeJSON(variables.result)#</cfoutput>

    And have no other output

  • Doug Cain

    Hi Ben,

    I just tried the bind example out and it fails with:

    error:http: Error invoking CFC /art.cfc : Error Executing Database Query.
    info:http: HTTP GET /art.cfc?method=getMedia&returnFormat=json&argumentCollection=%7B%7D&_cf_nodebug=true&_cf_nocache=true&_cf_rc=0
    info:http: Invoking CFC: /art.cfc , function: getMedia , arguments: {}

    in the ajax debugger. It seems to be looking for my cfc in / when both files are in my webroot: /localhost/

    This is driving me nuts as I get the same issue trying to bind to a cfc which is in a mapped directory. Hence I went back to your simple example.

    This seems like a bug to me? Anyway any thoughts greatly appreciated.

    Oh i'm running cf8 on vista 32bit..

    #4Posted by Doug Cain | Jul 13, 2007, 01:23 PM
  • Ben Forta

    Doug, try invoking those CFCs directly, a straight <cfinvoke> call in a .CFM page. It looks like you are getting a <cfquery> error independent of the Ajax stuff,s o you need to figure that out first.

    --- Ben

    #5Posted by Ben Forta | Jul 13, 2007, 01:34 PM
  • Doug Cain

    Hi Ben,

    Sorry I noticed that , cf8 didn't install the sample stuff it seems. Fixed that by grabbing the cf7 one. I have solved my problem though, I was sending parameters as you would if calling the cfc by url id=1&lang=2 etc when it should be id=1,lang=2.

    Doesn't work:
    <cfselect bind="cfc:org.survey.api.getChildren(orgid=1&surveyid=2)"

    Works:
    <cfselect bind="cfc:org.survey.api.getChildren(orgid=1,surveyid=2)"

    Simple in the end as ever! Thanks for the quick response.

    #6Posted by Doug Cain | Jul 13, 2007, 02:08 PM
  • Matt F.

    Thanks for the tutorial, I just finished a State / City select chain using it. One problem I am having is with speed. My initial states select box populates very quickly but the query of the cities takes up to 30 seconds. The query itself is very snappy. Any ideas on helping me speed this up?

    Thanks so much.

    #7Posted by Matt F. | Jul 15, 2007, 11:50 PM
  • Ben Forta

    Matt, try calling the City CFC method yourself, from a <CFINVOKE>, and see how it performs. Then try it also from a URL setting RETURNFORMAT="json", and see how that performs.

    --- Ben

    #8Posted by Ben Forta | Jul 16, 2007, 09:42 AM
  • Matt F.

    Hey Ben,

    <!--- CFINVOKE --->
    <cfinvoke
        component="/mydirectory/Loads/act_getZipCode"
        method="getOriginCities"
        returnVariable="origin_city"
        origin_state_id = "1"
    >
    <cfdump var="#origin_city#">

    3532 ms

    <!--- URL CALL --->

    http://localhost/mydirectory/Loads/act_getZipCode....

    36 ms

    I used CFINVOKE and it returns the query in 3532 ms and takes about 10-12 seconds to actually fully display the page. I called it from the url using RETURNFORMAT="json" like you suggested and it returned in 36ms... much faster. Does this bring anything to light?

    Thanks for your help!

    Matt

    #9Posted by Matt F. | Jul 16, 2007, 08:05 PM
  • Chris

    When working with this example, I get the following error in the AJAX debug window

    "window:global: Exception thrown and not caught"

    Any ideas? I have stripped everything down to a cfselect that calls a function that I have verified that works. In fact, it's resulset populates in the debug window, but my select isn't populated with it's resultset.

    #10Posted by Chris | Aug 4, 2007, 05:04 PM
  • Jeremy Rottman

    I am playing around with my new coldfusion 8 install. I am trying to use your example to bind data from two of my cfc's But for some reason, my tests don't work at all. It does not populate any of the inputs and gives no errors


    Here is the code I am using

    test.cfm

    <cfform>
    <table>
    <tr>
    <td>Select Media Type:</td>
    <td><cfselect name="catUUID"
    bind="cfc:com.UtilityManager.List_Categories()"
    bindonload="true" /></td>
    </tr>
    <tr>
    <td>Select Art:</td>
    <td><cfselect name="secUUID"
    bind="cfc:com.UtilityManager.List_Sections({catUUID})" /></td>
    </tr>
    </table>
    </cfform>


    Function: List_Categories
       <cffunction name="List_Categories" access="remote" output="false" returntype="array">
          <cfquery name="GetCats" datasource="#this.DSN#">
             SELECT
                fld_category_UUID as catUUID,
                fld_category_Name as catName,
                fld_category_Alias
             FROM
                tbl_classAd_Categories
             ORDER BY
                fld_category_Order ASC
          </cfquery>
             <cfset catArr = arrayNew(1)>
             <cfset i = 1>
             <cfloop query="GetCats">
                <cfset catArr[i] = structNew()>
                   <cfset catArr[i].catUUID = GetCats.fld_category_UUID>
                   <cfset catArr[i].catName = GetCats.fld_category_Name>
                   <cfset catArr[i].catAlias = GetCats.fld_category_Alias>
                <cfset i = i + 1>
             </cfloop>
          <cfreturn GetCats />
       </cffunction>

    Function: List_Sections

       <cffunction name="List_Sections" access="remote" output="false" returntype="array">
          <cfargument name="catUUID" required="yes" type="string" />         
             <cfquery name="GetSections" datasource="#this.DSN#">
                SELECT
                   fld_section_UUID,
                   fld_section_Name,
                   fld_section_Alias,
                   fld_category_UUID
                FROM
                   tbl_classAd_Sections
                WHERE
                   fld_category_UUID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.catUUID#" />
             </cfquery>
             
             <cfset secArr = arrayNew(1)>
             <cfset i = 1>
             <cfloop query="GetSections">
                <cfset secArr[i] = structNew()>
                   <cfset secArr[i].secUUID = GetSections.fld_section_UUID>
                   <cfset secArr[i].secName = GetSections.fld_section_Name>
                   <cfset secArr[i].secAlias = GetSections.fld_section_Alias>
                   <cfset secArr[i].catUUID = GetSections.fld_category_UUID>
                <cfset i = i + 1>
             </cfloop>
          <cfreturn secArr />
       </cffunction>

    #11Posted by Jeremy Rottman | Aug 11, 2007, 06:04 PM
  • Scott Terrell

    Hello Ben,

    Thanks for your wonderful example and dedication to CF. I'm trying to get the basic example of related selects to work using CF8 and binding.

    I get the following: "exception thrown and not caught" It does not seem to matter if I bind using cfc or url. I can hit the cfc directly via a url and it works fine. Any help would be appreciated.

    CFC

    <cfcomponent output="no">
       <cfset THIS.dsn="axdealer">
       
       <!--- Get array of media types --->
    <cffunction name="getMedia" access="remote" returnType="query">
    <!--- Define variables --->
    <cfset var data="">

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#">
    SELECT Country_ID as CountryID, Country_Name as CountryName
    FROM Countries
    ORDER BY Country_Name
    </cfquery>

    <!--- And return it --->
    <cfreturn data>
    </cffunction>

    </cfcomponent>

    FORM

    <cfform>
    <table>
    <tr>
    <td>Select Media Type:</td>
    <td><cfselect name="mediaid"
    bind="cfc:art.getMedia()"
    value="CountryID"
    display="CountryName"
    bindonload="true" method="remote" /></td>
    </tr>
    </table>
    </cfform>

  • K0rrupt

    I used this and it works great on a test site i got, but when i add it to the site i'm working on my Application.cfc onRequestStart / onRequestEnd cancels it out. any idea why?

    <cfcomponent output="no">

       <cfset THIS.name = "reg.securitycode" />
       <cfset THIS.sessionmanagement=true />
       <cfset THIS.dsn = "aiya_ca" />
       
       <cffunction name="onRequestStart" returntype="boolean" output="true">
       
        <!--- DIsplay the header.cfm --->
        <cfinclude template="../includes/Header.cfm"/>
       
        <cfreturn true />
       </cffunction>
       
       <cffunction name="onRequestEnd" returntype="void" output="true">
        <!--- Display Footer.cfm --->
        <cfinclude template="../includes/Footer.cfm" />
       </cffunction>

    </cfcomponent>

    #13Posted by K0rrupt | Aug 23, 2007, 11:59 PM
  • Kasey Koester

    I'm having trouble putting this example code up on my server. I keep getting this error: Error invoking CFC /art.cfc: Not Found

    Any suggestions on what I'm doing wrong?

    #14Posted by Kasey Koester | Sep 4, 2007, 05:18 PM
  • Jainee

    Hi! Ben,

    Thanks for your tutorial. The newly created bound selection boxes work perfect when I browse direct on our intra net but it will not working at all when browse through VPN. Do you ware of the problem? Any advice? I really like the new feature and don't want drop it due to VPN compatible issue.

    Thanks,

    #15Posted by Jainee | Sep 24, 2007, 02:46 PM
  • Sharad

    Hi Ben,
    Thanks for the example...but i have some problem executing it with Fusebox 4.
    I use following code in fusebox.init.cfm
    <cfset application.tryajax = createObject( 'component', '#REQUEST.cfcPath#.cfcs.testajax' ).init() />
                
    And then in calling page...
    <cfform>
    <cfselect bindonload="true" bind="application.tryajax.agnt()" name="agent_code" multiple="true" size="4">
    </cfselect>
    </cfform>

    it do not recognise line...
    bind="application.tryajax.agnt()"

    i tried ...
    bind="cfc:tryajax.agnt()"

    then it cannot locate tryajax CFC.

    #16Posted by Sharad | Sep 28, 2007, 01:55 AM
  • Michael Brennan-White

    Instead of sending the selected item from the first select box to the bind of the second select, is there a way of passing the first value as a CFgrid Argument.

  • Scott Terrell

    How would you go about defaulting values to the related selects.

    Thanks

  • Scott Terrell

    Has anyone been able to use the related selects (bound to a cfc) and set a default value (as if editing an existing record)?

  • David Graham

    Ben and All - As always - thanks for all your help.

    This may seem simple - but I'm trying to persist the selected values in a form when posting back to the same page. Here's what I have:

    (1) HTML SELECT - static values
    (2) CFSELECT bound to (1)
    (3) CFSELECT bound to (2)
    (4) CFSELECT bound to (2)

    On repost NONE of the values in 2, 3, or 4 are selected (though they are correct in the FORM). What am I missing? It looks like cfform.persistData and cfselect.selection handle this when using the query attribute...

    #20Posted by David Graham | Oct 17, 2007, 08:36 PM
  • Mike Demahy

    Any luck solving the problem of "window:global: Exception thrown and not caught ". I have seen lots of posts for this but no resolutions.

    Mike

    #21Posted by Mike Demahy | Oct 22, 2007, 09:42 AM
  • Jason Presley

    I put both of these files (form.cfm & art.cfc) into my root folder which I have set up on a flash drive and mapped to using IIS (which has CF installed into it). I tried calling the form.cfm page and get this error:

    error:http: Error invoking CFC /art.cfc : Not Found
    info:http: HTTP GET /art.cfc?method=getMedia&returnFormat=json&argumentCollection=%7B%7D&_cf_nodebug=true&_cf_nocache=true&_cf_clientid=1F0E1972D346E48FF8BE4E01B50D62DE&_cf_rc=0
    info:http: Invoking CFC: /art.cfc , function: getMedia , arguments: {}
    info:LogReader: LogReader initialized
    info:global: Logger initialized

    If I change the path I get even more of an error. Is there an issue with the / that is showing in front of the art.cfc? Why is this saying that it can't find the cfc.

    My local url is: http://localhost/liquidfusiondemo

    I have tried binding the cfc to the cfselect in the following ways:
    cfc:.getMedia()
    cfc:liquidfusiondemo.art.getMedia()

    Any help with this path issue would be appriciated!

  • Tony McCormick

    Hi
    I got this to work well in HTML forms mainly for Country, State, Town bound dropdowns.

    My problem:
    How can I get it work in a Flash form - I've tried every combination and thechnique I can think of - it doesnt throw an error, just no results.

    I can get it to work with straight drop downs accessing CF queries for each cfselect but I can't get it to work as "bound" fields in a Flash form using a cfc that works in HTML

    I'd be grateful for any clues.

  • Jim

    Ben,
    Is there an answer for the binding problem that many of us are having in CF 8? Using your simple autocomplete code I get this error:

    window:global: Exception thrown and not caught in the ajax cfdebug window

    This is the complete ajax cfdebug out which shows that the data is returned but never loaded into the control:

    window:global: Exception thrown and not caught (http://pww.partech.com/test/bencode.cfm?cfdebug, line 787)

    info:http: CFC invocation response: "Beauty,Blue Moon,Bowl of Flowers"

    info:http: HTTP GET /test/art.cfc?method=lookupArt&returnFormat=json&argumentCollection=%7B%22search%22%3A%22B%22%7D&_cf_nodebug=true&_cf_nocache=true&_cf_clientid=5B3D4FB5A704B1B07324B62723A43911&_cf_rc=2

    info:http: Invoking CFC: /test/art.cfc , function: lookupArt , arguments: {"search":"B"}

    info:widget: Fetching data for autosuggest id: artname , current value: 'B'

    Please help. - Jim

    #24Posted by Jim | Nov 16, 2007, 10:18 AM
  • Ben Forta

    Jim, I have asked the engineering team to look into this one too. I'll post a response when I hear something useful.

    --- Ben

    #25Posted by Ben Forta | Nov 16, 2007, 10:25 AM
  • Tony McCormick

    Hi Ben
    Love reading your stuff and this has been most useful.
    Will your example work in a Flash form?
    How do you get your example to work in a flash form?
    I've fiddled with the syntax in cfselect and get nothing - not even errors.
    I've not used a lot of Flash but I'm trying to use it to make it harder for hacks and snoops to find the names of variables passed in forms.
    Id be most grateful if you could show the changes in cfselect to do this.

    Regards
    Tony McCormick

  • Ak

    I am getting error on 2nd box bind: "Bind failed. Element not found: subcat_key"
    I can't figure it out, been trying for an hour now! This is my code:
    CFC
    <cfcomponent output="false" >
    <cfset THIS.dsn="NJDB">

    <!--- Get array of media types --->
    <cffunction name="getcat" access="remote" returnType="array">
    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#">
    SELECT cat_key, cat
    FROM tb_includes_cat
    ORDER BY cat
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.cat_key[i]>
    <cfset result[i][2]=data.cat[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    <!--- Get art by media type --->
    <cffunction name="getSubCat" access="remote" returnType="array">
    <cfargument name="cat_key" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#" >
    SELECT subcat_key , subcat
    FROM tb_includes_subcat
    WHERE cat_key = #ARGUMENTS.cat_key#
    ORDER BY subcat
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.subcat_key[i]>
    <cfset result[i][2]=data.subcat[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    </cfcomponent>

    cfm
    <cfform>
    <cfoutput query="data">#subcat# - #subcat_key#</cfoutput>
    <table>
    <tr>
    <td>Select Media Type:</td>
    <td><cfselect name="Cat"
    bind="cfc:admin.cfc.cat.getCat()"
    bindonload="true" /></td>
    </tr>
    <tr>
    <td>Select Art:</td>
    <td><cfselect name="subCat"
    bind="cfc:admin.cfc.cat.getSubCat({subcat_key})" /></td>
    </tr>
    </table>

    </cfform>

    #27Posted by Ak | Dec 11, 2007, 01:29 PM
  • Wendy

    Ben,

    Is there any samples with using the cfselect with more than 2. I haven't been able to get anything more than 2 to work regardless if I use queries, or arrays in the cfc page. Is there some sample I can review that shows three related cfselects working? I've posted this on adobe's cf forums and haven't received any posts. I'm pulling my hair out.

    #28Posted by Wendy | Dec 12, 2007, 02:41 PM
  • Jared

    Many people in these threads are getting the error listed below:

    window:global: Exception thrown and not caught (<url>, line 787)

    The reason for this is because although you are calling a CFC, your are ultimately sending a full HTTP GET request to the server. In doing so, application.cfm/application.cfc is still being processed. If you are including ANY content via application.cfm/cfc, then your call via AJAX is actually returning the result of the CFC function as well as all content being included in your requests....

    The workaround that Im using is to check the value of the CGI.SCRIPT_NAME and if it ends w/ cfc, DONT include any content... that way your CFC is only returing the data that you want returned.

    Oh yeah... make sure its in JSON format (SerializeJSON)....

    Happy coding :-)

    #29Posted by Jared | Dec 18, 2007, 04:04 PM
  • james

    Hi

    Just to follow up on a topic that I have seen in multiple threads here (and a problem I was having). Trying to get the multiple selects to work, I was getting an error saying that the cfc could not be found. I have all my components and display pages outside of webpages and can invoke all cfcs without a problem, but when it came to trying to get "ajax" to invoke the cfc no luck.

    This is very disappointing and I was wondering if there was a reason for this and if this will be changed in subsequent updates?

    I have used cfajax from indiankey.com without any problems and will continue to do so as I can not, and frankly don't want to, change the structure of my files.

    So for anyone else having problems, for me I had to move all my display and cfc files inside of webpages and then that worked for me.

    As always Ben thanks for your continued effort and great work.

    #30Posted by james | Jan 21, 2008, 09:42 AM
  • Ken Teegardin

    Ben,
    I copied the "Using Binding-pg361) example in your book (CF8-getting started) and was able to get it working with no problems. Now I need to do something with the values. I tried passing them using a form submit but that results in an Ajax error.

    How do I access the values from my bound listboxes once someone has selected them and submitted the form?
    Is there some simple way to use #form.listboxname#?

    Ken

  • Raymond Camden

    Hey Ken - I may not be reading you right. But when you submit the form, it should indeed be available as form.whatever. Have you tried cfdumping the form scope to see all the values?

  • Matt Bennett

    Ben,

    I'm trying to add an <option> tag into the code below:

    Old:

    <table>
    <tr>
    <td>Select Media Type:</td>
    <td><cfselect name="mediaid"
    bind="cfc:art.getMedia()"
    bindonload="true" /></td>
    </tr>

    New:

    <table>
    <tr>
    <td>Select Media Type:</td>
    <td><cfselect name="mediaid"
    bind="cfc:art.getMedia()"
    bindonload="true" />
    <option value="">---All Media---</option>
    </cfselect>
    </td>
    </tr>

    This scenario works great when you populate the cfselect with a query, and allow you to put the option up at the top. When I'm using the cfc and binding, this isn't showing up. Thoughts on how to make this work. Ideally the option tag would be the first option to come up (top).

    Thanks! Matt

    #33Posted by Matt Bennett | Jan 30, 2008, 12:25 PM
  • Jared

    Try manually inserting a blank record into it inside of your CFC ;-)

    #34Posted by Jared | Jan 30, 2008, 09:47 PM
  • Matt Bennett

    Hi,

    Just in case anyone wanted the code:

    <CFSET sortArray = ArrayNew(1)>
    <CFSET QueryAddColumn(data, "sort_order", sortArray)>
    <CFSET QueryAddRow(data)>
    <CFSET QuerySetCell(data, "MediaType", "")>
    <CFSET QuerySetCell(data, "sort_order", 1)>
    <CFQUERY NAME="querySorted" DBTYPE="Query">
    SELECT * FROM data
    ORDER BY sort_order desc, Category asc
    </CFQUERY>
          
    <CFRETURN querySorted>

    Matt

    #35Posted by Matt Bennett | Jan 31, 2008, 12:04 PM
  • Will Swain

    Hi Ben,

    I'm using your example code and having a problem:

    It works fine on my local server cf8 enterprise. Nothing is returned on my production server, cf8 standard. Using Firebug I can see that the call to the cfc is correct, but the response is empty. No error is being thrown. Any suggestions. (BTW, I've had similar problems with binding to a cfgrid too.)

    Code:

    <cfselect name="operaID"

    bind="cfc:#application.cfc_root#perfs.getOperas()"

    bindonload="true"></cfselect>

    <cfselect name="perfID"

    bind="cfc:#application.cfc_root#perfs.getPerfs({operaID})" />

  • Raymond Camden

    Do you have an Application.cfc in play? One with an onRequest method?

  • Ben Forta

    Will, sounds like it may be the virtual directory bug, which is supposed to be fix in the updater due out shortly.

    --- Ben

    #38Posted by Ben Forta | Feb 27, 2008, 12:46 PM
  • Will Swain

    @Ray, yes - have tried commenting it out but no change

    @Ben - ah - is this a known bug then? Is there somewhere I can find more detail about it to check against my scenario? Also, if I bind to a .cfm will I get the same problem?

  • Franklin Aizpurua

    Hello Ben,

    I'm having trouble when I try to use more than 2 related cfselects.

    Now I'm working in a Page with 5 related cfselect for country, state, county, city, street
    and because the cfc functions are invoked more than once when you change the country or state for example, the page loads the data very slowly.

    When I change the value on the first one, it invokes de cfc function for the other cfselects, but at the same time since the 2nd cfselect is changing it reinvokes again all the cfc functions of the cfselects that are related to him and so on, making the last one call the cfc function for each time the cfselects before him changed

    How can I work aroud that?

    Here is a example of my cfselects and the way the binds are related

    <cfselect name = "country"
    required = "Yes"
    message = "some text"
    query="qCountries"
    value ="ID"
    display="NAME" >
    </cfselect>

    <cfselect name = "state"
    required = "Yes"
    message = "some text"
              bindOnLoad="no"
    bind="cfc:cfc.getData0025('#dtsource#',{country})">
    </cfselect>

    <cfselect name = "county"
    required = "Yes"
    message = "some text"
              bindOnLoad="no"
    bind="cfc:cfc.getData0035('#dtsource#',{country},{state})" >
    </cfselect>
             
    <cfselect name = "city"
    required = "Yes"
    message = "some text"
              bindOnLoad="no"
    bind="cfc:cfc.getData0045('#dtsource#',{country},{state},{county})" >
    </cfselect>

    <cfselect name = "street"
    required = "Yes"
    message = "some text"
              bindOnLoad="no"
    bind="cfc:cfc.getData0051('#dtsource#',{country},{state},{county},{city}) >
    </cfselect>

    The query results are not big so it should be fast if I can avoid calling the cfc functions more times than needed.

    #40Posted by Franklin Aizpurua | Mar 6, 2008, 11:02 AM
  • Jared Shields

    I'm not sure if the "onChange" event is fired when the options inside of a select box are alters (but not the selection changed, but you could try appending @change to the end of each of your bind variables

    {country@change}

    Thanks might work.

    #41Posted by Jared Shields | Mar 6, 2008, 06:57 PM
  • Franklin Aizpurua

    Thanks for the idea Jared,

    Unfortunately it doesnt work that way, it seems the "onChange" event is fired and because of that the binds keep calling the cfc.

    Any other ideas will be appreciated.

    Thanks.

    #42Posted by Franklin Aizpurua | Mar 7, 2008, 09:01 AM
  • Paul

    I have adapted this example to work with 3 selects (the 3rd select being dependant on the second).

    I am wanting to hide the second and third selects when no value has been selected from the first and hide the 3rd select when no value has been selected from the second.

    I have been trying to get this working, but cannot find a way to intercept and use the results coming back in the bind i.e. if no results found, hide the relevant select.

    Any ideas any one?

    Paul.

    #43Posted by Paul | Mar 13, 2008, 06:17 PM
  • tim

    Your bind example works great, but I have one thing that i can't figure out. When you populate a cfselect using a query you have the selected="#FORM.inputName#" to select an option when editing a record. However, when you bind these select boxes I cannot figure out how to get my user's selection to stay selected in the event of a form error - such as other required fields that were left blank and still need to be filled out- or editing a record to reselect their previous selection that has been stored in the database. I am binding two select boxes one with a list of countries and the other with active states/provinces. I tried sending those selections as arguments to the cfc, but that simply limited my returned query only to those single records not allowing them to change their selection. Any help/suggestions to help me figure out how to maintain these user selections would be appreciated.

    #44Posted by tim | Mar 21, 2008, 07:17 PM
  • Franklin Aizpurua

    Hello all, I found the answer to my problem and decided to share it here.
    When i used 2 or more cfselet with related binds the binds called de cfc component for every value that changed.
    To avoid that use @none in the bind values, that way only the values without the @none will trigger the bind event, but will send all the variables to the cfc
    As an example: the county cfselect need the values from the country and state cfselects, but will only refresh the data when the state cfselect change value

    <cfselect name = "county"
    required = "Yes"
    message = "some text"
    bindOnLoad="no"
    bind="cfc:cfc.getData0035('#dtsource#',{country@none},{state})" >
    </cfselect>

    #45Posted by Franklin Aizpurua | Mar 25, 2008, 02:16 PM
  • Arowolo M.

    hi tim,
    i have been looking for the solution to the problem of bind and selected attributes. after 30 min of search i decide to hack the thing myself.

    <!--- function to bind to --->
    <cffunction name="ajEmployeeLookUp" access="remote" returntype="array">
    <cfargument name="SelectedId" default="0" required="yes" />
    <!--- get all the record first --->
    <cfquery name="qTemp" datasource="dsn">
       SELECT Employee,Name
    FROM Employee
    </cfquery>
    <!--- get the selected rec. using Query of Query --->
    <cfquery name="qSel" dbtype="query">
       SELECT * FROM qTemp WHERE EmployeeId = #arguments.SelectedId#
    </cfquery>
    <!--- requery and remove SelectedId from ur ressult --->
    <cfquery name="qTemp" dbtype="query">
       SELECT * FROM qTemp WHERE EmployeeId <> #arguments.SelectedId#
    </cfquery>
    <cfset i=1/>
    <cfset a=ArrayNew(2) />
    <!--- set the selected item first, since thats what the browser will choose first --->
    <cfset a[1][1] = qSel.EmployeeId />
    <cfset a[1][2] = qSel.Name />
    <cfloop query="qTemp" >
       <cfset i=i+1 />
       <cfset a[i][1] = EmployeeId />
    <cfset a[i][2] = Name />
    </cfloop>
    <cfreturn a />
    </cffunction>

    <!---- your .cfm page --->

    <!--- the selected id can be from a url, form or query. --->
    <cfselect name="Employee" bind="cfc:Employee.ajEmployeeLookUp(#selectedid#)" />

    that might not be too clean but it does the work.
    i will try and work on a better hack.

    #46Posted by Arowolo M. | Mar 29, 2008, 06:04 PM
  • James

    Hi

    I wanted to add another way to get the second related drop down to be prepopulated.
    Again this is a bit of a hack, but works for now. This is combining something that I read on Raymond Camden's site (http://www.coldfusionjedi.com/) and Ben's example.

    Simply put, you use cfajaxproxy to check to see when the first select has loaded and then call some simple Javascript that loops over the options in the select and marks the one that you want as selected.

    I'd love for their to be a better way, so if there is please someone educate me :)

    <cfajaxproxy bind="cfc:cfc.getClientContacts({contactID.value})" onSuccess="preselected">
    <script>
    function preselected(){
       preSelectedContactID = document.formName.preSelectedContactID.value;
       for(var i=0;i<document.formName.contactID.options.length;i++){
          if(preSelectedContactID == document.formName.contactID.options[i].value){
                document.formName.contactID.options[i].selected = true;      
          }      
       }
       
    }
    </script>
    <cfform name="formName">
    <input type="hidden" name="preSelectedContactID" value="#attributes.query.contactID#">
    <cfselect name="clientid"
       query="attributes.clientlist"
       value="clientid"
       display="acronym"
       selected="#attributes.query.clientID#" />

    <cfselect name="contactID" multiple="false" size="1"
       bind="cfc:cfc.getClientContacts({clientid})"
       bindOnLoad="true"
       value="ContactID"
       display="lastFirst" />

    </cfform>

    #47Posted by James | Apr 21, 2008, 04:46 PM
  • Arowolo M.

    check out http://weblog.xanga.com/adexfe/650557484/cfselect-... if it will help

  • elaine

    Using:
    <cfselect name="mediaid"
    bind="cfc:art.getMedia()"
    bindonload="true" />

    How do you set the initially selected item?

    I tried:
    <cfselect name="mediaid"
    bind="cfc:art.getMedia()"
    bindonload="true"
    selected="artItem"
    />

    But it didn't work. Does selected work with cfselect and bind?

    thanks.
    elaine

    #49Posted by elaine | Apr 27, 2008, 10:52 PM
  • Raymond Camden

    Elaine please see this blog entry:

    http://www.coldfusionjedi.com/index.cfm/2007/8/7/S...

  • Ken Hobbs

    This post is following a couple different threads. The one that brought me here is the inability to select an option with a bind expression. I solved the issue for my app by setting the bindonload attribute to "no" and initially populate the select options on my own. I've pasted a little bit of code below as an example.

    <cfselect bind="cfc:components.ui.getClientProjectsForSelect({clientID})" bindonload="no" name="projectID" id="projectID" style="width: 200px;">
    <cfif Task.taskID eq 0>
    <option value="0" selected>No project</option>
    <cfelseif Task.taskID gt 0>
    <option value="0"<cfif Task.projectID eq 0> selected</cfif>>No project</option>
    <cfloop query="ClientProjects">
    <option value="#pro_projectid#"<cfif Task.projectID eq pro_projectid> selected</cfif>>#pro_name#</option>
    </cfloop>
    </cfif>
    </cfselect>

    #51Posted by Ken Hobbs | May 1, 2008, 07:29 PM
  • Dave Boulden

    Further to Jared's solution to the issue of the error "window:global: Exception thrown and not caught".

    His solution worked nicely... in my case I initially put my CFC outside of the directory containg my application.cfm file to avoid the content created by my application.cfm. However I wanted to put the CFC within my application's directory and not have to add extra logic to application.cfm to prevent it from outputting any content when being called by a CFC. Then the answer struck me.

    At the start of the method within my CFC that returns the dynamic data to the AJAX call I simply added the following:

    <cfcontent type="text/html" reset="yes">

    and now it works just fine. The "reset=yes" clears the pre-existing page content without needing to add any logic to your application.cfm/cfc to do the same.

    The solution is essentially the same, just a bit less complicated to apply.

    #52Posted by Dave Boulden | May 2, 2008, 07:51 AM
  • Chris

    To add a default value to the cfselect try modifying your cfc as such:

    <cfset result[1][1]="">
    <cfset result[1][2]="---------">
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i+1][1]=data.artID[i]>
    <cfset result[i+1][2]=data.artName[i]>
    </cfloop>

    This will append a default selection to the cfselect

    #53Posted by Chris | May 20, 2008, 12:55 PM
  • Daniel

    I have this example working on IE, but not Firefox. Anyone else with that problem? I get this error from Firefox: Bind failed, element not found. Works great in IE, though.

    #54Posted by Daniel | May 23, 2008, 11:01 AM
  • Tim

    Hi Daniel,
    I too am having the same issue.
    I had an existing form and wanted to add the selects to it.
    once i added a set of WORKING cfselects, now i get the bind error element not found but only in FF and only on the existing form. There is something on that page that is causing this issue but for the life of me I can not find it.

    Here is the form witch works on a stand alone page with nothing else.
    I tried to debug it with FireBug but no luck

    <cfform action="#cgi.script_name#" method="post" name="styleEditForm" id="styleEditForm">
       <input type="hidden" name="StyleID" value="1">
        <tr>
        <td><b>Style Name:</b></td>
        <td><input name="StyleName" class="forms" size=40 value=""></td>
        </tr>
        <tr>
        <td><b>Category</b></td>
        <td>
          <table>
           <tr><td><b>Category</b></td><td><b>Sub Category</b></td><td><b>Sub Style</b></td></tr>
           <tr><td>
           <cfselect class="forms" name="catlist" bind="cfc:cfc.cats.getcats()" bindonload="true" display="CategoryName" value="categoryID" size=5>
        <option value="0">--categories--</option>
           </cfselect></td>
           <td><cfselect class="forms" name="subcatlist" bind="cfc:cfc.cats.getSubcats({catlist.value})" size=5 display="SubCategoryName" value="SubcategoryID">
        <option value="0">--Choose a category--</option>
           </cfselect></td>
           <!--- <td><cfselect class="forms" name="substyle" bind="cfc:cfc.cats.getStyles({subcatlist.value})" size=5 display="Name" value="ID">
          <option value="0">--Choose a Sub Style--</option>
           </cfselect></td> --->
           </tr>
           </table>

        </td>


        </tr>

        <tr>
        <td><b>Active?</b></td>
        <td><input type="checkbox" name="Active" value="1" ></td>
        </tr>
        <tr>
        <td>&nbsp;</td>
        <td><input type="submit" name="Action" value="Update" class="forms"> <input type="submit" name="Action" value="Remove" class="forms"> <input type="button" value="Cancel" class="forms" onClick="location.href='styles_add.cfm'"></td>
        </tr>
       </cfform>

    #55Posted by Tim | May 24, 2008, 03:16 PM
  • Tim

    Hi Daniel,
    if you are still searching for the issue I found it by more searching.

    basically if you have a cfform inside of a table it fails in FF.
    more the cfform outside of your tables.

    Tim

    #56Posted by Tim | May 24, 2008, 03:24 PM
  • Daniel

    Tim,
    The form is in a table on my page as well. Thanks for figuring that out. That is completely weird. I have no idea how a table would present a problem, and probably never would have figured that one out!

    #57Posted by Daniel | May 27, 2008, 08:19 AM
  • Paul

    I get "ColdFusion is undefined" JS error as soon as I take the files out of wwwroot and put them somewhere else. Anyone know what that's all about? Probably something easy. I guess it's not finding CFIDE or something.

    #58Posted by Paul | Jun 5, 2008, 06:15 AM
  • Paul

    OK, figured it out. Needed to set up a virtual directory mapping in IIS for the CFIDE directory.

    #59Posted by Paul | Jun 5, 2008, 06:19 AM
  • Paul

    How would the selects be adapted to work in an edit form, where you want to have prepopulated fields, including prepopulated values of the related selects?

    #60Posted by Paul | Jun 5, 2008, 06:28 AM
  • Laker Netman

    I am losing my mind trying the make a simple ajax-driven multiple select exercise work. I am parsing a flat text file, placing the results I want to keep in a 2D array. Regardless of the several hundred variations I try I ALWAYS get:
    "Bind failed for select box siteInfo, bind value is not a 2D array or valid serialized query"

    ...However, a "cfinvoke" immediately above the cfform/cfselect clear returns the result I expect.

    Here is the code:
    (CFC first)
    <cfcomponent output="false">

    <cffunction name="getSites"
       access="remote"
       returntype="string"
       hint="Get list of web sites">
       <cfset domains=ArrayNew(2)>
       <cfset x=2>
       <cfset domains[1][1]="Name">
       <cfset domains[1][2]="Value">
       <cfloop index="record" file="c:\temp\livesites.txt">
          <cfif (left(record,3) is "www")>
             <cfset domains[x][1] = rereplace(record, "www\.([\w-_]+?)\..*?STARTED.*", "\1")>
             <cfset domains[x][2] = domains[x][1]>
             <cfset x = x + 1>
          </cfif>
       </cfloop>

       <cfreturn SerializeJSON(domains)>
    </cffunction>

    <cffunction name="getRevisions"
       access="remote"
       returnType="string"
       hint="Get list of web site revisions">
       <cfset var revs="">
       <cfquery name="revs" datasource="somewhere">
          select revs from somewhere
       </cfquery>
       <cfreturn revs>
    </cffunction>

    </cfcomponent>

    (Now the CFM)
    <cfform name="test">
    <table>
       <tr>
          <th colspan="2">
             Select a site, then a revision
          </th>
       </tr>
       <tr>
          <td>Site:<br>
          <cfselect name="siteInfo"
             bind="siteInfo.getSites()"
             bindonload="true" />
          </td>
          <td>
          <td>Revision:<br>
          <cfselect name="revision"
             bind="siteinfo.getRevisions()"
             display="revs"
             value="revs" />
          </td>
       </tr>
       <tr>
          <td colspan="2">
             <input type="submit" value="Switch Revision">
          </td>
       </tr>
    </table>
    </cfform>

    "livesites.txt" contains the output from an "iisweb /query" command that provides a list of sites on a particular server, their status and IP address(es). My regex parses out the one piece I want: the domain name. The output from the "cfinvoke" confirms the array is being populated correctly. The getRevisions() method is stubbed out at this point, and the issue I'm seeing exists even if I completely remove that portion of the code.

    I have tried everything I can think of from the rational to irrational to get this working. It's loosely based on the CF Getting Started example on page 363 of the CF8 book Vol 1. I'm trying to use an array rather than a query, which I thought works.

    Any help would be appreciated greatly, I've already spent too much time monkeying with this problem.

    Thanks in advance,
    Laker

    #61Posted by Laker Netman | Jun 11, 2008, 05:29 PM
  • Laker Netman

    Oops! Realized I posted some errant code. Here is the correct (original) getSites() function. (I've been making so many changes, I lost track for a moment):
    <cffunction name="getSites"
       access="remote"
       returntype="array"
       hint="Get list of web sites">
       <cfset domains=ArrayNew(2)>
       <cfset x=2>
       <cfset domains[1][1]="Name">
       <cfset domains[1][2]="Value">
       <cfloop index="record" file="c:\temp\livesites.txt">
          <cfif (left(record,3) is "www")>
             <cfset domains[x][1] = rereplace(record, "www\.([\w-_]+?)\..*?STARTED.*", "\1")>
             <cfset domains[x][2] = domains[x][1]>
             <cfset x = x + 1>
          </cfif>
       </cfloop>

       <cfreturn domains>
    </cffunction>

    #62Posted by Laker Netman | Jun 11, 2008, 05:38 PM
  • Kurt Bunge

    Ben,

    As usual, you are the MAN! Thanks for this quick and easy example. Do you have any idea how many times you've helped me with ColdFusion over the years! More than I can count!

  • Kurt Bunge

    I think, for this to be really useful, we need to know how to be able to use this on an edit form, where previously selected list values need to be selected. This all works fine if it's a form the user will see only once, but in the circumstance of say, a user profile that can be edited, this solution falls well short.

  • Mark

    Tim -

    Thank you so much for the Firefox and cfform bug post - exactly what I was looking for. Too bad I didn't come across this an hour earlier :)

    #65Posted by Mark | Jun 18, 2008, 03:33 PM
  • Brandon

    Ok im having a hell of a time trying to get my third select box to work in IE. it works fine in FF but it wont load the values in the the box. When i run the ajax debugger it shows the values getting loaded to the form but they dont show up. has any one had a similar problem.

    Here is my CFC

    <cfcomponent output="false">
    <cfset THIS.dsn="dbMODE">
    <!--- Get array of media types --->
    <cffunction name="country" access="remote" returnType="array">
    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#">
    SELECT DISTINCT country
    FROM plant
    ORDER BY country
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.country[i]>
    <cfset result[i][2]=data.country[i]>
    </cfloop>
    <cfcontent type="text/html" reset="yes">
    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    <!--- Get art by media type --->
    <cffunction name="state" access="remote" returnType="array">
    <cfargument name="country" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#">
    SELECT DISTINCT state
    FROM plant
    WHERE country = "#ARGUMENTS.country#"
    ORDER BY state
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.state[i]>
    <cfset result[i][2]=data.state[i]>
    </cfloop>
    <cfcontent type="text/html" reset="yes">
    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    <cffunction name="site" access="remote" returnType="array">
    <cfargument name="country" required="true">
    <cfargument name="state" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#">
    SELECT DISTINCT site
    FROM plant
    WHERE state = "#ARGUMENTS.state#" AND country = "#ARGUMENTS.country#"
    ORDER BY site
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.site[i]>
    <cfset result[i][2]=data.site[i]>
    </cfloop>
    <cfcontent type="text/html" reset="yes">
    <!--- And return it --->
    <cfreturn result>
    </cffunction>
    </cfcomponent>

    Here is my form
    <cfform>
    Select Country:
    <cfselect name="country" bind="cfc:components.getmedia.country()" bindonload="true" />
    Select State:
    <cfselect name="state" bind="cfc:components.getmedia.state({country})" />
    Select Site:
    <cfselect name="site" bind="cfc:components.getmedia.site({country@none},{state})" />
    </cfform>

    If anyone can help me out i would really appreciate it im getting very frustrated.

    Thanks
    -Brandon

    #66Posted by Brandon | Jun 27, 2008, 11:26 AM
  • Frankie

    How can I add a loading image when a select are loading data?

    #67Posted by Frankie | Jul 2, 2008, 01:42 AM
  • Tom Noel

    Hey Ben,
    How would you include input parameters for the function call for the first select box. I have tried a dozen different ways with no success.

    #68Posted by Tom Noel | Jul 31, 2008, 03:37 PM
  • Doug Pieper

    Ben

    I have something really bizarre happening and I really hope you can help. I am able to get the select form to work perfectly when it is not associated with an application.cfc. If I comment out the OnRequestStart and OnRequestEnd (which load the header and footer respectively via cfinclude) the related selects work. However if not commented out they do not. I suspected that something in the header or footer file was the culprit and if I comment out the entire contents header.cfm and footer.cfm it works. But if there is a single character not commented it breaks . I have been pulling out my remaining hair trying to figure this one out. Any help would be much appreciated.

    #69Posted by Doug Pieper | Aug 13, 2008, 03:48 PM
  • Doug Pieper

    "I have something really bizarre happening and I really hope you can help. I am able to get the select form to work perfectly when it is not associated with an application.cfc. If I comment out the OnRequestStart and OnRequestEnd (which load the header and footer respectively via cfinclude) the related selects work. However if not commented out they do not. I suspected that something in the header or footer file was the culprit and if I comment out the entire contents header.cfm and footer.cfm it works. But if there is a single character not commented it breaks . I have been pulling out my remaining hair trying to figure this one out. Any help would be much appreciated."

    This is really bizarre if delete the entire contents of the header and or footer linked via the cfinclude the related selects work. However if I put a single character ie "a" it will break.

    #70Posted by Doug Pieper | Aug 14, 2008, 11:12 AM
  • Doug Pieper

    "I have something really bizarre happening and I really hope you can help. I am able to get the select form to work perfectly when it is not associated with an application.cfc. If I comment out the OnRequestStart and OnRequestEnd (which load the header and footer respectively via cfinclude) the related selects work. However if not commented out they do not. I suspected that something in the header or footer file was the culprit and if I comment out the entire contents header.cfm and footer.cfm it works. But if there is a single character not commented it breaks . I have been pulling out my remaining hair trying to figure this one out. Any help would be much appreciated."

    "This is really bizarre if delete the entire contents of the header and or footer linked via the cfinclude the related selects work. However if I put a single character ie "a" it will break."

    cfdebug gives me no errors. It looks like the cfselects are being popluated but the drop down menus are blank.

    #71Posted by Doug Pieper | Aug 14, 2008, 11:16 AM
  • Doug Pieper

    ""I have something really bizarre happening and I really hope you can help. I am able to get the select form to work perfectly when it is not associated with an application.cfc. If I comment out the OnRequestStart and OnRequestEnd (which load the header and footer respectively via cfinclude) the related selects work. However if not commented out they do not. I suspected that something in the header or footer file was the culprit and if I comment out the entire contents header.cfm and footer.cfm it works. But if there is a single character not commented it breaks . I have been pulling out my remaining hair trying to figure this one out. Any help would be much appreciated."

    "This is really bizarre if delete the entire contents of the header and or footer linked via the cfinclude the related selects work. However if I put a single character ie "a" it will break."

    cfdebug gives me no errors. It looks like the cfselects are being popluated but the drop down menus are blank. "

    It doesn't appear to matter if the cfinclude is local or in the application.cfc. If any cfinclude is included linking to a page with any html content the drop down menus are blank.

    ??

    #72Posted by Doug Pieper | Aug 14, 2008, 11:32 AM
  • Dave Boulden

    Doug, check my post above:

    http://www.forta.com/blog/index.cfm/2007/5/31/Cold...

    #73Posted by Dave Boulden | Aug 14, 2008, 11:36 AM
  • Doug Pieper

    Thanks Dave but I'm not sure I've got it right. It's still not working. Do you see what might be wrong?

    Here is my methods in the cfc

    <!--- Get SelectA --->
    <cffunction name="getselectA" access="remote" returnType="array">
          
    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>
          
    <cfcontent type="text/html" reset="yes">

    <!--- Get data --->
    <cfquery name="data" datasource="#ds#">
    SELECT distinct SelectAID, SelectAName
    FROM TableA
    ORDER BY SelectAName
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.SelectAID[i]>
    <cfset result[i][2]=data.SelectAName[i]>
    </cfloop>
          
    <!--- And return it --->
    <cfreturn result>
    </cffunction>



    <!--- Get SelectB --->
    <cffunction name="getSelectB" access="remote" returnType="array">

    <!--- Define Arguements--->
    <cfargument name="SelectAID" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <cfcontent type="text/html" reset="yes">

    <!--- Get data --->
    <cfquery name="data" datasource="#ds#">
    SELECT SelectBID, SelectBName
    FROM TableB
    WHERE SelectAID = #ARGUMENTS.SelectAID#
    ORDER BY SelectBName
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.SelectBID[i]>
    <cfset result[i][2]=data.SelectBName[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>
       
       
       
    <!--- Get Select C --->
    <cffunction name="getSelectC" access="remote" returnType="array">
          
    <!--- Define Arguements--->
    <cfargument name="SelectAID" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

           <cfcontent type="text/html" reset="yes">
          
    <!--- Get data --->
    <cfquery name="data" datasource="#ds#">
    SELECT SelectCID, SelectCName
    FROM TableC
    WHERE SelectAID = #ARGUMENTS.SelectAID#
    ORDER BY SelectCName
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.SelectCID[i]>
    <cfset result[i][2]=data.SelectCName[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
       </cffunction>



    Here is the form selects
       
    <cfform>    
       <cfselect name="SelectAID"
             bind="cfc:mysite.linked.cfc.mycfc.getselectA()"
             bindonload="true"/>
       <br />
       Select Issue:
       <cfselect name="SelectBID"
             bind="cfc:mysite.linked.cfc.mycfc.getselectB({SelectAID})"/>
       <br />
       Select Size:
       <cfselect name="SelectCID"
             bind="cfc:mysite.linked.cfc.mycfc.getselectC({SelectAID})"/>
       <br />
    </cfform>


    Thanks for any help it's greatly appreciated!

    #74Posted by Doug Pieper | Aug 14, 2008, 03:41 PM
  • Dave Boulden

    You also need to prevent your functions from returning anything except the data for the CFSELECT tags, set the function attribute "output" to "no"... e.g.:

    <cffunction name="getselectA" access="remote" returnType="array" output="no">

    #75Posted by Dave Boulden | Aug 14, 2008, 04:20 PM
  • Doug Pieper

    Still has a problem. It works fine without the cfinclude statements but not without.

    #76Posted by Doug Pieper | Aug 14, 2008, 04:53 PM
  • Doug Pieper

    Correction

    Still has a problem. It works fine without the cfinclude statements but not with them.

    #77Posted by Doug Pieper | Aug 14, 2008, 04:54 PM
  • Doug Pieper

    Finally got it by using the CGI.SCRIPT_NAME logic Jared mentioned earlier. Thanks for the help

    #78Posted by Doug Pieper | Aug 18, 2008, 11:42 AM
  • Sonya Brundege

    I don't know if this is helpful to any of you by now or not, but i found that i was looking for too long to find a way to first build the CFSelect with binding and then to find a way to make sure any pre-selected values were still there when I went back to edit the form. Obviously after reading this page and going to links within, you can see that Steve Savage (http://www.realitystorm.com/experiments/coldfusion...... ) has a great fix for this issue, but until Adobe accepts it and incorporates it, I don't want to have to babysit Coldfusion through upgrades to make sure it is still in place. So this is the code I am using until then...

    Add Page code:
    <!--- First Select -
    ** calls out the cfc in bind parameter (filepath and filename are separated by periods as you do in the component parameter in a cfinvoke and then you also add in the function name and a set of empty parenthesis);
    ** bindonload set to true;
    ** value set to value to pass to action and binding query;
    ** display value that is to show up in the dropdown list. --->
    <cfselect name="firstselectname" bind="cfc:cfcfilepath.cfcfilename.cfcfirstfunctionname()" bindonload="true" value="ID_value" display="display_value" />

    <!--- Second Select -
    ** calls out the cfc in bind parameter (filepath and filename are separated by periods as you do in the component parameter in a cfinvoke and then you also add in the function name);
    ** place the first CFSelect's name in curly brackets inside the parenthesis;
    ** value set to value to pass to action and binding query;
    ** display value that is to show up in the dropdown list. --->
    <cfselect name="secondselectname" bind="cfc:cfcfilepath.cfcfilename.cfcsecondfunctionname({firstselectname})" value="Sub_ID_value" display="Sub_display_value" />

    Edit page code:
    <!--- First Select -
    ** calls out the cfc in bind parameter (filepath and filename are separated by periods as you do in the component parameter in a cfinvoke and then you also add in the function name);
    ** place fieldname from query that sends pre-selected value to cfc argument (SELECTEDID);
    ** bindonload set to true;
    ** value set to value to pass to action and binding query;
    ** display value that is to show up in the dropdown list. --->
    <cfselect name="firstselectname" bind="cfc:cfcfilepath.cfcfilename.cfcfirstfunctionname(#qryName.SelectedID#)" bindonload="true" value="ID_value" display="display_value" />

    <!--- Second Select -
    ** calls out the cfc in bind parameter (filepath and filename are separated by periods as you do in the component parameter in a cfinvoke and then you also add in the function name);
    ** place the first CFSelect's name in curly brackets inside the parenthesis and place fieldname from query that sends pre-selected value to cfc argument (SELECTEDSUBID) separated by a comma and no spaces and MUST be in the same order as you list them as arguments in the CFC;
    ** value set to value to pass to action and binding query;
    ** display value that is to show up in the dropdown list. --->
    <cfselect name="secondselectname" bind="cfc:cfcfilepath.cfcfilename.cfcsecondfunctionname({firstselectname},#qryName.SelectedSubID#)" value="Sub_ID_value" display="Sub_display_value" />

    CFC that takes care of both:
    <!--- set output to no --->
    <cfcomponent output="no">
    <!--- First function sets up values for your first CFSelect statement; set access to remote; returntype in this case is array --->
    <cffunction name="cfcfirstfuntionname" access="remote" returntype="array" hint="first select list - send selectedid if coming from edit page">
    <!--- if call is coming from an edit page where a value was already pre-selected, it will be passed here --->
    <cfargument name="selectedid" default="" required="no">
    <!--- Define variables and clears them --->
    <cfset var qrySelectedID="">
    <cfset var qryListWBind="">
    <cfset var arList="">
    <!--- if call from edit page, query to single out pre-selected values --->
    <cfif isDefined("arguments.selectedid") and arguments.selectedid neq "">
    <cfquery name="qrySelectedID" datasource="#datasource#">
    SELECT ID_value, display_value
    FROM table_with_first_values
    WHERE ID_value = #arguments.selectedid#
    </cfquery>
    </cfif>
    <!--- Define values for your array to place in first select--->
    <!--- if call from edit page, eliminate pre-selected values from the rest of the values with cfif statement in where clause --->
    <cfquery name="qryListWBind" datasource="#datasource#">
    SELECT ID_value, display_value
    FROM table_with_first_values
    WHERE <cfif isDefined("arguments.selectedid") and arguments.selectedid neq ""> AND ID_value != #arguments.selectedid#</cfif>
    ORDER BY    display_value
    </cfquery>
    <!--- Build array for first select. If editing, lists the preselected values first. --->
    <cfset arList = arraynew(2)>
    <cfif isDefined("arguments.selectedid") and arguments.selectedid neq "">
    <cfset arList[1][1] = qrySelectedID.ID_value>
    <cfset arList[1][2] = qrySelectedID.display_value>
    <cfset arList[2][1] = 0>
    <cfset arList[2][2] = '*SELECT ONE*'>
    <cfelse>
    <cfset arList[1][1] = 0>
    <cfset arList[1][2] = '*SELECT ONE*'>
    </cfif>
    <cfloop from="1" to="#qryListWBind.recordcount#" index="i">
       <cfif isDefined("arguments.selectedid") and arguments.selectedid neq "">
    <cfset x = i + 2>
    <cfelse>
    <cfset x = i + 1>
    </cfif>
    <cfoutput>
        <cfset arList[x][1] = qryListWBind.ID_value[i]>
    <cfset arList[x][2] = qryListWBind.display_value[i]>
    </cfoutput>
    </cfloop>
    <cfreturn arList>
    </cffunction>

    <!--- Second function sets up values for your second CFSelect statement; set access to remote; returntype in this case is array --->
    <cffunction name="cfcsecondfuntionname" access="remote" returntype="array" hint="second select list - send selectedsubid if coming from edit page">
    <!--- the ID_value is automatically passed after you specify what select statement to get the ID_value from. You must list these in the same order you list them in the CFSelect bind () --->
    <cfargument name="ID_value" type="numeric" required="yes">
    <!--- if call is coming from an edit page where a value was already pre-selected, it will be passed here --->
    <cfargument name="selectedsubid" default="" required="no">
    <!--- Define variables and clears them --->
    <cfset var qrySelectedSubID="">
    <cfset var qryListWSubBind="">
    <cfset var arSublist="">
    <!--- if call from edit page, query to single out pre-selected values --->
    <cfif isDefined("arguments.selectedsubid") and arguments.selectedsubid neq "">
    <cfquery name="qrySelectedSubID" datasource="#datasource#">
    SELECT Sub_ID_value, Sub_display_value
    FROM table_with_second_values
    WHERE Sub_ID_value = #arguments.selectedsubid#
    </cfquery>
    </cfif>
    <!--- Define values for your array to place in second select--->
    <!--- if call from edit page, eliminate pre-selected values from the rest of the values with cfif statement in where clause --->
    <cfquery name="qryListWSubBind" datasource="#datasource#">
    SELECT lsi.Sub_ID_value, lsi.Sub_display_value, lsi.FKfromFirstTable
    FROM table_with_first_values li INNER JOIN
    table_with_second_values lsi ON li.ID_value = lsi.FKfromFirstTable
    WHERE lsi.FKfromFirstTable = <cfqueryparam value="#arguments.ID_value#" cfsqltype="cf_sql_integer"><cfif isDefined("arguments.selectedsubid") and arguments.selectedsubid neq ""> AND lsi.Sub_ID_value != #arguments.selectedsubid#</cfif>
    ORDER BY lsi.FKfromFirstTable, lsi.Sub_display_value
    </cfquery>
    <!--- Build array for first select. If editing, lists the preselected values first unless you choose something else in the first select list. --->
    <cfset arSublist = arraynew(2)>
    <cfif isDefined("arguments.selectedsubid") and (arguments.selectedsubid neq "")>
    <cfif qrySelectedSubID.recordcount>
        <cfset arSublist[1][1] = qrySelectedSubID.Sub_ID_value>
    <cfset arSublist[1][2] = qrySelectedSubID.Sub_display_value>
    <cfset arSublist[2][1] = 0>
    <cfset arSublist[2][2] = '*SELECT NEXT*'>
    <cfelse>
        <cfset arSublist[1][1] = 0>
    <cfset arSublist[1][2] = '*SELECT NEXT*'>
    </cfif>
    <cfelse>
    <cfset arSublist[1][1] = 0>
    <cfset arSublist[1][2] = '*SELECT NEXT*'>
    </cfif>
    <cfloop from="1" to="#qryListWSubBind.recordcount#" index="i">
    <cfif isDefined("arguments.selectedsubid") and arguments.selectedsubid neq "">
        <cfif qrySelectedSubID.recordcount>
    <cfset x = i + 2>
    <cfelse>
    <cfset x = i + 1>
    </cfif>
    <cfelse>
    <cfset x = i + 1>
    </cfif>
    <cfset arSublist[x][1] = qryListWSubBind.Sub_ID_value[i]>
    <cfset arSublist[x][2] = qryListWSubBind.Sub_display_value[i]>
    </cfloop>
    <cfreturn arSublist>
    </cffunction>
    </cfcomponent>

    Sorry so long. Hope it helps. I put in hints along the way to describe everything. I like detail. :)

    #79Posted by Sonya Brundege | Sep 4, 2008, 07:15 PM
  • Chip Pinkston

    Found another work around to the issue of Application and OnRequest End causing trouble for the binds (i.e. the Exception Thrown but not caught error)

    It might not be ellegant, but it was a split second fix, so maybe someone will get some value from this. I tossed a blank 'Application.cfm' and 'OnRequestEnd.cfm' file into my cfc directory. This prevents CF climbing up to my site root and pulling in the actuall Application.cfm file I'm using.

    Hope this helps.

    #80Posted by Chip Pinkston | Sep 18, 2008, 06:04 PM
  • Gavy

    Hi, That Actually Worked. Just I changed the Location of Cfc outside the folder and it worked. I tend to think why coldfusion behave so awkward.

    Regards

    http://www.randhawaworld.com

    #81Posted by Gavy | Nov 22, 2008, 09:51 PM
  • Andy

    I am getting the "Exception thrown and not caught" error as well. Both files are in the same directory and I am not using an application.cfm file. ???

    #82Posted by Andy | Dec 9, 2008, 06:04 PM
  • Craig Barnes

    Ben, I read through all the post and have seen a huge amount of Thank You's. So seriously, thank you for this Tutorial. It is huge and was I was able to implement this whole concept into my site. I have totaly cut down on the amount of code and I have been able to call the same cfc from multiple form pages. Appreciate it very much.

    I do have two question for everyone.............

    1) Did anyone find a fix for the speed issues when binding to cfc.
    I am currently doing this in my cfselect

    bind=cfc:getmethod.getSeries({Sel_getMakes@blur},{Sel_getYears@none})"

    This works really well, but very slow, especially when having the enduser step through each CFselect form field.

    I tested the cfinvoke and it is fast, I also looked at passing the url, but not sure how to pass url with bind and still refrence the other cfselects data.

    any examples on url with refrence to other cfselects?

    2. Anybody know how to, or know where I could look on getting a spinning icon next to each cfselect that is waiting on the return data. I have seen this on googles website, but can not seem to find an easy tutorial on how to accomplish this. I have the image I want to use, just need to write a script which sinces the data loaded into the CFselect.

    Thanks to everyone that has contributed on this blog. I have reeped much knowledge from everyone.

  • J Boyko

    Thank you for very useful post !!!

    When I try to create a similar example using my own tables I receive a Java Script alert message that says "Bind Failed for Select Box because bind value is not a 2D array or serialized query". However, when I try to dump the array variable, it looks absolutely fine to me. Has any one had a similar problem? Any suggestions on a possible cause?

    #84Posted by J Boyko | Jan 9, 2009, 06:43 PM
  • Sonya Brundege

    Do you have a sample of your array?

    #85Posted by Sonya Brundege | Jan 12, 2009, 10:39 AM
  • J Boyko

    You can view a sample of array here unless I fix the issue before: http://partsdepotgoodyear.com/performancedepot/sto...

    #86Posted by J Boyko | Jan 12, 2009, 01:15 PM
  • Sonya Brundege

    that one appears to be a 2D array, but you are calling out the description twice instead of an ID for the description. The id is typically what you would bind to in the next array to make your bingings talk to each other.

    #87Posted by Sonya Brundege | Jan 12, 2009, 01:50 PM
  • J Boyko

    Theoretically and practically (as you can now see ;) ) it should not make any difference. The problem lies elsewhere.

    #88Posted by J Boyko | Jan 12, 2009, 02:19 PM
  • J Boyko

    Also, I need to first be able to display a single cfselect using a component method bind before i start thinking about binding multiple cfselects, which is my eventual intent.

    #89Posted by J Boyko | Jan 12, 2009, 02:23 PM
  • Sonya Brundege

    I looked over your code and was able to duplicate your error and from what you have so far all you are missing is the "cfc:" and the "()". See how it should read below...

    bind="cfc:application.GetCategories()"

    #90Posted by Sonya Brundege | Jan 12, 2009, 05:58 PM
  • Frankie

    Hallo, I made related selects with your help. You can see in action on www.agriturismoincampania.it. I have only problem to display second related select on explorer 6 onloading.....

    Could someone suggests why do this?

    #91Posted by Frankie | Jan 20, 2009, 07:58 PM
  • Kate Maher

    Ben, thank you so much for this tutorial! It's been very helpful. I think I'm allllmost there, but I'm still getting a binding error, and am not sure why. The cfdebug output looks like my binding is happening AFTER I get the binding error.

    .cfm
    <cfselect name="type_id" bind="cfc:calls.call_types()" bindOnLoad="true" />
    <cfselect name="concern_id" bind="cfc:calls.get_concerns({type_id})" />

    calls.cfc
    <cfcomponent>
       <cfset dsn = 'admi-prod'>
       <!--- get types of calls --->
       <cffunction name="call_types" access="remote" returntype="array">
          <cfset var result = arrayNew(2)>
          <cfset var data = querynew("concern_type, type_id")>
          <cfcontent type="text/html" reset="yes">
          <cfset queryAddRow(data)>
          <cfset querySetCell(data,"concern_type", "Special Projects")>
          <cfset querySetCell(data, "type_id", 16)>
          <cfset queryAddRow(data)>
          <cfset querySetCell(data,"concern_type", "QA")>
          <cfset querySetCell(data, "type_id", 36)>
          <cfquery name="data2" dbtype="query">
             SELECT   concern_type, type_id
             FROM   data
          </cfquery>
          <cfloop index="i" from="1" to="#data2.RecordCount#">
             <cfset result[i][1] = data2.type_id[i]>
             <cfset result[i][2] = data2.concern_type[i]>
          </cfloop>      
          <cfreturn result>
       </cffunction>
       <cffunction name="get_concerns" access="remote" returntype="array">
          <cfargument name="type_id" type="numeric" required="yes">
          <cfset var data = "">
          <cfset var result = arrayNew(2)>
          <cfset var i = 0>
          <cfquery name="data" datasource="#dsn#">
             SELECT   concern, concern_id
             FROM      pbr_concerns_masters
             WHERE   concern_type = #arguments.type_id#
             ORDER BY   concern
          </cfquery>
          <cfloop index="i" from="1" to="#data.RecordCount#">
             <cfset result[i][1] = data.concern_id[i]>
             <cfset result[i][2] = data.concern[i]>
          </cfloop>
          <cfreturn result>
       </cffunction>
    </cfcomponent>

    cfdebug:
    info:bind: Assigned bind value: '16,Special Projects,36,QA' to type_id.value
    info:http: CFC invocation response: [[16,"Special Projects"],[36,"QA"]]
    error:bind: Bind failed, element not found: type_id

    Maybe the bind value is wrong? Maybe it's binding to that entire list instead of just the numbers?

    #92Posted by Kate Maher | Feb 11, 2009, 12:48 PM
  • Superfly_FR

    Thanks Ben for this: makes me start in minutes !

    Default values related tip.

    Well, a a *very simple* trick to populate default value for the first CFselect, rather than adding values to the Query and then re-sort it, if found cleaner to deal with the Array.
    So there it is (note that query and columns name has been changed, for my use only) :

    In the CFC's first function (related to the firs cfselect)

    <!--- Add an Array default Value --->
    <cfset result[1][1]=0>
    <cfset result[1][2]="--- Any type ---">
    <!--- Add QUERY results to the array --->
    <cfloop index="i" from="1" to="#infoType.RecordCount#">
    <cfset result[i+1][1]=infoType.type_id[i]>
    <cfset result[i+1][2]=infoType.type_libelle[i]>
    </cfloop>

    One thing you should notice is "result[i+1]", as I first inserted 1 row.
    Should you insert more than 1 row, then adapt it to the proper value (ad try to deal with multiple default selected values ...).

    Right, so the default value is at top position in my list, with value "0".
    Then, I have to setup an exception rule in my query :

    In the second CFC's function (related to the second Cfselect):
    <cfquery name="getInformations" datasource="#this.DSN#">
    SELECT *
    FROM informations
    <cfif ARGUMENTS.infoType NEQ 0>
    WHERE info_type_id = #ARGUMENTS.infoType#
    </cfif>
    ORDER BY info_dateDebutPub
    </cfquery>

    DBA's will shout about the "ugly joker", so just ask for whatever you need in the query; just testing here ;-).

    That's it you're set up for two related cfselect w/default value

    #93Posted by Superfly_FR | Feb 17, 2009, 07:50 AM
  • Bobbi

    I've been working on a project that will fill in the adress information on a form when a user is selected from a select box. Since for my purposes I can use the same query, is there a way run the query one time and use the results in each function.

    For a better idea of what I'm trying to do, please visit this link:
    http://www.cfdeveloper.co.uk/forum/forum_posts.asp...

    Thanks!!!

    #94Posted by Bobbi | Feb 25, 2009, 12:48 PM
  • Armando

    I'm taking the code in the example provided and modifying it to be a three select. The third query is taking 2 parameters. When I load the page the following error is thown:
    Error invoking CFC /stclive/network.cfc: Internal Server Error [Enabling debugging by adding 'cfdebug' to your URL parameters to see more information]. This error pops up twice; however, when the page finishes loading the selects work. When an option from the first select is picked the same error is thown but only once.

    Checking the CF Administrator the following entry is found in the application logs:
    The BLADE argument passed to the getPort function is not of type numeric.If the component name is specified as a type of this argument, its possible that a definition file for the component cannot be found or is not accessible. The specific sequence of files included or processed is: E:\Inetpub\www\stclive\network.cfc, line: 66.
    I have verified that the datatype in the query matches the datatype in the table/column.

    Code listed below:

    Select Switch:
    <cfselect name="switchid"
    bind="cfc:network.getSwitch()"
    bindonload="true" />

    Select Blade:
    <cfselect name="blade"
    bind="cfc:network.getBlade({switchid})" />

    Select Port:
    <cfselect name="port"
    bind="cfc:network.getPort({switchid},{blade})" />

    <cfcomponent output="false">

    <cfset THIS.dsn="datasource">

    <cffunction name="getSwitch" access="remote" returnType="array">
    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#" CACHEDWITHIN="#CreateTimeSpan(0,0,2,0)#">
          Select switchid,ipaddress
          from resnet_switches
          order by ipaddress
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
        <cfif i IS "1">
    <!--- Set the display of the first value so the select displays empty set --->
        <cfset result[1][1]= "9999">
        <cfset result[1][2]= "">
       <cfelse>
        <cfset result[i][1]=data.switchid[i]>
        <cfset result[i][2]=data.ipaddress[i]>
       </cfif>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>


    <cffunction name="getBlade" access="remote" returnType="array">
    <cfargument name="switchid" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <CFQUERY NAME="data" DATASOURCE="#THIS.dsn#" CACHEDWITHIN="#CreateTimeSpan(0,0,2,0)#">
          Select distinct(blade)
          from resnet_portinfo
          where switchid= #switchid#
          order by blade
       </CFQUERY>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
       <cfif i IS "1">
    <!--- Set the display of the first value so the select displays empty set --->
        <cfset result[1][1]= "9999">
        <cfset result[1][2]= "">
       <cfelse>
        <cfset result[i][1]=data.blade[i]>
        <cfset result[i][2]=data.blade[i]>
    </cfif>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    <!--- Get art by media type --->
    <cffunction name="getPort" access="remote" returnType="array">
    <cfargument name="switchid" type="numeric" required="true">
        <cfargument name="blade" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#" CACHEDWITHIN="#CreateTimeSpan(0,0,2,0)#">
          Select distinct port
          from resnet_portinfo
          where
              switchid= #switchid#
             and
             blade= #blade#
          order by port
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.port[i]>
    <cfset result[i][2]=data.port[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>


    </cfcomponent>

    I'm at my wits end, any help in debugging the error would be greatly appreciated.

    #95Posted by Armando | Mar 5, 2009, 01:40 PM
  • tim

    I had the same problem what i did was wrap the and statement of the where clause in a conditional statement that wouldn't call this unless the parameter met the proper requirements.

    In this case my bind was based on two previously bound selects as well so it appeared it was attempting to bind the 3rd one before the other two had obtained their values...with the conditionals it kept it from throwing the error yet still bound correctly because if for some reason it bound the third two early it will originally get all then once the values are available it will bind with the new arguments.

    I was going crazy too wondering how it was passing ""(blank) to the cfc when it should have not bound the 3rd select until the other 2 were bound. This is some code to try in your cfc. Modify as needed.

    <cfif isDefined("ARGUMENTS.switch") AND ARGUMENTS.switch NEQ 0 AND ARGUMENTS.switch NEQ "">
       AND switch=<cfqueryparam cfsqltype="cf_sql_integer" value="#ARGUMENTS.switch#" />
    </cfif>
    <cfif isDefined("ARGUMENTS.blade") AND ARGUMENTS.blade NEQ 0 AND ARGUMENTS.blade NEQ "">
       AND blade=<cfqueryparam cfsqltype="cf_sql_integer" value="#ARGUMENTS.blade#" />
    </cfif>



    obviously change the cf_sql_integer to match your datatype. Also in firebug does anyone else get extra responses where the third select returns a 401 Unauthorized message twice before successfully binding the information to the element.

    Hope this works for you and maybe someone has insight into this 401 response.

    Thanks

    #96Posted by tim | Mar 5, 2009, 02:12 PM
  • Armando

    Still throwing the same errors. Does anyone have any other insights or solutions?

    #97Posted by Armando | Mar 5, 2009, 05:05 PM
  • Raymond Camden

    For the second drop down, try setting bindOnLoad=false. This should prevent it from trying to load data before something is picked in the first drop down.

  • Wayne

    Got this to work with a URL for my first dropdown, adjusting it to fit the preexisting XML values I'm dealt.
    But how would the code or logic be adjusted if the XML data source was separate XML lists from URLs. Example follows.
    My problem is figuring out how to take the first selection and use it in the next URL for the next dropdown. This is a twist from having an all-in-one XML list. And the depth of dropdowns goes to about five, but not all options will produce values that deep.

    The Example XML:
    ----- http://fakeserver/sitemap.do?id=1 ----- renders this:
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <categoryList id="1">
    <category id="500">Home</category>
    <category id="9">Employment</category>
    <category id="61">Education</category>
    <category id="113">Housing</category>
    <category id="126">Transportation</category>
    <category id="137">Health</category>
    <category id="164">Benefits</category>
    <category id="185">Technology</category>
    <category id="192">Community Life</category>
    <category id="217">Civil Rights</category>
    <category id="6006">National Resource Directory</category>
    </categoryList>

    ----- http://fakeserver/sitemap.do?id=185 ----- renders this:
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <categoryList id="185">
    <category id="5244">State & Local Resources</category>
    <category id="186">Accessibility</category>
    <category id="187">Assistive & Information Technology</category>
    <category id="5048">Federal Accommodations Programs</category>
    <category id="5044">Resources & Organizations</category>
    <category id="5116">News Archives</category>
    <category id="5015">News & Events</category>
    <category id="5106">Grants & Funding</category>
    <category id="189">Laws & Regulations</category>
    </categoryList>

    ----- http://fakeserver/sitemap.do?id=5244 ----- renders this:
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <categoryList id="5244">
    <category id="5559">Alabama</category>
    <category id="5560">Alaska</category>
    <category id="5562">Arizona</category>
    <category id="5561">Arkansas</category>
    <category id="5563">California</category>
    </categoryList>

    I've already requested a change in format to the lists are combined into one, but that's "in the hopper" for a while.

    #99Posted by Wayne | Mar 5, 2009, 05:28 PM
  • Armando

    Thank you to Tim and Raymond for your responses. Unfortunately, I still get the same errors. Once again, any suggestions would be welcome.

    #100Posted by Armando | Mar 5, 2009, 07:02 PM
  • Wayne

    With a good amount of help from Support I finally know how this works with separate XML results...from my previous post.

    As was explained to me… the gist is to get the ID from the first dropdown into an array (a non XML object) so that it can be used as a value within the subsequent function for the subsequent dropdown.

    My question is this: What actually gets passed from the first dropdown? In Ben’s example it’s the {mediaid} from the cfselect. I’d like to know if it’s truly an XML object or a number within an array…as it appears in the cfargument line.

    #101Posted by Wayne | Mar 11, 2009, 05:24 PM
  • stang89

    Hello all, I have really found this tutorial useful. But I really need some help expanding it.
    All I am doing is changing the dropdowns to multiple selects, so adding multiple="true" to the cfselects (and updating the cfc to handle the comma seperated list instead of single value - no problem). It seems to work great. Except by default nothing is selected. So, the second select doesnt populate (which is fine with me!). However, it throws an error executing the DB query (because the first value hasnt been selected yet). This is the message:
    error:http: Error invoking CFC /AJAXTest/art.cfc : Error Executing Database Query.
    When I select a media type, it works, it seems to be as expected, except I have to do something to stop this error. I cant figure out how to make a default selection, suppress the error, or tell the second selects bind to do nothing if mediaid is undefined. Please help!

    #102Posted by stang89 | May 19, 2009, 02:27 PM
  • Francesco Pepe

    Have you tried to set bindonload= false on the first select box?

  • stang89

    I just tried setting bindonload=false on the first select box, and then it doesnt load when I go to the page. Should I use some other method to populate the first select box?

    I had tried setting bindonload=false for the second select box but that did nothing. Any other thoughts?

    #104Posted by stang89 | May 20, 2009, 07:22 AM
  • stang89

    Well, I think I found out that the error I was getting was in the query like it said, I just really didnt want to manipulate the default case, and wasnt sure how. I realized its just passing a null while nothing is selected. I can manipulate the query to say if mediaid GT 0 add WHERE mediaid IN (#arguments.mediaid#) and then change it to something else (like select nothing or everything).

    Now the issue is if I select everything, the first select populates super fast, but the second is EXTREMELY slow. In my application modeling this example I have about 75 items to return for the second select, and I really don't want it to take so long to load the page initially. Is my only choice to blank out the field? I haven't even gotten to the third related select yet, which is even bigger and slower to load initially (unacceptable slow).

    Any thoughts on the best way to optimize this? Why is it so slow, and can a <cfselct> with binding and multiple=true be given a default selection? It would be nice to just select the first in the list like a normal dropdown does.

    #105Posted by stang89 | May 20, 2009, 08:31 AM
  • Stanley Lesniak

    I am trying to do the example that you provided, but for some reason this code never calls the CFC

    cfselect name="mediaid" bind="cfc:art.getMedia()" bindonload="true" />

    Has anyone ever seen this before? I tried calling it via cfinvoke and it works fine.

    #106Posted by Stanley Lesniak | Jun 9, 2009, 03:26 PM
  • Sonya Brundege

    <cfselect name="firstselectname" bind="cfc:cfcfilepath.cfcfilename.cfcfirstfunctionname()" bindonload="true" value="ID_value" display="display_value" />

    are you missing the path maybe? You are also missing your value and display values.

    #107Posted by Sonya Brundege | Jun 9, 2009, 03:41 PM
  • Stanley Lesniak

    I just tried this and i still don't see it even making the call to the CFC. Is there something in the Application.cfm or OnRequestEnd.cfm that will allow this to work.

    <cfselect name="mediaid" bind="cfc:art.getMedia()" bindonload="true" value="mediaid" display="mediatype" />

    #108Posted by Stanley Lesniak | Jun 9, 2009, 03:49 PM
  • Agriturismo in Campania

    Hi,

    I've made this related select with start value, but I have a problem:

    my star value is -- seleziona città -- and this character with accent never encode well....

    How can I set the encoding on a output of component?

    You can see this on www.agriturismoincampania.it/ on the right box...

    Thank you

  • Tim V

    Can anyone make this faster when using multiple related cfselects? Not usable with 50 entries in the 2nd cfselect, and progressively gets worse with each additional bound cfselect.

    #110Posted by Tim V | Jun 24, 2009, 11:02 PM
  • stang89

    Well, what I did above was able to make it faster. I turned them into multiple=true selects. I have 3 selects, and while they were very slow initially, i had hundreds of entries for the second two depending on the combinations. By doing everything I can to limit the data until those combination are selected it is much faster.
    To start, can you default to a generic entry at the top of your list so nothing is loaded until a selection is made?
    Also, if you have database queries to get this data, do what you can to speed them up. Dont use SELECT * when you can use SELECT id,name.
    Good luck, hope some of this helps.

    #111Posted by stang89 | Jun 25, 2009, 08:38 AM
  • Tim V

    Thanks for the quick reply; unfortunately does not pertain to my situation. I think the reality is binding multi related cfselects has significant performance issues. Works great for 1sy 2sy related cfselects, but should be avoided with "n" number of select items.

    #112Posted by Tim V | Jun 25, 2009, 09:53 AM
  • Tim V

    Binding to a url has proven to be much faster... very cool.

    <cfselect name="region_name"
    bind="url:region_district_store.cfc?method=getRegion&returnFormat=json&region_x=#region#"
    bindonload="true" />
    <cfselect name="district_name"
    bind="url:region_district_store.cfc?method=getDistrict&returnFormat=json&region_x={region_name.value}&district_x=#district#"
    bindonload="false" />
    <cfselect name="store_name"
    bind="url:region_district_store.cfc?method=getStore&returnFormat=json&region_x={region_name.value}&district_x={district_name.value}&store_x=#store#"
    bindonload="false" />

    #113Posted by Tim V | Jun 25, 2009, 04:23 PM
  • Andrew J

    @ Tim V...Thank you so much for your post. I've been banging my head for hours trying to speed this up. FF & Safari were running it in less than 2 seconds with my app (which had 4 cfselects using bind) and IE7 took about 40 seconds. Now IE7 takes <10 seconds. You are a life-saver....Now if only you can make Google Maps on IE7 run faster when displaying markers...but that problem is for another forum. Thanks again!

    #114Posted by Andrew J | Jun 27, 2009, 02:32 PM
  • David H

    Tried your art.cfc sample as is but cannot resolve the Error Executing Database Query error.
    It seems to be finding my /includes/art.cfc file no problem but can't run the query. I'm stuck without some help.

    #115Posted by David H | Jul 29, 2009, 07:38 PM
  • Frankie

    Why in component "città" is not well formatted?

    How can I set the encoding?

    #116Posted by Frankie | Aug 14, 2009, 03:34 AM
  • Christopher Walker

    Tim V's comment posted on 6/25/09 is spot on. I was having terrible performance issues with my bind and his example worked like a dream.

  • Bill

    I found most of the posting here on CFSELECT is selecting the first select then populate the rest. While I have a situation which I need to populate all the cfselection onload. It seem easy, by setting "bindonload=true",but the hard part is while select anyone of the cfselects and populate the rest. I am pulling my hair but still could not figure out how to do. If only we could manage coldfusion tag "bindonload" in javascript then my job would be easier. So I can use onChange event at the selecting CFSELECT to turnoff the "bindonload" for the rest CFSELECTS. But I javascript does not see it. Could anyone help?

    #118Posted by Bill | Sep 14, 2009, 11:55 AM
  • Stacey

    I incorporated this into my code back in the beginning of the year and a few days ago it stopped working in IE6 and IE7 - not in firefox though.
    I have two related drop down boxes:
    <cfselect name="code" bind="cfc:questdata.getcats()" bindonload="true" />
    <cfselect name="name" bind="cfc:questdata.getoptions({code})" />
    <cfinput type="submit" name="find" value="Find your quest now!">
    I have not changed this code since I first put it up there and all of a sudden in IE the boxes are empty and I get this error 'Coldfusion' is undefined.
    Has there been some change the to libraries? can someone suggest something? Help!

    #119Posted by Stacey | Sep 14, 2009, 02:47 PM
  • Dani

    Thanks for this tutorial Ben.
    Do you know if this works with CF7?

    #120Posted by Dani | Sep 24, 2009, 10:09 AM
  • Raymond Camden

    As the entry says, it is new to ColdFusion 8. You _can_ do related selects in CF7, it just isn't quite as easy. :)

  • Dani

    Thanks Ray for your answer (I knew your were going to be the first answer).!!

    #122Posted by Dani | Sep 24, 2009, 10:20 AM
  • Christopher Walker

    Dani, be advised, if you are using long lists (say over 100 lines) it can be a real bugger to wait for the drop
    downs to populate.

    I would recommend returning the data a a json object in the bind:
    bind="url:#cfc_dirctory#/art.cfc?method=getMedia&returnFormat=json&mediaid=#mediaid#"
    it makes the build time on the dropdowns lighting fast.

  • Mutui Inpdap

    Thanks for help

  • Dani

    Hello community, I have another question about this feature.
    I have in my form 3 cfselects. The second and third populate depending on whatever has been selected on the first one. So far so good.
    This is for my "Add project" screen. Now, if I need to edit the project, I couldn't figure out yet how to select on the cfselects the info from the database but providing still the functionality of the "related" selects. In other words, if I need to modify the information on the second cfselect, it will still show me the options based on what the first cfselect retrieved from the database.
    Could someone help me? Ben? Ray? Anybody?

    Thanks a lot.

    Dani

    #125Posted by Dani | Oct 15, 2009, 02:25 PM
  • Dani

    To explain with the code:

    <cfselect name="nfgCliID"
    bind="cfc:collection.getCompany()"
    bindonload="true">
    <option selected><cfoutput query="myQuery">#myCompany#</cfoutput></option>
    </cfselect>

    </td>

    #126Posted by Dani | Oct 15, 2009, 02:28 PM
  • Christopher Walker

    Try adding cachedwithin="#CreateTimeSpan(0,0,0,0)#" to your cfquery block.

  • Christopher Walker

    Also if your select looks like:
    Select nfgCliID, myCompany

    then you shouldn' need to use:
    <option selected><cfoutput query="myQuery">#myCompany#</cfoutput></option>

  • Dani

    Thank you Christopher, but I think I got lost.
    What the cachedwithin will do? Also, in which of my queries should it go? I have the first query to select the company the second to select the contact at that company and the third to select the projects for that company. Thanks for all the help by the way.

    #129Posted by Dani | Oct 15, 2009, 02:51 PM
  • Christopher Walker

    I only use that exact function when querying tables that are updated frequently.

    cachedWithin (optional) Timespan, using the CreateTimeSpan function. If original query date falls within the time span, cached query data is used. CreateTimeSpan defines a period from the present, back. Takes effect only if query caching is enabled in the Administrator.

    To use cached data, the current query must use the same SQL statement, data source, query name, user name, and password.

  • rav

    Hi
    I have problem of similar kind with the cfselect not working with bind attribute.
    The bind attribute is working properly in localhost but when uploaded to server the bind attribute is not working properly. I have application.cfc in my application however i also user this line of code "<cfcontent type="text/html" reset="yes">" at starting inside the function in cfcomponent.
    The strange thing which i observed is when commented the cfc completely then I dont see any error dislpaying which is unusal( where an error is expected in normal case). But In my localhost I can see an error as expected.

    #131Posted by rav | Nov 13, 2009, 03:14 PM
  • S.C. Adams

    I am having trouble with the ‘onChange’ event firing.
    I use a query in the cfselect so I can have a value selected, if in edit mode.
    Also there is a CFGrid that uses the .value to populate itself. I am in CF8.

    The cfselect :
    <cfselect name="OID_SERVICE" query="Selectdata" value="OID" display="Service_CD" selected="0"
       onChange="showServiceRatesGrid();">
    </cfselect>

    The ‘selected’ value will come from a query column when implemented for real.

    I have also tried “javascript: showServiceRatesGrid()” with and without the semi colon.

    The JS function, up in the <body> tag is :

    <script language="JavaScript" type="text/javascript">
       showServiceRatesGrid() {
    alert("one");
       if (document.getElementById("OID_SERVICE").selected.value == "0") {
       document.getElementById("ServiceRatesGrid").style.display="none";
          } else {
       document.getElementById("ServiceRatesGrid").style.display="block";
          }
       }      
    </script>
    I want it to only show the grid if a value other than 1 is selected.

    The ‘alert’ never appears.

    Any ideas?

    #132Posted by S.C. Adams | Apr 20, 2010, 03:44 PM
  • Bobbi Rawlings

    Is there a way to refresh the first select box if a new value is added to the underlying database table via a pop-up form?

    On my entry form (myentry.cfm), the first select box, "hostgenus" is filled with "genus" (ex. Crassostrea, Crypto, etc.), the related select
    for "hostgenus" called "hostspecies" contains the genus and species for the chosen genus. For example, if "Crassostrea" is
    selected from "hostgenus", then "hostspecies" shows a list like this: Crassostrea ariakensis, Crassostrea virginica, etc.)

    If the desired "hostspecies" isn't in the box, a new one can be added via a pop-up form (popup1.cfm). The popup1.cfm contains
    a select box, "cbo_genus", that is populated with a list of genus, and there is a form field where the species can be added.
    So if I want to add a new genus/species, I select the genus that I want from "cbo_genus" and then in type the new species
    name in the form field.

    After the popup1.cfm is submitted, it closes. My new genus/species appears beautifully on myentry.cfm in the "hostspecies" box.

    My problem is this: in the popup1.cfm mentioned, if I don't see a genus that I want in the "cbo_genus" box, I can open,
    from popup1.cfm, another a pop-up form, popup2.cfm, that allows a new genus to be added. After popup2.cfm submits, the
    new genus appear's in popup1.cfm's cbo_genus box. I then select my new genus from cbo_genus and type my new species in the form
    field. But after I submit popup1.cfm, I do not see my new entry. Neither my new genus in "hostgenus" or the new genus/species
    in "hostspecies".

    All of this makes sense to me. Which is why I understand that I need a way to refresh "hostgenus". Help will be appreciated.

    #133Posted by Bobbi Rawlings | Apr 28, 2010, 01:38 PM
  • Three Feathers

    I am joining the fray. I've tried everything in the 133 or so comments that I understood and I'm still getting; "Bind failed, element not found: num". First select fills and the second doesn't. I'm hoping I just need another set of eyes to point something out to me. I'm adding my cfc and calling form code. Good luck and thanks in advance.
    <cfcomponent output="false">

    <cfset THIS.dsn="BCC">

    <!--- Get array of divisions --->
    <cffunction name="getDivisions" access="remote" returnType="array">
    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get divisions --->
    <cfquery name="data" datasource="#THIS.dsn#">
        select num, romNum + '- ' + title as displayed
             from divisions
             where num < 6
             order by num
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.num[i]>
    <cfset result[i][2]=data.displayed[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    <!--- Get program by num --->
    <cffunction name="getPrograms" access="remote" returnType="array">
    <cfargument name="num" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var data="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="data" datasource="#THIS.dsn#">
    SELECT ProgCode, title
    FROM progDetails
    WHERE division = #ARGUMENTS.num#
    ORDER BY title
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#data.RecordCount#">
    <cfset result[i][1]=data.ProgCode[i]>
    <cfset result[i][2]=data.title[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    </cfcomponent>

    <cfform>
    <table>
    <tr>
    <td style="padding-right:4px">Select Division:</td>
    <td><cfselect name="selDiv" id="division"
    bind="cfc:progDetails.getDivisions()"
    bindonload="true" /></td>
    </tr>
    <tr>
    <td>Select Programs:</td>
    <td style="padding-right:4px"><cfselect name="selProg"
                bindonload="false"
          <!---bind="{selDiv.selectedItem.data}"></cfselect>--->
    bind="cfc:progDetails.getPrograms({num})" />
    </td>
    </tr>
    </table>
    </cfform>

    #134Posted by Three Feathers | May 25, 2010, 03:47 PM
  • Will Swain

    I'm still having the same issues I had before with this. I've had to use JQuery to achieve the same result, but revisiting it again and I would like to get this fixed.

    CF Version 8,0,1,195765 Standard.

    The code is as per your example. Firebug shows the cfc being hit, but nothing is returned and no error shown.

    If I call the function in the cfc directly, rather than bind to it, then I get a result no problem, so clearly something is amiss with the binding.

    I'd really appreciate any ideas.

    Thanks

    #135Posted by Will Swain | Jun 11, 2010, 08:07 AM
  • Will Swain

    I'm still having the same issues I had before with this. I've had to use JQuery to achieve the same result, but revisiting it again and I would like to get this fixed.

    CF Version 8,0,1,195765 Standard.

    The code is as per your example. Firebug shows the cfc being hit, but nothing is returned and no error shown.

    If I call the function in the cfc directly, rather than bind to it, then I get a result no problem, so clearly something is amiss with the binding.

    I'd really appreciate any ideas.

    Thanks

    #136Posted by Will Swain | Jun 11, 2010, 08:08 AM
  • Jainee

    I have similar problem. Do you have other .cfc files in the same cfc folder? Try to create another folder only containing the .cfc file for your binding use. It works for me. I know some coding in other related files will interfere with the binding, I have not figured out exactly what yet.

    Good luck!

    #137Posted by Jainee | Jun 11, 2010, 10:13 AM
  • Three Feathers

    Will,
    I'd be interested in how you got the data from a cfquery Into jquery.

    #138Posted by Three Feathers | Jun 11, 2010, 11:11 AM
  • Will Swain

    Hi Jainee,

    Nope. It happens that this project only has one cfc. Access is set to remote, and there is nothing in the code that I can see that would prevent it from working. Very annoying.

    There is this interesting line in the cf ajax debug window:

    window:global: _31c is null (http://*********/******/scripts/ajax/package/cfajax.js, line 1264)

    #139Posted by Will Swain | Jun 14, 2010, 05:31 AM
  • Bobbi

    I'm getting an "element var_proposal undefined" error that I cannot figure out! My select boxes look like this:
    <cfselect name="cbo_status"
    bind="cfc:proposal_status_cfc.getStatus()"
    bindonload="true"
    display="prop_status"
    id="prop_status"


    />

    <cfselect name="cbo_proposal"
    bind="cfc:proposal_status_cfc.getProposal({cbo_status})"
    value="prop_number"
    size="3"
    />

    Then in my cfc, in the function getStatus, I "select distinct prop_status from proposal" then in the function getProp I have a cfargument=var_proposal. I'b be glad to post all of the cfc's code, but I didn't want to clog the blog.

    #140Posted by Bobbi | Jul 1, 2010, 12:58 PM
  • Bobbi

    I'm getting an "element var_proposal undefined" error that I cannot figure out! My select boxes look like this:
    <cfselect name="cbo_status"
    bind="cfc:proposal_status_cfc.getStatus()"
    bindonload="true"
    display="prop_status"
    id="prop_status"


    />

    <cfselect name="cbo_proposal"
    bind="cfc:proposal_status_cfc.getProposal({cbo_status})"
    value="prop_number"
    size="3"
    />

    Then in my cfc, in the function getStatus, I "select distinct prop_status from proposal" then in the function getProp I have a cfargument=var_proposal. I'b be glad to post all of the cfc's code, but I didn't want to clog the blog.

    #141Posted by Bobbi | Jul 1, 2010, 12:59 PM
  • Bobbi

    I'm getting an "element var_proposal undefined" error that I cannot figure out! My select boxes look like this:
    <cfselect name="cbo_status"
    bind="cfc:proposal_status_cfc.getStatus()"
    bindonload="true"
    display="prop_status"
    id="prop_status"


    />

    <cfselect name="cbo_proposal"
    bind="cfc:proposal_status_cfc.getProposal({cbo_status})"
    value="prop_number"
    size="3"
    />

    Then in my cfc, in the function getStatus, I "select distinct prop_status from proposal" then in the function getProp I have a cfargument=var_proposal. I'b be glad to post all of the cfc's code, but I didn't want to clog the blog.

    #142Posted by Bobbi | Jul 1, 2010, 01:00 PM
  • ms

    hi Ben
    how can i pre select first dropdown field (with id or name) ?
    thanx

    #143Posted by ms | Jul 23, 2010, 08:07 PM
  • ms

    hi Ben
    how can i pre select first dropdown field (with id or name) ?
    thanx

    #144Posted by ms | Jul 23, 2010, 08:07 PM
  • david

    Ben,
    I have implemented your example in my code and it is working well. My problem comes when I call the same form for edit. The fields are always populated BindOnLoad. I cannot figure out how to show the value from the data base, like having selected in html form. Is this not possible with this process. Do I need separate code to do the update?

    #145Posted by david | Sep 16, 2010, 10:44 PM
  • Gem

    This post helped me troubleshoot my error using CFINVOKE becase the CFDEBUG was turned off on our new CF9 Server.

    Thank You!!

    #146Posted by Gem | Oct 19, 2010, 10:49 AM
  • Hugo

    Sorry for the NOOB question. I have copied the cfcomponent into a file and called it AJAX.cfc.
    I then copied the form information into a file called AJAX.cfm. I saved them both to the
    same folder. But when I run AJAX.cfm, I get an error that reads:

    "The specified CFC art could not be found"

    What am I missing?

    #147Posted by Hugo | Nov 8, 2010, 11:34 PM
  • mvergel

    Thank's Ben, this sample solve my problem, is too easy to implement in my project.

    Best regards.

    #148Posted by mvergel | May 2, 2011, 04:01 AM
  • bianca

    I really need help with my dropdown menus with bind. I am getting the error "Bind failed, element not found: T_categories_ID"
    The first menu shows up well, the second is empty. here's the code. I must be missing something:-) And Yes,both category and subcategory are in 1 table, I am working on a CMS developed by someone else....
    CFC:
    <cfcomponent output="false">

    <cfset THIS.dsn="#request.dba#">

    <!--- Get array of media types --->
    <cffunction name="getcategories" access="remote" returnType="array">
    <!--- Define variables --->
    <cfset var getcategories="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->
    <cfquery name="sel_categories" datasource="#request.dba#">
    SELECT
    T_categories_ID,
    T_categories_name as categoryname
    FROM
    T_categories
    WHERE
    T_categories_ID > 0
    AND
    T_categories_subcat_ID = 0
    AND
    T_categories_active = 1
    AND
    T_categories_partnerID = #session.partnerid#
    ORDER BY T_categories_name ASC
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#sel_categories.RecordCount#">
    <cfset result[i][1]=sel_categories.T_categories_ID[i]>
    <cfset result[i][2]=sel_categories.categoryname[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    <!--- Get art by media type --->
    <cffunction name="getsubcategories" access="remote" returnType="array">
    <cfargument name="T_categories_ID" type="numeric" required="true">

    <!--- Define variables --->
    <cfset var getsubcategories="">
    <cfset var result=ArrayNew(2)>
    <cfset var i=0>

    <!--- Get data --->

    <cfquery name="sel_sub_categories" datasource="#request.dba#">
    SELECT DISTINCT
    T_categories_subcat_ID,
    T_categories_subcat_name as subcatname
    FROM
    T_categories
    WHERE
    T_CATEGORIES_SUBCAT_ID = #ARGUMENTS.T_categories_ID#
    ORDER BY
    subcatname ASC
    </cfquery>

    <!--- Convert results to array --->
    <cfloop index="i" from="1" to="#sel_sub_categories.RecordCount#">
    <cfset result[i][1]=sel_sub_categories.T_CATEGORIES_SUBCAT_ID[i]>
    <cfset result[i][2]=sel_sub_categories.subcatname[i]>
    </cfloop>

    <!--- And return it --->
    <cfreturn result>
    </cffunction>

    </cfcomponent>
    __________________________
    CFM:
    <cfselect name="categories"
    bind="cfc:cfc.categories.getcategories()"
    bindonload="true" />

    <cfselect name="subcategories"
    bind="cfc:cfc.categories.getsubcategories({T_categories_ID})" />
    _________________

    #149Posted by bianca | May 28, 2011, 03:29 AM
  • Tayyab

    Hi-
    When i executed this code on my local system, it executed fine, but when I
    uploaded to http://www.lasanisarkar.org/bait/form.cfm and executed it does not give any error except

    Webpage error details
    User Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.3; .NET4.0C; .NET4.0E)
    Timestamp: Tue, 19 Jul 2011 06:02:37 UTC
    Message: Exception thrown and not caught
    Line: 798
    Char: 1
    Code: 0
    URI: http://www.lasanisarkar.org/CFIDE/scripts/ajax/pac...

    #150Posted by Tayyab | Jul 19, 2011, 02:04 AM
  • PISSED OFF

    I can't believe it is still an issue with using an Application.cfc ...
    No application.cfc and this sample works perfect.
    Add an Application.cfc and it goes to crap..
    Why pray tell has Adobe not addressed this issue?
    This has been a problem since 5/31/07..
    Holly crap, do I need to look a for a different programming language, cus if adobe is not working on issues like this after 4 years...... I have to wonder are they working on CF X anymore or will this programming language just get shoved to the side,
    And I should start learning @#$#@$#*#$%& PHP?

    It would behoove someone to reply to this comment, as I can't believe the laziness I am seeing with CF issues...

    #151Posted by PISSED OFF | Aug 20, 2011, 07:13 PM
  • ion

    in cf9, this example doesn't work very well, in fact, i was only able to make it work having a cfselect and a cfgrid, but not with 2 cfselects. on the other hand, it works perfect without arrays:
    <pre>

    <cfcomponent>
    <!--- Get array of groups --->
    <cffunction name="getGroups" access="remote" returnType="query">

    <cfset var groupData = "">
    <!--- Get data --->
    <cfquery name="groupData" datasource="myDSN">
             SELECT group_id, group_name
             FROM myTable
    </cfquery>

    <!--- And return it --->
    <cfreturn groupData>
    </cffunction>
       
    <cffunction name="getApps" access="remote" returnType="query">
       
    <cfargument name="group_id" required="true">
          <cfset var appData = "">

    <cfquery name="appData" datasource="myDSN">
             SELECT app_id, app_display_name
             FROM myOtherTable
             WHERE   group_id = #arguments.group_id#
    </cfquery>
    <cfreturn appData>
    </cffunction>
    </cfcomponent>

    <!------------------------------------------------------------------------>
    <cfform>
    <cfselect name="groups" bind="cfc:selects.getGroups()" bindonload="true" value="group_id" display="group_name" selected="group_id" />
    <p>
    <cfselect name="apps" bind="cfc:selects.getApps({getGroups})" bindonload="false" value="app_id" display="app_display_name" selected="app_id" />
    </cfform>

    </pre>

    #152Posted by ion | Oct 21, 2011, 01:40 PM
  • Cathy White

    You may find yourself here looking for help with a "bind failed" error, just as I did a couple of weeks ago. Unfortunately for me, the quick tips I found here and elsewhere didn't solve my exact problem. Some code I didn't write that had been "working" for over a year starting producing an avalanche of "bind failed" errors seemingly out of the blue, but only in IE 9 and nowhere else. This in itself is a clue, and if this is your problem, I recommend the following:

    I copied the code into a test page and began by eliminating all of the extraneous javascript and formatting in the template of the page. The error still occurred, which ruled out any of that code. Then I began methodically eliminating code until I was able to isolate the problem: improper HTML structure was causing the error. How imperfect was it? It was an unclosed <p> tag. I spent upwards of 5 hours on this problem only to fix it with 3 keystrokes. Imagine the four-letter words I mentally edited out of that last sentence.

    It appears that the smallest deviation from proper HTML structure can cause this problem in IE 9. If I had started with methodical instead of looking for a quick fix, I could have saved some hours, but maybe you will see this and save yourself some time. Alas, it is too late for me.

    #153Posted by Cathy White | Nov 29, 2011, 01:20 PM
  • Alex Zamora

    How can I preserv the select value when there are errors and you click the back browser button and avoid to reset the cfselect?

    #154Posted by Alex Zamora | Jul 29, 2012, 11:40 PM
  • Allen

    Ben,
    I found this is very helpful since I'm not savvy with Javascript but I need the value of my second dropdown be able to do a little bit more thn just showing
    a value related to the first drop down.
    For example:
    The first drop down is listing amount of money such as $10,$20,$30,$40, etc
    The second drop down will list the related fees: $2,$5,$10,$20,etc
    In certain cases I need to apply dicount to the fee so I need to past 2 values from my second drop down this way when a discount exist for this user
    the fee listed on the drop down should show discounted fee.

    I tried this to my second drop down but it did not work:
    <cfselect name="OurFee" bind="cfc:cfcomponents.mycomponent.getFees({FeeID,Diskon})" class="inputSelect" />

    On the component side I did:
    <CFIF arguments.Diskon LTE 10>
        <cfquery name="datafee" datasource="MyDSN">
        SELECT OurFee
        FROM tblFeeLookUp
        WHERE FeeID = <cfqueryparam cfsqltype="cf_sql_numeric" value="#ARGUMENTS.FeeID#">    
        </cfquery>
    <CFELSE>
        <cfquery name="datafee" datasource="MyDSN">
        SELECT (OurFee - #arguments.Diskon#) AS OurFee
        FROM tblFeeLookUp
        WHERE FeeID = <cfqueryparam cfsqltype="cf_sql_numeric" value="#ARGUMENTS.FeeID#">    
        </cfquery>      
    </CFIF>

    Can I get some help on how to be able to do something like this?

    #155Posted by Allen | Sep 19, 2012, 12:23 PM
  • Derek Versteegen

    [sign] So I've been reading this post up and down and I can't seem to find the answer to my issue - many close issues but not quite exactly what I am running into.

    So, the short of it is my first select drop box works successfully - bind, function, query, array, to drop box. On page load, the second drop box doesn't have any options. When an option from the first drop box is selected, the second one does not update.

    All my functions work - when I hard code and invoke mt CFC at the top of the page, passing in a value from what would be in the second drop box, I get a result. But, the bind in the second select doesn't seem to either running the update or passing a value in.

    There seems to be similar issues here in the past but I can't seem to find a resolution. I'm running CF 9,0,0,251028 and the following code:

    First Select:
    <cfselect name="resource_unit" id="resource_unit" bind="cfc:/cfc/Practitioners.aryGetResourceUnits()" bindonload="true" tabindex="4" />

    Second Select
    <cfselect name="abbreviation" id="abbreviation" bind="cfc:/cfc/Practitioners.aryGetPractitioners({resource_unit})" bindonload="false" tabindex="5" />

    I can post more code if needed, but all the functions in the CFC work when invoked on the form page.

    Eventually, I want to add this so there is ultimately a third field updated with the selection from the second drop box.

    <cfinput type="text" name="employee_name" id="employee_name" value="" size="35" tabindex="6" bind="cfc:/cfc/Practitioners.aryGetPractitioner({abbreviation})" bindonload="false" />

    Any help would be greatly appreciated.

  • Derek Versteegen

    Ok - appending my post with an interesting behavior. I added an option to the <cfselect> tag and on page load the options I hard coded appear then are refreshed and removed. The first select drop box successfully populates with the correct options from the database call (the one I hard coded is removed from the options). The value I hard coded in the second drop box appears and then quickly refreshes and is removed and there are no options replaced. Which is fine since it is supposed to be dependent on the first select. But what is interesting is that the third text input field, for that brief moment, correctly grabs the second field value and looks it up to get the value I am ultimate after.

    This confirms that I'm not having a lot of the issues discussed here. But I can figure out why the other call backs are not triggered on change. Any ideas?

    Unit:<br />
    <cfselect name="resource_unit" id="resource_unit" bind="cfc:/cfc/Practitioners.aryGetResourceUnits()" bindonload="true" tabindex="4"><option value="PMRBG">PMRBG</option></cfselect><br />

    Abbreviation:<br />
    <cfselect name="abbreviation" id="abbreviation" bind="cfc:/cfc/Practitioners.aryGetPractitioners({resource_unit})" bindonload="true" tabindex="5"><option value="GAJOMAGE">GAJOMAGE</option></cfselect><br />

    Employee<br />
    <cfinput type="text" name="employee_name" id="employee_name" bind="cfc:/cfc/Practitioners.aryGetPractitioner({abbreviation})" value="" size="35" tabindex="6" bindonload="true" /><br />

    Functionally, the user selects a unit, which updates the Abbreviation list with a smaller list. When the user selects the abbreviation, it pulls the employee full name and puts it into the text input field.

  • TJ

    This tutorial is great, I was able to create 3 drop down selection for countries then states then cities.
    They work except when my users are accessing them from iPhone and google chrome they errors out!!!!!
    It says: Bind failed, element not found: CountryId [Enable debugging by adding 'cfdebug' to your url parameters to see more information]

    Not sure why this is happening because the code is not depend on the browser, how come CF can't handle this? not sure how can I fix this situation because in other browsers, such as, IE and Mozilla, they work just fine!

    #158Posted by TJ | Apr 3, 2013, 05:15 PM
  • Jay Smith

    For some reason, if you have css on the same page, no data will appear in the dropdown.

    #159Posted by Jay Smith | May 28, 2013, 07:48 PM
  • Tjenko

    Hi Ben!
    I found this posting very helpful. I did it in one of my registration form and it was working beautifully.
    But when I need the same functionality for other form within this same application, the functionality doen't work.
    The error message keep saying bind failed because CountryId is not passed.
    I copied and pasted the cfselects from the registration form to this other form and nothing is changed.
    Logically the bind on cfselect should call the same component, am I right?

    #160Posted by Tjenko | Oct 14, 2013, 02:37 PM
  • Alan Mackenzie

    Hi Ben
    I love your concise code!
    This connected select box trick would be magic but I'm missing something!
    The first select works and triggers on the first onchange. The second function works if I invoke the component and manually populate the select with the data from the invoked function. However, the second select with the bind leaves me an empty box everytime.
    Also the onchange doesn't seem to fire a second time.
    I've tried without the onchange and I'm getting nothingCould you help an old man out.
    Thanks terribly
    Alan (