Wednesday, February 10, 2010

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:

Anonymous,  April 21, 2010 at 1:20 AM  

Works perfectly ! Thanks a lot

Anonymous,  May 5, 2010 at 7:49 AM  

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!!!

cfSearching May 5, 2010 at 8:33 AM  

@Anonymous,

Code does not show up in comments unless you html escape it. It is a blogger thing..

Anonymous,  August 18, 2010 at 3:16 PM  

wow! very nice. I've been struggling with this for the past 2 days. Thanks!

Russ,  November 9, 2010 at 6:44 AM  

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.

cfSearching November 9, 2010 at 7:29 PM  

@Russ,

In what version of CF?

-Leigh

Russ,  November 11, 2010 at 6:26 AM  

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.

cfSearching November 11, 2010 at 6:35 AM  

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

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep