5149 Views // 0 Comments // Not Rated

How To Get A Client Reference To An ASP.NET 2.0 AJAX Accordion Control In JavaScript

Every once in a while, you stumble onto something in programming that saves several days of thinking or several weeks of brute force. I just stumbled onto such a gem. If you Google how to use JavaScript to manipulate an ASP.NET AJAX Control Toolkit Accordion, you're going to get more results on coffee and musical instruments than you will for actual help with this control...that seems to always cut it close in terms of the headache vs. AJAX magic ratio.

Anyways, I am one bug away from completing a rewrite of a crazy ASP.NET 2.0 page that took over half a year to create using traditional ASP.NET and AJAX. Now, it will be entirely in Script Controls, JSON web services, and just enough code-behind the page to initialize everything. It's beautiful thing. This one bug, however, required client access to an Accordion object so I could switch panes and update content.

So I merrily did a $find(), passing the client ID of the client, and contemplated where to take my girlfriend for dinner that night while my app compiled. My browser has "Disable script debugging" disabled, so the breakpoint I set on the line of script with the $find() was hit. But there was a little problem: instead of a nice reference to my accordion and the ability to leave early on a Friday, I instead had a big fat null.

And when $find() fails you, it's time to hack or it's time to cry.

So I dried my tears, and decided to dig. I did a $get() with the id, and I had a reference to my Accordion as a DOM element, not an actual JavaScript class. And I could see the innerHTML of all of the divs that the panes render, but nothing in terms of a true reference to the control. Then for some reason, the standard Attributes collection on the DOM object in my Immediate window caught my eye. Seriously, no reason at all. But I dug.

This array had 83 dimensions. And again, for no reason at all, I was curious as to what was lingering at the last index. So I dug. Turns out, there was a DOM object here, which had a property named "nodeValue." I seem to remember this always being null in my experience with web development (in terms of iterating DOM elements, traversing TreeNodes, etc).

But this nodeValue thing was not null this time; it had a beautiful little ellipsis sitting there in my Immediate window, looking at me...almost winking. So I dug one level deeper, and there it was! A client-side, programmatic reference to the accordion control! From here I can kick off the animation to change panes, and set the header or content divs of each. Here's how to do it:

First, in your page or control, we need a global variable to store the ID of your accordion. Do something like this:

Code Listing 1

  1. <script type="text/javascript" language="javascript">
  2. var accID = '<% =this.accAccordion.ClientID %>';
  3. </script>

Then, in a js file, create a wrapper function to return a reference to your control, like this:

Code Listing 2

  1. function GetAccordionReference(id)
  2. {
  3. //get a reference to the accordion
  4. var acc = $get(id);
  5. return acc.attributes[acc.attributes.length - 1].nodeValue;
  6. }

Here are some usages: (Check out the documentation or source of the Accordion for more.)

Code Listing 3

  1. //open first pane
  2. GetAccordionReference(accID)._changeSelectedIndex(0, true, false);
  3. //set the first pane's content's div html
  4. GetAccordionReference(accID)._panes.content.childNodes[0].innerHTML = '<b>cool</b>';

This is still a bit of a hack, but I haven't found any other way to do it. Have fun!

3 Tags

No Files

No Thoughts

Your Thoughts?

You need to login with Twitter to share a Thought on this post.