Writing multiple toggle links in JQuery

Jquery

I was just working with this so thought I would write and quick a quick blog post about it. It was covered a bit on http://www.learningjquery.com/2006/09/slicker-show-and-hide but hidden in the comments so I though I would bring it out for all to see. Thanks to Scott for the original explanation.

 Most of you will know the basic JQuery function for toggling an item open or closed…

$(document).ready(function() {
$('[class^=toggle-item]').hide();
$('a.link').click(function() {
$('.toggle-item-').toggle();
});
});

Pretty straight forward stuff, once the page has loaded hide all elements on the page that have the class “toggle-item”, grab the link with class=”button” and use this to toggle the element with class=”toggle-item” open and closed, done deal. But what about if we want to do this for multiple items on the page and not call each item on its own and create a bunch of unnecessary code, we need a way to dynamically pick each element we want to show and hide.

One option is to use the JQuery ‘^’ selector, basically enabling us to pick any elements that begin with the class we choose e.g.

$('[class^=link]')

Would pick any elements on the page that begin with class=”link…”. Using this we can add out unique identifier to the element to signify it as being individual. So lets look at this a little deeper, say you have three elements on the page you want to show/hide, you’ll have three links to perform each action.

< a href="#" class="link1" >Link 1< / a >
< a href="#" class="link2" >Link 2< /a >
< a href="#" class="link3" >Link 3< /a >
<div class="toggle-item-link1">Content</div>
<div class="toggle-item-link2">Content</div>
<div class="toggle-item-link3">Content</div>

First thing we are going to do is hide all the elements on the page, using the JQuery selector above we close all the elements that begin with the class “toggle-item”

$(document).ready(function() {
$('[class^=toggle-item]').hide();
});

Next we tell the DOM which links perform the toggle action. Again using the JQuery selector we grab all the links on the page that begin with the class “link”. We then create a variable that wraps the link itself in an object and get the class of the particular link that was clicked.

$(document).ready(function() {
$('[class^=toggle-item]').hide();
$('[class^=link]').click(function() {
var $this = $(this);
var x = $this.attr("className");
});

Now we have this all we need to do is append of unique class identifier using the variable to the toggle item so its relates to the link that was clicked e.g.

$(document).ready(function() {
$('[class^=toggle-item]').hide();
$('[class^=link]').click(function() {
var $this = $(this);
var x = $this.attr("className");
$('.toggle-item-' + x).toggle();
return false;
});
});

And there you have it, you can now traverse the DOM and pick out all the toggles you need in one simple bit of Jquery.

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Facebook
  • LinkedIn
  • Bookmark this

11 Comments

  1. Posted Nov 14, 2008 at 9:27 am | Permalink

    Hi!

    Very interesting post about JQuery!

  2. Robby
    Posted Feb 1, 2009 at 3:51 am | Permalink

    Hi,
    I have implemented your code and it works fine but I cant get it to work with a checkbox :->

    Problem being that the jquery code negates the normal Tick in the checkbox . . seems to be using the checkbox as (a href) Any Clues Robby

  3. Stéphane
    Posted Mar 9, 2009 at 2:24 am | Permalink

    Thanks a lot for that, it spared me hours of research.

    It’s a shame that jQuery lacks so much in documentation. You should write a book. :-)

  4. Posted Mar 11, 2009 at 3:35 am | Permalink

    Nice. Thanks for a clean concise post on this! Like Stephane said…you spared me hours of research (and aggravation).

  5. KeepingYouAwake
    Posted Apr 3, 2009 at 7:53 pm | Permalink

    This is perfect! I wanted to change the text so that instead of saying “read more…” once expanded, it could say the more appropriate “close” or something, so I added a basic conditional:

    $(document).ready(function() {
    $(’[class^=toggle-item]‘).hide();
    $(’[class^=link]‘).click(function() {
    var $this = $(this);
    if($this.attr(”alt”)==”"){
    $this.html(’Close’);
    $this.attr({alt: “toggled”});
    }
    else if ($this.attr(”alt”)==”toggled”){
    $this.html(’Read more…’);
    $this.attr({alt: “”});
    };
    var x = $this.attr(”className”);
    $(’.toggle-item-’ + x).toggle();
    return false;
    });
    });

  6. Posted Apr 15, 2009 at 1:49 pm | Permalink

    Great stuff, it’s nice to see people expanding on this and making it readily available

  7. Posted Apr 16, 2009 at 2:29 pm | Permalink

    Very Cool, and definitely useful. Cheers.

  8. Posted May 15, 2009 at 11:55 pm | Permalink

    May I make things a bit more complicated? Suppose, I have the following:

    $(’[class^=toggle-item-link4]‘).hide();

    $(’[class^=toggle-item-link5]‘).hide();

    $(’[class^=toggle-item-link6]‘).hide();

    $(’[class^=toggle-item-link7]‘).hide();

    $(’[class^=toggle-item-link8]‘).hide();

    $(’[class^=toggle-item-link9]‘).hide();

    $(’[class^=toggle-item-link10]‘).hide();

    $(’[class^=link]‘).click(function() {
    var $this = $(this);
    var x = $this.attr(”className”);
    alert(x);
    $(’.toggle-item-’ + x).toggle();
    return false;
    });

    I want
    Link 4
    to be visible if only link3 is clicked. It will work like an accordion basically. Any help?

  9. Posted May 27, 2009 at 5:34 pm | Permalink

    I ended up writing some server side code to have a conditional loop. It works but I am not 100% there. So, I need to set

    $(’[class^=toggle-item-link5]‘).val(”);

    the toggle-item-link5 comes from:

    var y = this.id.replace(’addNew’, “”);

    how can I append toggle-item-link to y ?

  10. Posted Jun 4, 2009 at 5:28 pm | Permalink

    So glad I found this post. Thank you very much for the clean code! It works great for my purposes.

  11. Marc
    Posted Jun 10, 2009 at 8:27 pm | Permalink

    No demo?

Post a Comment

Your email is never published nor shared. Required fields are marked *