ColdFusion and populating a dropdown, based on the selection of another

I thought I would write a tutorial on this subject as it appears to be the most asked from people, and show how to utilise some features of ColdFusion that seem to be overlooked by a lot of people.

When this question arises it seems that the majority if not all the answers and solutions that I see, are always pointing to the use of jQuery and never have I seen one that uses what is already built into ColdFusion.

Lets begin with the basics of a country select for our first dropdown, and then we will have a second that will be repopulated with the states for that country. As an example I'll use just a sub select of what one would usually use, only to highlight its usage and hopefully people will be able to modify this to suit their needs.

The first place that we need to begin with is the html side of this first, and the following code will give us a very quick form that will give us our two drop down boxes.

<div>
   <select id="CountrySelected" onChange="javascript: getStates();">
      <option value="Canada">Canada</option>
      <option value="Mexico">Mexico</option>
      <option value="United States">United States</option>
   </select>
   <select id="states">
      <option value="">N/A</option>
   </select>
</div>

As you can see this is very straight forward, we have applied the onchange attribute to the select tag. This is so that when a user changes the selection in the first drop down, we are going to run some JavaScript code to do a bit of magic for us.

The JavaScript code is not very complicated and looks like this.

<cfajaxproxy cfc="getStates" jsclassname="stateProxy" />
<InvalidTag>
   function getStates(country) {
      var instance = new stateProxy();
      instance.setCallbackHandler(getStatesResult);
      instance.getStates(country);
   }
   function getStatesResult(result){
      var states = document.getElementById('states');
      while(states.length > 0) {
         states.remove(0);
      }
      for(var i=0; i<result.length; i++ ){
         var myNewOption = new Option(result[i], result[i]);
         states.options[i] = myNewOption ;
      }
      states.selectedIndex = 0;
   }
</script>

The most important thing to notice in this block of code is the CFAjaxProxy tag, this allows us to map a coldfusion component, to be used as if it was a javascript object. With a ColdFusion component method set to remote we can then call this method and return and pass information to the server,

So as you can see the JavaScript function we have defined above called getStates sets up this call, and provides a callbackhandler. We don't really need to do this in all cases, but it is a good habit to do this. So when the the call has returned from the server, the function getStatesResult is called. And we take the information that we have received and then do what we need to do. In this case we remove everything from the states drop down, and we repopulate the dropdown with the new data that has been returned.

This is as basic as it gets with ColdFusion and Ajax calling.

The ColdFusion Component that was used is as follows.

<component>
   <cffunction name="getStates" access="remote" return="struct">
      <cfargument name="CountryName" type="string" required="true" />
      <cfset var local = {} />
      <cfset local.reStruct = {} />
      <cfset local.states['Canada'] = ["Alberta","British Columbia","Manitoba","New Brunswick","Newfoundland and Labrador","Nova Scotia","Ontario","Prince Edward Island","Quebec","Saskatchewan","Northwest Territories","Nunavut","Yukon Territory"] />
      <cfset local.states['United States'] = ["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","District of Columbia","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina","North Dakota","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"] />
      <cfset local.states['Mexico'] = ["Aguascalientes","Baja California","Baja California Sur","Campeche","Chiapas","Chihuahua","Coahuila de Zaragoza","Colima","Distrito Federal","Durango","Guanajuato","Guerrero","Hidalgo","Jalisco","Mexico","Michoacan de Ocampo","Morelos","Nayarit","Nuevo Leon","Oaxaca","Puebla","Queretaro de Arteaga","Quintana Roo","San Luis Potosi","Sinaloa","Sonora","Tabasco","Tamaulipas","Tlaxcala","Veracruz-Llave","Yucatan","Zacatecas"] />
      <cfset local.retStruct = local.states[arguments.CountryName] />
      <cfreturn local.retStruct />
   </cffunction>
</component>


RT @aeoncube: RT @cfbloggers: ColdFusion and populating a dropdown, based on the selection of another - http://smurl.be/?a4166 (A nice w ... Jul 26, 2010
RT @aeoncube: RT @cfbloggers: ColdFusion and populating a dropdown, based on the selection of another - http://smurl.be/?a4166 (A nice way to do it!) Jul 26, 2010
RT @cfbloggers: ColdFusion and populating a dropdown, based on the selection of another - http://smurl.be/?a4166 (A nice way to do it!) Jul 26, 2010
ColdFusion and populating a dropdown, based on the selection of another - http://cfbloggers.org/?c=43214 Jul 26, 2010