Our Blog

This is an example of two cfselect related, where the second dropdown depends on the selection of the first one.
In the code shown, when a state is selected, the second dropdown shows the cities in that state.

The code:

<cfsavecontent variable="actionPopulate">
if(_global.arrCities == undefined) _global.arrCities = selectCity.dataProvider.slice(0);

   var arrCities:Array = _global.arrCities;
   selectCity.removeAll();

for(var i = 0; i < arrCities.length; i++)
{
   var item = arrCities[i].data.split('|');
   if(item[1] == selectState.value )
   {
      selectCity.addItem(arrCities[i].label,item[0]);
   }
}
selectCity.enabled = (selectCity.length >0) ? true:false;
</cfsavecontent>

<cfform name="myform" format="flash" width="400">
<cfformgroup type="hbox">
   <cfselect queryposition="below" label="State" name="selectState" query="state" value="stateid" display="name" width="200" onChange="#actionPopulate#">
      <option>Please select a parent category</option>
   </cfselect>
   <cfselect queryposition="below" disabled="true" label="City" name="selectCity" width="200">
      <cfoutput query="city"><option value="#cityid#|#stateid#">#name#</option></cfoutput>
   </cfselect>
</cfformgroup>
</cfform>

View the example.
Download the source.

Nahuel Foronda

Nahuel Foronda

43 Comments

  1. Chuck
    What if I'm pulling my data from a query not a array? How would the variable=&quot;actionPopulate&quot; read?
  2. Laura
    Hi Chuck,
    The data is populated from a query. If you look at the source in the zip file, you will see that we are making a query with querynew(). Also, the cfselect attribute &quot;query&quot; only takes a query name as its value, so if we wanted to populate it from an array, we would've needed to make a loop with the option tags instead.

    I hope this clarifies things a bit :)
    Laura
  3. Wayne
    Thank you this site has helped me tremendously. What I would like to know is how I can populate a third cfselect. I tend to get the third select list but the list doesnt change when I select the a different index in the second select.

    Honestly I not sure how the code needs to be added to have a third select.

    I have one more question please. I would like the lists for the selects have a blank option in the list first as the list is populated in the secound and third select. I have to generate information based on the selections. Currently I can not as eg: select a item in the first select that has other list attached to it for the secound and third selects. The other lists populate without a blank option field. I know its has to to with the code in the cfsavecontent tag.

    I would really appreciate your help as what code would look like

    Kind regards

    Wayne
  4. LM
    As you mentioned that the data is populated from a query, is there a source code that shows this (i.e. populate from stored proc rather than having the state &amp; city hard-code in the cfscript section). Any help is very much appreciated because I'm quite new to this.
  5. Wayne
    Hi LM,

    I would like to help you. I can send you the code to help you with this. I need to know whether you are also using CFC's of you are just pulling the store proceedure straight into the .cfm page

    HINT: You will need to have a seperate query for each select which can be done in a single store proceedure with seperate result sets.

    You then will using the results of each result set from the store proceedure to populate the selects.

    Hope this helps :)

    Wayne (South Africa)
  6. harvey berkowitz

    harvey berkowitz

    It didn't work for me.
    Using Coldfusion MX 6.1. I suppose this work just for CF MX 7 +.
    Getting the following:

    Attribute validation error for tag CFFORM.
    The tag does not allow the attribute(s) FORMAT,WIDTH. The valid attribute(s) are ACTION,ARCHIVE,CLASS,CODEBASE,ENABLECAB,ENABLEJAR,ENCTYPE,ID,METHOD,NAME,ONLOAD,ONRESET,ONSUBMIT,PASSTHROUGH,PRESERVEDATA,SCRIPTSRC,STYLE,TARGET.

  7. Wayne
    Hi Nahuel,

    Please could you be of help please. I have posted a question previously see: Posted By Wayne / Posted At 3/29/05 4:12 AM

    I would be so grateful if you could show me the code changes to add this functionality. You are the only person that has even come close, as your code works great.

    Im new to CF7 action script. I really need your help urgently please/

    my email: [email protected]

    Thanx for all your good work

    Wayne
  8. Thanks for the code. I am new to CF7 actionscript, too. What if a state is preselected? In my code selectCity stays grayed out, even if the statefield is preselected coming into the page
  9. Brian B
    Hi Nahuel,

    Can I get a copy of the code that has the third (and possibly 4th) related select menu driven by multipul queries?

    Thanks in advanced,
    Brian
  10. Nahuel
    FYI we made a new post showing a <a href="/blog/?mode=entry&amp;entry=52A45F0A-3048-525A-B2223CDF0A32A366">multiple selects related</a>
  11. Michael
    Thanks for this post. I just cannot seem to get the as. If I replace the script with two queryies, q1 with the states and q2 with the cities and associated states, can you help out with the as in the &quot;actionPopulate&quot; variable? Thanks for bearing with me.

    Michael.
  12. Casey A

    Casey A

    Hey guys, how do you concatenate a DISPLAY field?
    &lt;cfselect queryposition=&quot;below&quot; label=&quot;Recipient&quot; name=&quot;eeid&quot; query=&quot;sample&quot; value=&quot;EMPLID&quot; display=&quot;employee, emplid&quot; width=&quot;200&quot; &gt;
    &lt;option&gt;Please select an employee&lt;/option&gt;
    &lt;/cfselect&gt;
  13. Casey A

    Casey A

    Got a bit of a workaround, or what may be the solution... What do you think?

    &lt;cfquery name=&quot;sample&quot; datasource=&quot;#application.dsn.oiws#&quot;&gt;
    SELECT *, employee +' - '+ EMPLID AS Myname
    FROM sooeAuditPMP
    ORDER BY Employee
    &lt;/cfquery&gt;

    &lt;cfselect queryposition=&quot;below&quot; label=&quot;Recipient&quot; name=&quot;eeid&quot; query=&quot;sample&quot; value=&quot;EMPLID&quot; display=&quot;Myname&quot; width=&quot;200&quot; &gt;
    &lt;option&gt;Please select an employee&lt;/option&gt;
    &lt;/cfselect&gt;
  14. Marco Bacchiani

    Marco Bacchiani

    Thanks a lot for you work.
    But my answer is this:
    if i want execute the second query not previously but after have known the item value of first select,
    to use this value as &quot;where filter&quot; for the second select ?
    How make this ?

    Best regards.

    Marco Bacchiani
  15. Patrick

    Patrick

    I am having trouble replacing the hard-coded queries with 2 queries in my CFC.

    I can get the State select to populate without any problem, but I can't figure out how to determine which StateID is the selected one (to be used in my query that populates the city select).

    Thanks!

    Patrick G.

  16. Laura
    Patrick,
    I recommend you to use this custom tag. It should be simpler to use:
    http://www.asfusion.com/blog/entry/multiple-selects-related-flash-cfform
  17. ChrisB

    ChrisB

    Hi,

    I have a question about having multiple selects in the parent category and then having all the options displayed in the child cfselect. Even if you do allow multiple selects for the parent cfselects, it only will display the last selected parent's child option. Is there a way you can have multiple child option displayed if there are multiple parent options selected. For example if I wanted to look at Toyotas and Nissans, and then select the Camry and Maxima to compare. Just wanted to know if it was possible and how it could be done. Multiple=&quot;yes&quot; allows you to select it, but doesn't populate it. Thank you for your time and mainly for this great resource you have provided.

    Chris
  18. help
    Where do i get a copy of the select with 3 or 4 related selects? Nathan asked about that earlier but I didnt see a reply.
  19. Laura
    You can find it here:
    http://www.asfusion.com/blog/entry/multiple-selects-related-flash-cfform
  20. Stephen Cassady
    I was wondering how to adjust the script in the cfsavecontent or what to add in an onload to allow the second select to be enabled, correctly populated with selections related to the first drop down, and have one of the values pre-selected (so to pre-fill both selections). Example - returning to the form on some sort of error checking, preserve data will correctly pre-fill the first select, but the script does not pre-select the second select.
  21. Raphael Anzenberger

    Raphael Anzenberger

    Hey Wayne,

    Did you ever get a solution for your problem related to your comment:

    &quot;I have one more question please. I would like the lists for the selects have a blank option in the list first as the list is populated in the secound and third select. I have to generate information based on the selections. Currently I can not as eg: select a item in the first select that has other list attached to it for the secound and third selects. The other lists populate without a blank option field. I know its has to to with the code in the cfsavecontent tag.&quot;

    Could you post-it there for me?

    Thanks!

    Raphael.
  22. Tim
    I needed to do the same thing - have a blank option as well on the child menu in case there was no corresponding option to the item chosen in the parent. A guy on the DFW/CF Users group suggested doing adding the line of code outlined below and it works. The one drawback is that it adds the blank line permanently. So, if there are no options, you still get &quot;Select...&quot; once a parent item is chosen. However, you still get the correct items related to the dropdown chosen in the parent dropdown.

    selectqTripUpgrade.removeAll();
    &lt;---&gt; Add the line below after the line above ************
    selectqTripUpgrade.addItem(&quot;select...&quot;,&quot;0&quot;);

    Hope this helps...

    Thanks,
    Tim
  23. Rich
    I am not sure if someone has addressed this issue yet. If so please let me know.

    I am having problem with my version of related select boxes in a cfform. I have 3 select boxes. The first box controls what is displayed in the other 2 boxes and that's it. I used flash remoting with the form and it works exactly how I want it except for one thing. When I change the first select box, the information displayed in the other 2 are correct, but the values always come up as undefined. When I test the information returned after the remoting call, it will give me the correct text displayed, but the current value of the selected index is undefined. Is there a way to correct this? And each select box has it's own cfc method that populates its information.
  24. Derek
    What would cause the form to not initialize? I don't get any errors, the flash form just does not load.
  25. Harold
    Laura:

    I have been trying to get this code to work for awhile. The problem I am having is that I need to pull the informaiton to make the querynew() from an existing query. Can you please tell me how to do this or give me a starting push?

    Thank you
  26. Laura
    Harold,
    This custom tag should help you:
    http://www.asfusion.com/blog/entry/multiple-selects-related-flash-cfform
  27. Liam
    Hi I'm trying to work your code using queries rather than code the options for the drop down. Its not quite working and i think this is related to a problem in the action script, although being a novice I'm not sure what to do. Does anyone have any advice? Here is my code:

    <cfquery name="QREGION" datasource="OSM">
    SELECT * FROM Region
    </cfquery>

    <cfquery name="Qmain" datasource="OSM">
    SELECT * FROM MAINTABLE
    </cfquery>

    <cfquery name="test" datasource="OSM">
    SELECT * FROM test
    </cfquery>




    <cfscript>
    region = queryNew("regionid,regionname",'varchar,varchar');
    for (x = 1; x LTE qregion.RecordCount; x=x+1) {
       queryAddRow(region);
          querySetCell(region,'regionid','#qregion.regionid[x]#');
          querySetCell(region,'regionname','#qregion.regionname[x]#');
          

    }
    </cfscript>

    <cfscript>
    district = queryNew("regionid,district",'varchar,varchar');
    for (x = 1; x LTE test.RecordCount; x=x+1) {
       queryAddRow(district);
          querySetCell(district,'regionid','#test.regionid[x]#');
          querySetCell(district,'district','#test.district[x]#');
          }
    </cfscript>







    <cfsavecontent variable="actionPopulate">
    if(_global.arrCities == undefined) _global.arrCities = selectCity.dataProvider.slice(0);
       
       var arrCities:Array = _global.arrCities;
       selectCity.removeAll();
       
    for(var i = 0; i < arrCities.length; i++)
       {
       var item = arrCities[i].data.split('|');
          if(item[1] == selectregion.value )
          {
             selectCity.addItem(arrCities[i].label,item[0]);
          }
       }
       selectCity.enabled = (selectCity.length >0) ? true:false;
    </cfsavecontent>







    <html>
    <head>
    <title>OSM</title>


    <meta http-equiv="Content-Type" content="text/html;">
    <!-- Fireworks MX Dreamweaver MX target. Created Fri Jun 20 14:42:26 GMT+0100 (GMT Daylight Time) 2003-->
    <body bgcolor="#ffffff">
    <div align="center">
    <cfform action="/osm_menu2.cfm" format="flash" height="650" width="650" method="post">
    <cfformgroup type="tabnavigator">
          <cfformgroup type="page" label="Reporting" height="300">
          
          
          <cfformgroup type="horizontal" label="Region:">

          </cfformgroup>
          
          <cfformgroup type="horizontal" label="Region:" >
          <cfselect queryposition="below"
    name="selectregion" query="region" value="regionid"
    display="regionid" width="200"
    onChange="#actionPopulate#">
    <option>Please select a parent category</option>
    </cfselect>
       </cfformgroup>
          <cfformgroup type="horizontal" label="District:">
          <cfselect queryposition="below"
    name="selectCity" width="200" >
    <cfoutput query="district"><option value="#district#">#district#</option></cfoutput>
    </cfselect>
          </cfformgroup>
          <cfinput type="submit" name="submit1" value="submit">
          </cfformgroup>

             
    </cfformgroup>
    </div>
    </cfform>
    </body>
  28. Riz.
    Hi, Such a nice script, but when it is slow when there is more than 1000 record in a combo box. im using P-III with 256 MB RAM, but not satisfied with speed. Is there any solution to speed up it.


    Thanks
  29. Stephen Cassady
    I would lay odds that the script isn't what is slow - it will be found with your graphics card/main desktop. It's a lot of data it'll shove around. A person with a "snappy" desktop will see the 1000 recodrs with much less display lag that you will. Always been a problem with big "lists, tables, etc.". Not CF/Flash related directly, but with the computer's ability to process such a long list. Anyway to logically break it down some?
  30. Simon
    Wow! Thanks to the team at AsFusion. You have hooked me on flash forms.

    I do have a question for all out there. Any assistance would be appreciated. I have spent weeks searching for the answer.

    I basically want to use a selected grid value to filter a another query result, so I can bind these to a repeated form item or something similar.

    I have 2 database tables:

    Business: BusinessId, BusinessName
    Locations: LocationId, BusinessId, State

    This has been set up since each business has multiple locations.

    So I populate a grid with a query similar to below:

    Select *
    FROM business, location
    WHERE business.businessID = Location.businessID

    This shows a list of businesses with a row for each of their locations, which is what I want.

    PROBLEM:

    I want to bind the grid to some form items. This is no problem except if I want to show ALL locations for the business selected no matter which location row is select.

    I assume I need to filter a location query based on the selected businessid in the grid and display in a repeater group??

    I guess something like this, but as bind using actionscript filter:

    Select *
    FROM locations
    WHERE businessid = {datagrid.selectedItem.businessid}

    By the way I do not want to submit the form to achieve this.

    Thank you kindly.
  31. Simon
    Sorry neglect above question.It looks like i should be able to get most of the info here:

    Binding a grid to a grid
    http://www.asfusion.com/blog/entry/quick-grid-bindings

    Thanks
  32. Kay
    OK, I am a real newbie to Java in fact about the only thing I do know about it is how to spell it. Any, I want to use this example above. My two queries are shown below.

    <cfquery name="stage" datasource="customer">
    SELECT opty_stage, opty_stage_code
    FROM opty_stage
    </cfquery>

    This pulls records that look something like this:
    09-Won = Opty_stage
    09 = opty_stage_code


    <cfquery name="reason" datasource="customer">
    SELECT reason_closed_can, reason_code
    FROM opty_reason_closed
    </cfquery>

    This query pulls records that look like this:
    09-Best Value = reason_closed_can field
    09 - reason_code field

    In this query you will get a one to many match based on the opty_stage_code and the reason_code. The user will choose the opty_stage first and based on this I want the reason_closed_can populated. Does this make sense? I copied down your code and tried to change the field names, but of course it did not work since I don't have a clue what I am doing.

    Any help would be appreciated.
    Thanks
  33. solmyr

    solmyr

    Hi Laura,

    I have combobox that populate by dataprovider.

    var search_Planname:mx.controls.ComboBox = search_Planname;
    responseHandler.GetPlanName_Result = function( results: Object ):Void {
    //when results are back, populate the cfselect
    search_Planname.labelField = "Planname";
    search_Planname.dataProvider = results;
    }

    I want to have "Select All" option as the first option in the combobox. I tried using QueryPosition but it doesnt work.

    Thanks.

    Here's the code I use to display cfselect which will be populate from the event above. It dont show "Select All" as I want.

    <cfselect name="search_Planname" query="qGetPlan" queryPosition="below"
    display="PlanName" value="PlanNum" width="450" disabled="false" label="Plan Name:" >
    <option value=""> Select All</option>
    </cfselect>
  34. Michael W.

    Michael W.

    Hello,

    I think this question is really easy for you, but I dont have experience with actionscript and I have no idea, how to use this two-cfselect-related-solution for database-queries. My question is,how can I modify this code to use database-records in the comboboxes.

    THX in advance
  35. T
    Michael W. - Could you please post your solution?
  36. Laura
    solmyr,
    Whenever you use remoting to populate your controls, you will lose all other items, including "Select all". After you receive the records, you need to manually add that item in the dataprovider. See the documentation on how to add items to a drop down (combobox)

    T,
    I would recommend you to use this custom tag: http://www.asfusion.com/blog/entry/multiple-selects-related-flash-cfform
  37. T
    Thanks so much Laura - I used the custom tag and it works an absolute treat!! You rock :)
  38. Rey
    May be you guys can help me out with this, I'm using the above code for the two selects. This works just fine, but I'm trying to make the second select populate some text fields by doing an onChange event but for some reason the form will not display. here is the CFC code and the cfsavesontent code.

    <cffunction name="contactRet" access="remote" returntype="query">
    <cfargument name="groupid" type="numeric" default="" required="yes">
    <cfargument name="cont_name" type="string" default="" required="yes">
    <cfquery name="retCont" datasource="mysqlcf_otgadmin">
    SELECT contactid,groupid,cont_name,cont_address,cont_city,cont_state,cont_zipcode,cont_phone,cont_email
    FROM contacts
    WHERE groupid = '#groupid#' AND cont_name = '#cont_name#'
    </cfquery>
    <cfreturn retCont>
    </cffunction>

    <cfsavecontent variable="ContactsReturn">
    if ((groups.value != '') && (contacts.value != '0')){
    //create connection, replacing the gateway url with yours
    var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection("http://<cfoutput>#cgi.HTTP_HOST#</cfoutput>/flashservices/gateway/");
       
    //declare service
    var myService:mx.remoting.NetServiceProxy;
    //put the controls in scope to avoid calling _root
       
        var groupid = groups.value;
        var cont_name = contacts.value;
       
        //make an object that will handle the response
    var responseHandler = {};
       
        //function that receives the response
    responseHandler.onResult = function( results: Object ):Void {
    //when results are back, we show the text received
        //_root.groupid.text = results.getItemAt(0).groupid;
          _root.cont_name.text = results.getItemAt(0).cont_name;
          _root.cont_address.text = results.getItemAt(0).cont_address;
          _root.cont_city.text = results.getItemAt(0).cont_city;
          _root.cont_state.text = results.getItemAt(0).cont_state;
          _root.cont_zipcode.text = results.getItemAt(0).cont_zipcode;
          _root.cont_phone.text = results.getItemAt(0).cont_phone;
          _root.cont_email.text = results.getItemAt(0).cont_email;
          
    mx.controls.Alert.show(Object(results));
    }
        //function that receives any error that may have occurred during the call
    responseHandler.onStatus = function( stat: Object ):Void {
    //if there is any error, show an alert
    alert("Error while calling cfc:" + stat.description);
    }
        myService = connection.getService("otgadmin.cfc.contactsCom", responseHandler );
    //make call, passing one parameter
    myService.contactRet(groupid,cont_name);
          }
    }
    else {
    mx.controls.Alert.show('Please Select a customer from the customer list or check the Add Contact box and enter the customer information!');
    }
    </cfsavecontent>
  39. BRuce
    I am using this tag. I have my query as such:
    SELECT States.State_ID, States.State_Abv, Venues.Venue_City_ID, Venues.Venue_City_Name
    FROM States RIGHT JOIN Venues ON States.State_ID = Venues.Venue_State_ID GROUP BY State_ID, State_Abv, Venue_City_ID, Venue_City_Name

    In another custom tag I am using, it works fine. Only one state abbv is shown and when I select it all the cities show. However, with your tag, I am getting as many states showing as there are cities. What is up with that? What do I need to do to fix it? I did not change the action script at all, just using an actual query invoked from a CFC.

    Thanks,

    Bruce