Updating a drop down based on an HTML Grid Selection

A user on cf-talk today asked if you could bind a drop down to an HTML grid. I tried it and got an error. The drop down expects a query or 2d array for it's source. Too bad. But - there is a solution. I blogged a few weeks ago about noting grid changes (Reacting to a grid row selection). This technique uses the CFAJAXPROXY tag to monitor the grid. In my previous blog entry, I just did an alert, but it's trivial to update a drop down as well. Consider the following example:

<cfajaxproxy bind="javascript:fixCat({entries.category})">

<script>
function fixCat(c) {
   var dd = document.getElementById('mycat');
   console.log(dd.options.length);
   for(var i=0; i<dd.options.length;i++) {
      if(dd.options[i].value==c) dd.selectedIndex=i;
   }
}
</script>
<cfset q = queryNew("category,title")>
<cfloop index="x" from="1" to="10">
   <cfset queryAddRow(q)>
   <cfset rcat = listGetAt("Cat1,Cat2,Cat3", randRange(1,3))>
   <cfset querySetCell(q,"category", rcat)>
   <cfset querySetCell(q,"title", "Title #x#")>
</cfloop>

<cfform name="test">
<cfgrid autowidth="true" name="entries" format="html" query="q" width="600" bindOnLoad="true">
<cfgridcolumn name="category" display="true">

<cfgridcolumn name="title" header="Title">
</cfgrid>

<cfinput type="text" name="thetitle" bind="{entries.title}">
<cfselect name="mycat" id="mycat">
<option value="Cat1">Cat1
<option value="Cat2">Cat2
<option value="Cat3">Cat3
</cfselect>
</cfform>

So a good part of the code is my fake query and grid. You can pretty much ignore that. Note the first line uses cfajaxproxy with a bind attribute. This is what will fire and pass the proper column value to my function. I then just check the drop down option values and select it when I find a match.

In the grid - why did I have display="true"? Well normally this would be a hidden column, but I wanted to double check my work and ensure that the code was working. Not that I make mistakes of course.

Off Topic P.S.: Today I discovered "Apocalpso" by Mew. Dang what a good song. I've played it about 10 times now. Of course, every time I hear a really cool song - the first thing I want to do is try to play it in Guitar Hero II!

Comments

Gareth's Gravatar The console.log is for firebug, right? I think that will throw an error in IE if people copy and paste the code directly.

All the bind stuff is really nice though. I really need to download the dev edition locally and check it out more.
# Posted By Gareth | 8/31/07 6:13 PM
Shawn Inman's Gravatar Thumbs up on the Mew comment. I first downloaded Apocalypso when it was the free single of the week long ago, and I totally fell in love with it. Rock on, Ray!
# Posted By Shawn Inman | 8/31/07 7:10 PM
todd sharp's Gravatar Gareth: You could have easily done a ColdFusion.Log.dump() too...
# Posted By todd sharp | 8/31/07 8:14 PM
Gareth's Gravatar Certainly. Just wanted to make sure there wasn't another reason for the console.log
# Posted By Gareth | 8/31/07 9:14 PM
Raymond Camden's Gravatar @Gareth - yep - that was a mistake (me leaving the line in there).
# Posted By Raymond Camden | 8/31/07 11:14 PM
Will Swain's Gravatar Thanks Ray. Looks like that does just what I needed.
# Posted By Will Swain | 9/1/07 3:36 AM
Oliver's Gravatar Now try and get a pull down within a html cfgrid. there seems to be a bug with cfgridcolumn and valuesdisplay and value. Everything works swell, until you pick a pull down and the display switches to the value rather then the valuedisplay. when I did a submit, the submited form varibles got scrambled. Sad really every CFrelease I keep wanting to use the new UI functions, and they always seem to fail. For fun I tried dumping the entire <select></select function into the calling query, it almost worked but something inside cfgrid prevented selecting other selections
# Posted By Oliver | 9/14/07 7:32 AM
M's Gravatar I'm having trouble updating the drop down when the form first loads. Works great otherwise. Any suggestions on how to get this to fire when it's first loaded?
# Posted By M | 10/10/07 5:10 PM
tim's Gravatar i did it this way since i'll have many dropdowns and want to use the same js function to select all of them. Works great. ajaxproxy works great too just thought this might be helpful.

<script type='text/javascript'>
var hasRun = false;
function selectDropDown(x,val) {
if(!hasRun) {
var dd = document.getElementById(x);
for(var i = 0; i < dd.length; i++){
if(dd.options[i].value == val){
dd.selectedIndex = i;
}
}
}
hasRun = true;
}
</script>

<cfinput type="hidden" name="categoryHiddenBind" value=""
bind="javascript:selectDropDown('CategoryID',
{grid.ComponentCatID})">
*Category:
<cfselect query="getCategories" name="CategoryID"
display="CategoryName" value="CategoryID" queryPosition="below">
<option value="0">-- Select a Category -- </option>
</cfselect>
# Posted By tim | 4/21/08 10:32 AM