ColdFusion 9: Yet Another Way to Refresh a Bound CFSELECT
One of the really nice features of CF8 and CF9 is bindings. But there are a few noticeable gaps, such as refreshing a bound CFSELECT list. From what I can tell, this still is not supported. Though apparently CF9 did introduce support for the selected attribute.
I spent some time pouring over the cfajax.js file, and had little more than a headache to show for my troubles. Then I came across a slick suggestion in an older entry on Todd Sharp's blog. It mentioned the undocumented ColdFusion.Bind.assignValue method could be used to refresh the list. It was perfect. Exactly what I needed.
Well... then I got to wondering if there might be something even simpler. (I know, I know. People are never satisfied). After further review of cfajax.js, and lots of experimentation, I came across a nice one-liner that seems to work. Still undocumented unfortunately. But still pretty neat:
<script language="javascript">
ColdFusion.bindHandlerCache['yourElementID'].call();
</script>
... and what does this function do?
If you generate a cfselect with a CFC bind, and view the source, you will see a call to a function named register(). Not surprisingly, the register() function seems to do all the work of creating the bindings and invoking the CFC to populate the select list.
After taking a peak inside cfajax.js, I noticed the register() function creates a parameter-less function which handles invoking the CFC. (You can open up cfajax.js yourself if you want to view all the gory details.) But the key part is that CF stores this handler function in one of its cache objects. So you can easily grab a reference to it function just by passing in the id (or name) of your form element. Then simply invoke it using call().
Pretty cool stuff! It goes a long way towards alleviating my headache..
8 comments:
Works perfectly ! Thanks a lot
I'm sorry to say that I'm not clear on how to get the refresh to work. Here's my cfselect:
select genus from lookup_genus;
.
.
.
Help would be appreciated :)
Thanks!!!
@Anonymous,
Code does not show up in comments unless you html escape it. It is a blogger thing..
wow! very nice. I've been struggling with this for the past 2 days. Thanks!
ColdFusion.Bind.assignValue and ColdFusion.bindHandlerCache seem to approach the problem from opposite sides. ColdFusion.Bind.assignValue sets the value of a form control and then triggers all bindings to that form control, while with ColdFusion.bindHandlerCache you must set the value of the form control yourself (using separate js code), and then call ColdFusion.bindHandlerCache on each form control that is bound to that first control.
Thus, if you're just interested in refreshing a control that is bound to something else, using ColdFusion.bindHandlerCache makes the most sense. If you need to change the value of a form control using js and then refresh any controls that bind to it, then using ColdFusion.Bind.assignValue makes the most sense.
@Russ,
In what version of CF?
-Leigh
I've used both methods in CF8[.01], but since this article was in reference to CF9, I'm guessing it would work there too.
Interesting. My memory is a little fuzzy, but I thought invoking call() using ColdFusion.bindHandlerCache also refreshed bound items in CF9. I could be wrong though.
-Leigh
Post a Comment