Even more twisty HTML

By | February 28, 2007

Whew! Yesterday I received a number of comments and complaints about my small twisty (disclosure triangle) library. To review:

  • It didn’t work in Internet Explorer. (Not too surprising since I don’t have access to a Windows machine for testing.)
  • It was a little ugly. (Okay, no one said that, but I think it was implied.)
  • The hidden sections would display for a moment before being hidden.
  • It wasn’t keyboard accessible.
  • I had a typo in the script.
  • The hiding animation wasn’t the same speed as the twisty animation.

So I’ve tried again with some good ideas from the SWAT tooklit. You can try the script.aculo.us animated version or the plain non-animated version. You can also simply download the whole thing as a tar file to play with.

To use this on your own, you need to include the twisty.js file in your code:

<script type="text/javascript" src="twisty.js"></script>

You should also include the two external style sheets:

<link rel="stylesheet" href="twisty.css" type="text/css" media="screen"></link>
<link rel="stylesheet" href="twisty-print.css" type="text/css" media="print"></link>

You no longer need any changes to your <body> tag.

To define a twisty, use this template:

<div class="collapsible"><a href="javascript:toggleTwisty('uniqueid');">The Section Title<img class="twisty" src="twisty-down.gif"></a>
<div id="uniqueid">
<div>
Section Content
</div>
</div>
</div>

If you want the section to default to hidden, simpy add this code to the end of the above code snippet. (after the last </div>)

<script type="text/javascript">
hideTwisty('uniqueid');
</script>

Hopefully, this version works better.

9 thoughts on “Even more twisty HTML

  1. xkahn Post author

    cs:
    Yeah. That’s actually how I tested. Do you know how to debug Javascript in IE? Especially in ies4linux? All I got was a message that there was an error on the page. It took others pointing out the line that caused the problem to find the issues.

  2. shen

    Thats awesome, they are both working in ie6 now. I didn’t realise the animation was to have the whole text area sliding in and out of the header line. Cool.

    I’m going to use this in a project I’m working on now.

    Shen

  3. Peter Lund

    Much better! 🙂

    Nits:

    1) sliding speed. All sections slide in/out using the same amount of time. Since some are short (“Huh”) and others long (the table and picture), the sliding speed varies between the sections — which is to a certain extent fine. It’s just that a short section like “Huh” ends up sliding /very/ slowly, so you probably need to adjust the time if the slide distance is below a cut-off.

    2) the sliding movements are not monotonic here. That might be something you did on purpose, because it looks sort of okay on the big table/picture section. On the other hand it looks awful on the short “Huh” section because the size of backwards step seems to be the same measured in pixels. Did you use the wrong DOM object or the wrong margin/border attribute? (Note, there are *many* browser bugs in that area!)

  4. xkahn Post author

    Hey Peter,

    Nit #1: I agree about the sliding speed. I’m not sure what the solution is, frankly. I want the twisty animation to be the same speed as the slide animation. That means the slide always has to be the same speed. I suppose a refinement would be to get rid of both animations for small sections. However, I’m not sure it’s worth it. Why would you need to hide a small section?

    Nit #2: This turned out to be a bug in the script.aculo.us animation package that I didn’t bother to research because I liked the effect. I’ve updated both demos and the tar file to fix the problem. (If the content outer div has padding, the animation doesn’t take that into account.)

    Thanks!

  5. Peter Lund

    Yep, much better. But I agree, the effect is actually ok (looks good, even!) as long as the backward motion is small relative to the section height.

    Regarding nit #1, sometimes one would want to hide small subsections not because they take up space as such but because they constitute visual noise.

    I think the way to make the effect look really nice and polished is to use two or three different animations. Either the server can generate the HTML with the right one in each case or one can use an onload handler to loop over the sections and replace the standard animation with faster ones for the small sections.

    That is, if one /really/ cares about polish 😉

    (Don’t you love fountain pens that make just the right click sound when you put the cap back on?)

  6. pedz

    The code assumes the gifs are in the same directory as the code. I added this function:

    function setNewBaseSrc(ele, newBaseSrc) {
    var dirPath = ele.src.replace(/[^\/]*$/, ”);
    ele.setAttribute(‘src’, dirPath + newBaseSrc);
    }

    Then I replaced places that call setAttribute to set the src to call this routine instead. e.g.

    replace:
    twisty.setAttribute(‘src’, ‘twisty-hidden.gif’);
    with:
    setNewBaseSrc(twisty, ‘twisty-hidden.gif’);

    One nit: The variable “twisties” does not have a “var” in front of it in the toggle function.

  7. weblog990

    How to modify this code so that if user click on another hide / show option the first option automatically hides.

    please let me know.

  8. admin

    Hi weblog990,

    You’re looking for an accordion widget instead of a disclosure widget.

    That said, it might not be too hard to convert this widget to do something similar. You would run the function getElementsByClassName(“collapsible”) and iterate over the results. You would need to find the div id to pass to hideTwisty, but that should be pretty easy….

    All that said, at this point, I’d look for jQuery accordion widgets. jQuery makes this very easy now.

Leave a Reply

Your email address will not be published. Required fields are marked *