So here is an interesting question. Take a look at Ben's post on related selects in ColdFusion 8 (and don't forget it is even easier now). Pretty simple, right? Well how do you set a control to use Ajax and have a default selected item? Turns out this isn't so easy.

The first thing I tried was selected=, figuring that would be the easiest solution, but unfortunately it didn't work.

I then tried ajaxOnLoad, thinking maybe I could set the default myself. But ajaxOnLoad() is fired when the page is complete, but before those Ajax calls to populate the drop downs are done.

I then tried onLoad in the cfform tag. This didn't work at all. So I threw the problem over to Todd Sharp, and together we were able to come up with a solution. It ain't pretty, but it works. My hope is that folks can look at this and suggest something nicer. I'm actually a bit surprised this isn't supported out of the box. It seems like I use forms half the time to edit content, not create content, so being able to set defaults is a must.

Anyway - the code:

<cfajaxproxy bind="javascript:test({mediaid},2)"> <head> <script> var imdone = false; function test(x,val) { if(!imdone) { var dd = document.getElementById('mediaid'); for(var i = 0; i < dd.length; i++){ if(dd.options[i].value == val){ dd.selectedIndex = i;

} } imdone = true; } } </script> </head>

<cfform > <table> <tr> <td>Select Media Type:</td> <td><cfselect name="mediaid" id="mediaid" bind="cfc:art.getMedia()" bindonload="true" value="mediaid" display="mediatype" /></td> </tr> <tr> <td>Select Art:</td> <td><cfselect name="artid" bind="cfc:art.getArt({mediaid})" value="artid" display="artname" /></td> </tr> </table> </cfform>

So first off - note the use of cfajaxproxy. It is bound to the first drop down. When the value changes, and this occurs on initial load, code is run to set the default. In this case note the hard coded value of 2. This would be #form.selected# or whatever. Also note the use of a variable to remember that the default value has been selected. The cfajaxproxy will always run on change, so we want to be sure it is run only once.

Thoughts? This code only supports one selected item, and only supports defaulting the left control, but obviously it could be extended to handle both. Again though it is a bit disappointing that essentially one line of code:

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

had to be extended by about 10 lines of JavaScript. To be fair, my beloved Spry doesn't make this much easier. You can use spry:if type conditionals so it is a bit slimmer. Maybe someone can speak to how other frameworks like Prototype does it?

Edit: A followup post by Todd: Selecting Multiple Default Items With ColdFusion 8 Ajax Controls