Ask a Jedi: Automatically selecting certain values with ColdFusion Ajax-bound controls

Shawn asked:

I am having an issue with a cfselect and I am wondering if you can help. I have a cfselect that binds to a CFC (to get value list) after another cfselect is changed. I need to have the cfselect (that is bound) to autoselect a particular value, if it exists in the returned values from the CFC. I have tried the onChange attribute of the cfselect (to see if it is triggered when the values are updated, but it appears that won't work. Do you know of any other way to achieve the autoselect?

I wasn’t exactly sure what he meant here, so I countered with: So basically, your CFC may return A,B,C and you want code that says ,”Hey, if you ever return C, default to that being selected.” That’s what he meant.

So - this is a case where ColdFusion’s Ajax makes something that is typically kinda easy a bit awkward. In jQuery I’d have code that binds to the first drop down and manually fires off the request to get the content for the second drop down. In the handler for it I’d notice “C” and select it. While you can do that with cfajaxproxy, I went with a route that may be simpler but… I don’t know. It works - but I’d be happier with it in jQuery. ;)

<cfajaxproxy bind="javascript:mediachange({mediaid})"> <cfajaxproxy bind="javascript:artchange({artid})"> <head> <script> var mediaChanged = false; function mediachange(x) { console.log("media "+x); mediaChanged = true; } function artchange(x) { console.log("art "+x); if(mediaChanged) { //get my values var dd = document.getElementById('artid'); for(var i = 0; i < dd.length; i++){ if(dd.options[i].text == "Space"){ dd.selectedIndex = i; } } mediaChanged = false; } } </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> </code>

In the example above I’ve got two related drop downs. Selecting an item in the first drop forces new data to load in the second. In order to handle the new “Look for C and auto select it” logic I used two cfajaxproxy tags. One runs a JavaScript function on changing the first drop down and the second one handles the other one. When a change is made to the first drop down I set a boolean value, mediachanged, to true. When the second one changes, I look for this value. If it is true, I grab the values and look for my special value. In this case I just hard coded the word “Space”. That could be dynamic. I could also check the value and not the text. Notice though that I set mediachanged back to false. Why?

Well, I needed a way to know when the values in the second drop down were loaded. Whenever ColdFusion loads these values, it will select the first one, automatically ‘changing’ it and running artchange. I only need to care about this once - right after you change the media drop down. If you change the drop down yourself, I don’t want to reset it back to Space. Hence the use of the variable.

So as I said - not terribly elegant - but it works.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Comments