Simple Hide and Show with Prototype

by Terri Ann on December 18, 2007

This entry is part 1 of 10 in the series Prototype Tutorial

Back to the basics. We’re going to create a div, and hide and show it using the toggle functionality and hide and show functions with Prototype.

As with most of my teaching/tutorial style I will walk you through the progression from doing things the quick and dirty way to the more sophisticated feature fancy way. Please view the source, steal the code and go play. Any non-inline JavaScript will be included near the example that it works with, just so y’all can jack my code easier. K?

In our first example we have a feature box that is already visible and two separate actions, a hide and a show (Example 1). This entire example uses only inline JavaScript and the included prototype.js file.


Example 1 – Hide and Show with Separate Buttons

Hide Feature Box | Show Feature Box

Feature Box – Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce augue. Integer aliquam porta nisi. Curabitur lacinia venenatis diam. Suspendisse fringilla. Etiam eget turpis ullamcorper sem convallis eleifend. Donec pharetra, velit ac feugiat dictum, felis orci tempus lorem, nec ultricies purus velit at velit. Sed eget justo. Nullam auctor tincidunt lacus. Nullam vitae nisi. Morbi metus. In hac habitasse platea dictumst. Nunc vel massa. Duis et quam. Donec bibendum, mi sed fermentum venenatis, est massa tincidunt nibh, eget convallis sem risus ac tellus. Sed nibh sem, volutpat ut, bibendum ac, imperdiet nec, lectus.

Example 1 – Code

HTML & JavaScript

<p><a href="#" onclick="$('featurebox-1').hide();">Hide Feature Box</a> | 
<a href="#" onclick="$('featurebox-1').show();">Show Feature Box</a></p>
<div class="featurebox" id="featurebox-1"><strong>FeatureBox</strong> - Lorem ipsum dolor sit amet[...]</div>

Now let’s use Prototype’s built in toggle function, which toggles the visibility of an element. No fancy JavaScript function to check for visibility and then make a decision, this is all built into the library (Example 2). This entire example uses only inline JavaScript and the included prototype.js file


Example 2 – Hide and Show with a Single Toggle

Toggle Feature Box

Feature Box – Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce augue. Integer aliquam porta nisi. Curabitur lacinia venenatis diam. Suspendisse fringilla. Etiam eget turpis ullamcorper sem convallis eleifend. Donec pharetra, velit ac feugiat dictum, felis orci tempus lorem, nec ultricies purus velit at velit. Sed eget justo. Nullam auctor tincidunt lacus. Nullam vitae nisi. Morbi metus. In hac habitasse platea dictumst. Nunc vel massa. Duis et quam. Donec bibendum, mi sed fermentum venenatis, est massa tincidunt nibh, eget convallis sem risus ac tellus. Sed nibh sem, volutpat ut, bibendum ac, imperdiet nec, lectus.

Example 2 – Code

HTML & JavaScript

<p><a href="#" onclick="$('featurebox-2').toggle();">Toggle Feature Box</a></p>
<div class="featurebox" id="featurebox-2"><h3>
    <h3>A h3 level heading inside a "featurebox" div</h3>
    <p>A normal paragraph of text[…]</p>
</div>

Now I don’t know about you but I’m tired of getting bounced to the top of the screen or reloading the page every time I click on one of those actions (hide, show or toggle) SO I am going to create a JavaScript function to listen for an even to click on a span instead of an action to happen onclick for an anchor tag. (Example 3). The listener example uses the below JavaScript function and the included prototype.js file and that span has the id ‘featurebox-3-listen’ applied to it.

JavaScript

<script type="text/javascript">
    Event.observe(window, 'load', function() {
        Event.observe('featurebox-3-listen', 'click', function(){
            $('featurebox-3').toggle();
        });
    });
</script>

Additional information about Event.observe is further detailed in the Event Observe and Event Listeners with Prototype Tutorial.

The inline example just has the onclick attribute of the span element set to toggle, just as the onclick attribute worked on the anchor tags in the above examples.


Example 3 – Adding a Listener, Removing the Anchor

Toggle Feature Box (Listener) | Toggle Feature Box (Inline)

Feature Box – Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce augue. Integer aliquam porta nisi. Curabitur lacinia venenatis diam. Suspendisse fringilla. Etiam eget turpis ullamcorper sem convallis eleifend. Donec pharetra, velit ac feugiat dictum, felis orci tempus lorem, nec ultricies purus velit at velit. Sed eget justo. Nullam auctor tincidunt lacus. Nullam vitae nisi. Morbi metus. In hac habitasse platea dictumst. Nunc vel massa. Duis et quam. Donec bibendum, mi sed fermentum venenatis, est massa tincidunt nibh, eget convallis sem risus ac tellus. Sed nibh sem, volutpat ut, bibendum ac, imperdiet nec, lectus.

Example 3 – Code

JavaScript

<script type="text/javascript">
Event.observe(window, 'load', function() {
    Event.observe('featurebox-3-listen', 'click', function(){
        $('featurebox-3').toggle();
    });
});
</script>

HTML & JavaScript

<p><span id="featurebox-3-listen">Toggle Feature Box (Listener)</span> | 
<span onclick="$('featurebox-3').toggle();">Toggle Feature Box (Inline)</span></p>
<div class="featurebox" id="featurebox-3"><div class="featurebox" id="featurebox-2">
    <h3>A h3 level heading inside a "featurebox" div</h3>
    <p>A normal paragraph of text[…]</p>
</div>

Now that we have the span listener, and toggle ability down pat, let’s change the language of the span to represent the action it will take if you click it.
Here we will introduce a new function built into the library: visible()
Visible measures the visibility of an element and returns the value of true of false.

We’ll use the returned value of visible() to determine what the span should now read and the update() function to change the inner html of the feature-4-listen text.

JavaScript

<script type="text/javascript">
    Event.observe('featurebox-4-listen', 'click', function(){
        $('featurebox-4').toggle();
        if($('featurebox-4').visible()){
            […]
        }
    }); 
</script>

Update VS. replace

When trying to figure out how to replace the content (inner HMTL) in the span there were two functions I ran some tests on: update() and replace(). Update will just effect the characters contained in the element you are calling it on, where as replace will replace the whole element.

When I replaced the whole element and kept it as a span with the id of featurebox-4-listen suddenly the listener would no longer work. That is why update() is clearly the correct choice in which function to use. Plus it is far lower maintenance in the coding of the listener function above!


Now you can see that the span that toggles the visibility of the feature box will change to reflect the state of the box.


Example 4 – Toggle with Text Change

Toggle Feature Box (Listener)

Feature Box – Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce augue. Integer aliquam porta nisi. Curabitur lacinia venenatis diam. Suspendisse fringilla. Etiam eget turpis ullamcorper sem convallis eleifend. Donec pharetra, velit ac feugiat dictum, felis orci tempus lorem, nec ultricies purus velit at velit. Sed eget justo. Nullam auctor tincidunt lacus. Nullam vitae nisi. Morbi metus. In hac habitasse platea dictumst. Nunc vel massa. Duis et quam. Donec bibendum, mi sed fermentum venenatis, est massa tincidunt nibh, eget convallis sem risus ac tellus. Sed nibh sem, volutpat ut, bibendum ac, imperdiet nec, lectus.

Example 4 – Code

JavaScript

<script type="text/javascript">
Event.observe(window, 'load', function() {
    Event.observe('featurebox-4-listen', 'click', function(){
        $('featurebox-4').toggle();
        if($('featurebox-4').visible()){
            $('featurebox-4-listen').update('Toggle Feature Box (Close)');
        } else {
            $('featurebox-4-listen').update('Toggle Feature Box (Open)');
        }
    });
});
</script>

HTML

<p><span id="featurebox-4-listen">Toggle Feature Box (Listener)</span></p>
<div class="featurebox" id="featurebox-4"><div class="featurebox" id="featurebox-2">
    <h3>A h3 level heading inside a "featurebox" div</h3>
    <p>A normal paragraph of text[…]</p>
</div>

So you think we’ve learned enough yet? Not by a long shot!
There’s two more items to cover before we’ve taken control of Prototype’s ability to hide and show elements. Let’s use an image to act as our toggling link, and let’s start the feature box as hidden!

First to ensure the feature box in question is hidden to start let’s add that to out listener. Since out listener first looks to make sure the window has loaded (in entirety) and then looks to see if the feature-box-5-listen has been clicked on we will add a command to hide featurebox-5 inside the window load listener, but before the click listener.

JavaScript

<script type="text/javascript">
    Event.observe(window, 'load', function() {
        $('featurebox-5').hide();
        Event.observe('featurebox-5-listen', 'click', function(){
            […]
        });
    });
</script>

Now to replace the span with an image. Instead of hard coding the image into the page let’s leave my span coded exactly as the above examples. A span with an id of featurebox-5. The same way we defaulted the feature box to hidden we will update the span to contain an image instead of text.

Why update the span with an image instead of just starting with an image? Earlier I had mentioned that the event listener would not work when you replace the element you are listening for, even if you continue to include that id in the replacement. For this reason it is faster/easier/more reliable to put the image inside the span to ensure that when the image is changed, either initially or on toggle, the listener will still effect the functionality.

Example 5 – Toggle with Image Change

toggler (remember we started with it closed first this time)

Feature Box – Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce augue. Integer aliquam porta nisi. Curabitur lacinia venenatis diam. Suspendisse fringilla. Etiam eget turpis ullamcorper sem convallis eleifend. Donec pharetra, velit ac feugiat dictum, felis orci tempus lorem, nec ultricies purus velit at velit. Sed eget justo. Nullam auctor tincidunt lacus. Nullam vitae nisi. Morbi metus. In hac habitasse platea dictumst. Nunc vel massa. Duis et quam. Donec bibendum, mi sed fermentum venenatis, est massa tincidunt nibh, eget convallis sem risus ac tellus. Sed nibh sem, volutpat ut, bibendum ac, imperdiet nec, lectus.

Example 5 – Code

JavaScript

<script type="text/javascript">
    Event.observe(window, 'load', function() {
        $('featurebox-5').hide();
        $('featurebox-5-listen').update('<img src="/uploads/2007/12/add.png" alt="Open the feature box" />');
        Event.observe('featurebox-5-listen', 'click', function(){
            $('featurebox-5').toggle();
            if($('featurebox-5').visible()){
                $('featurebox-5-listen').update('<img src="/uploads/2007/12/delete.png" alt="Close the feature box" />');
            } else {
                $('featurebox-5-listen').update('<img src="/uploads/2007/12/add.png" alt="Open the feature box" />');
            }
        });
    });
</script>

HTML

<p><span id="featurebox-5-listen">Toggle Feature Box (Listener)</span></p>
<div class="featurebox" id="featurebox-5">
    <h3>A h3 level heading inside a "featurebox" div</h3>
    <p>A normal paragraph of text[…]</p>
</div>

Example 5b – An Alternative Script for Toggle Image Changes (for Prototype 1.6+)

This is actually the one I have to use in example #5 above, to avoid problems with my blog’s plugin syntax editor.
This sample has very different HTML and uses JavaScript to replace the SRC of the image as well as the ALT tag instead of replacing the whole span. The HTML names the image toggle itself as the listener instead of a surrounding div.

Example 5b – Code

JavaScript

<script type="text/javascript">
    Event.observe(window, 'load', function() {
        $('featurebox-5').hide();
        $('featurebox-5-listen').writeAttribute('src', '/uploads/2007/12/add.png');
        Event.observe('featurebox-5-listen', 'click', function(){
            $('featurebox-5').toggle();
            if($('featurebox-5').visible()){
                $('featurebox-5-listen').writeAttribute('src', '/uploads/2007/12/delete.png');
            } else {
                $('featurebox-5-listen').writeAttribute('src', '/uploads/2007/12/add.png');
            }
        });
    });
</script>

HTML

<p><img id="featurebox-5-listen"  alt="toggler"/></p>
<div class="featurebox" id="featurebox-5">
    <h3>A h3 level heading inside a "featurebox" div</h3>
    <p>A normal paragraph of text[…]</p>
</div>

I start out the toggle button with a fake image innitially (xxx.jpg) for testing to ensure the add.png image is being updated in line 3 of the JavaScript. Then I’ll change it once I push the page live.


Summary

To really wrap that up, we see how Prototype can easily toggle showing and hiding a div, and changing the language in the span that does the toggling. Also we’ve seen how we can have the div start as hidden only if the prototype script is working properly. Don’t forget that we know how to change the image if you should choose to use two different images to instead of a span to toggle the div hidden/visible.

Prototype Functions Used

Prototype Functions Mentioned

{ 10 comments… read them below or add one }

1 Chris May 28, 2008 at 12:41 pm

Thanks for the concise explanation. Works perfectly!!

2 mySelf August 25, 2008 at 6:06 am

Hi,

in your toggle image code is a little misstyping:

$(‘featurebox-5-listen’).writeAttribute(src, ‘/uploads/2007/12/delete.png’);

has to be:

$(‘featurebox-5-listen’).writeAttribute(’src’, ‘/uploads/2007/12/delete.png’);

it works for me on 1.6.0.1

3 Tamonash August 27, 2008 at 6:26 am

Thanks. It helped

4 Paul October 22, 2008 at 9:24 am

I’m trying to implement this, but I want to toggle the display of all span elements with class name “whatever” on the page. I thought I could use the double $$, but that’s not working. Any thoughts? Thank you in advance…

5 mj October 29, 2008 at 6:04 pm

is there a way to have the ‘open/close’ image have a ‘hover’ effect?

6 Moreh November 5, 2008 at 6:58 am

good explaining Thank you!

7 martin December 31, 2008 at 10:55 am

How about if you want to have multiple items on the same page? Like a list of FAQ’s?

8 Chris Ward January 5, 2009 at 3:05 pm

Teri, I came across your post looking for prototype stuff. I just wanted to let you know that the ‘Prototype Tutorial’ series links of prototype articles doesn’t seems to exist at the current time. There looks like there should be a table of contents type page, or category for these pages, but it seems to be missing.

Also, what WP plugin are you using to get the javascript syntax highlighted?

9 Brian January 6, 2009 at 2:14 pm

our setup has Prototype 1.5.1, I used the Example 5 above, It worked. However what if you want multiple hide and show’s?

Would you just have to have the WHOLE script multiple times? changing the featurebox-1,-2,-3 so you have unique id’s? Isn’t there a way to streamline it and not have the code so many times? How would this be done?

10 Rain01 June 2, 2009 at 12:46 pm

Nice tutorial… works like a charm. But is there a way if I need to put like 10 or 20 box’s that people can show and hide? Have to make listener for each box?

Leave a Comment

Previous post:

Next post: