Mix06 demo part 1: the accordion control

I thought I'd write a few posts about the controls I've created for Brad's Mix06 demo, which you can download from his blog:

Full source code of the demo: http://blogs.msdn.com/brada/archive/2006/03/23/559077.aspx
Accordion control source code: http://blogs.msdn.com/brada/archive/2006/03/29/563648.aspx

One of the most reusable pieces of the demo is the accordion control. Plus, I'm French so it looked like a natural way to start this series of posts.

Atlas accordion control
(This is a snapshot of the control, an image, not a live sample)

The control is a client-side Atlas control. It does pretty much what you expect, which is to show only one of its panes at a time. It has a nice transition effect when switching to a new pane. Here's how you use it...

As usual with Atlas client-side controls, the control itself does not do any rendering. This part is left to the page developer and is completely free-form, which gives you total control over the rendering and helps separate layout and semantics from behavior. So the first thing to do is to create a container element (a div will do) and put the different headers and content panes inside of that. For accessibility reasons, I recommend you use A tags in the headers. Divs are fine for the panes themselves.

<div id="accordion1">
  <a href="javascript:;">Pane 1</a>
  <div id="Pane 1">
    This is Pane 1 in the accordion control.
 
</div>

  <a href="javascript:;">Pane 2</a>
  <div id="Pane 2">
    This is Pane 2 in the accordion control.
 
</div>

  <a href="javascript:;">Pane 3</a>
  <div id="Pane 3">
    This is Pane 3 in the accordion control.
 
</div>
</div>

<div id="accordion1">
  <a href="javascript:;">Pane 1</a>
  <div id="Pane 1">
    This is Pane 1 in the accordion control.
 
</div>

  <a href="javascript:;">Pane 2</a>
  <div id="Pane 2">
    This is Pane 2 in the accordion control.
 
</div>

  <a href="javascript:;">Pane 3</a>
  <div id="Pane 3">
    This is Pane 3 in the accordion control.
 
</div>
</div>

The accordion control will look at the contents of its associated element and will consider every other sub-element as a header or a content pane. So let's associate an accordion control to the div above:

<dice:accordion id="accordion1"/>

"accordion1"/>

And... that's it, we're done.

One nice thing to note is that if javascript is off on the user's browser, the contents of the accordion will just show with all panes fully deployed.

In a future post, I'll explain how such a control is built and in particular how I included the animation effect.
http://weblogs.asp.net/bleroy/archive/2006/04/04/441921.aspx

UPDATE: Here's the scaffolding you need in your page for the accordion control (or any Atlas control) to work... You need a script manager on the page, which will manage the necessary script inclusions. Here, the accordion needs the Glitz library for the animations so we're adding that:

<atlas:ScriptManager ID="ScriptManager1" runat="server">
  <Scripts>
    <atlas:ScriptReference ScriptName="AtlasUIGlitz" />
    <atlas:ScriptReference ScriptName="Custom" Path="~/ScriptLibrary/Dice.js" />
  </Scripts>
</atlas:ScriptManager>

Replace Dice.js with accordion.js if you're using the accordion-only version of the script file (the dice.js has the other controls used in Brad's demo).
If you're not using ASP.NET, you'll have to manually add <script> tags to your page that point to Atlas.js and the glitz script file.

And of course the Atlas markup itself must be in a <script type="text/xml-script"> section:

<script type="text/xml-script">
  <page xmlns:script="http://schemas.microsoft.com/xml-script/2005" xmlns:dice="http://schemas.microsoft.com/xml-script/2005/dice">
    <components>
      <dice:accordion id="accordion1"/>
    </components>
  </page>
</script>

Note the namespace declaration here so that we can use the dice:accordion tag. I should have included that from the start, but I wanted to show only what's relevant to the sample. My mistake, it's corrected now.

UPDATE 2: The Atlas Control Toolkit now has a far more advanced Accordion control, which should be preferred over this one for real-world use.

21 Comments

  • Just wondering, the control in your post is showing some odd stuff:



    A|Body Color

    B|Dot Color

    ...



    Is the accordian control supposed to be showing there?

  • Bryant: no, as I said in the post, the accordion control doesn't render anything, it's pure behavior. These are just the headers that are in the HTML in the demo application.

  • Ok, then I'm just confused. You comment that the control &quot;does pretty much what you expect, which is to show only one of its panes at a time.&quot; However, I don't see any panes changing or animations being done so the control doesn't really make sense to me. How does what is shown in the post relate to the accordian control? Is it just showing all the panes at once because of a javascript issue?

  • Runi, I've updated the post to include the scaffolding you need.

  • Steve: that's because Brad forgot to copy the namespace definition into accordion.js. Add this line at the top of the script file:

    Type.registerNamespace('Dice');

    I've sent mail to Brad so that he can fix the file.

  • Steve: the Javascript namespace is Dice with a capital D, but the xml namespace should be kept dice with lower-case d. Otherwise, I think it will fail on some browsers.

    So no, you don't have to and shouldn't correct the xml-script here.

  • Steve: I should probably add for the sake of clarity that the namespace that is used in the Javascript is Dice as defined by the registerNamespace, whereas the xml namespace that is used in the xml-script comes from the

    Sys.TypeDescriptor.addType('dice', 'accordion', Dice.Accordion);

    line at the bottom of the file, and this one uses lowercase d.

  • thanks for the clarification - that helps

  • Is it possible to do the accordion in an update panel? I'm trying it, but the accordion effect is lost.. Is there any way to get the effect back and not have a lot of screen refresh/flicker? I keep trying to find a way to use the UpdateProgess to fire off some javascript, but I can't get anything to work.



    I was using Rico.Accordion (another opensource accordion solution) but the same thing happened with it. I can reset the accordion with rico manually (which still doesn't acheieve the effect I'm looking for), but I still can't find any way to reset the accordion effect after the update panel completes the update.

  • Brian: UpdatePanel really is for server controls. What is your scenario exactly?

  • Rajiv: no need to shout ;) I don't see any flickering. What browser is that on? Maybe the animation could be made more fluid by using a composite animation (the control uses two simultaneous animations: one to reduce the old pane, the other to make the new one appear). This is only a sample so I went for the simplest solution but there are certainly more than a few ways to improve on that.

  • Brian, as I said, UpdatePanel is for server controls. We're considering enabling some limited support for xml-script inside UpdatePanel but that would be in a future release.

    There are at least two things you can do.

    First, you can put UpdatePanels inside the divs of the accordion.

    Second, and that's what I would recommend, you can build a server control that implements IScriptComponent and spits out the accordion's xml-script.

  • Brian:

    I think I had the same problem you did with openrico accordion.

    My accordion behaviour was still working, but the accordion lost all its styling (background colors, etc.).

    Turns out that I was linking to my stylesheet using outside of my head. I added my stylesheet the right way (server-side) and not it works fine.

    public void addCss(string url)
    {
    if (Page.Header != null)
    {
    HtmlLink cssLink = new HtmlLink();
    cssLink.Href = url;
    cssLink.Attributes.Add("rel", "stylesheet");
    cssLink.Attributes.Add("type", "text/css");
    Page.Header.Controls.Add(cssLink);
    }
    }
    }

    My accordion is not inside an update panel though...

  • Any suggestion on how to alter the viewIndex that is used on page load?

    I have used these panels in a window that pops up, but certain times I would like the first panel to be displayed, and other times I would like the second panel to be expanded initially.

  • Billy: yes, you can set the viewIndex from the xml-script tag. This way, it will change without playing the animation. If you're not using xml-script, just set the index before you call initialize.
    Maybe what you want to do is make sure only the pane that you want is shown, even before the scripts are initialized and the control gets a chance to hide the other panes? If that's the case, you'll have to do that in the HTML and CSS, by setting the overflow to hidden and the height to 1px on the other panes.

  • I've got the lattest 60914 Prod dll but when I add it to my toolbox I have the accordion component but do not seem to have the AccordionPane component and so am ubale to use this.

    Is anyone else having the same problem?
    How do I go about fixing it?

  • John: I have no idea what dll you're talking about. If you're using the Toolkit's Accordion, you should ask this question on the toolkit forums:
    http://forums.asp.net/1022/ShowForum.aspx

  • Sorry yes I'm using the toolkit on, my bad thought this was the same one.

  • No, this one was written way before. I'll update the post to make that clearer and to point people to the toolkit one (which should be used instead of this sample).

  • Is it possible to open a web page with accordion to open with a particular pane? For example if i have pane1 pane2 and pane3 and when I call a page, it will start with pane2 open. Thanks.

  • Nick: of course. Just set the current pane before initialization (which is easy if you're using xml-script, just write the attribute). When the page loads, all panes will be visible until initialization (this is desirable because if people visit your page with JavaScript disabled, they will see all panes and should still be able to use your application) but as soon as initialization happens, the panes other than the current one will collapse without animating.

Comments have been disabled for this content.