views:

152

answers:

4

I want to "functionalize" more of my jQuery code, instead of writing little standalone snippets. Here's an example. Let's say I have some li's that I'd like to use as triggers, like so:

<li class="alpha-init" id="a-init">A</li>
<li class="alpha-init" id="b-init">B</li>
<li class="alpha-init" id="c-init">C</li>

And some stuff I'd like to hide and show in correspondence to clicks on those triggers, like so:

<ul id="a-sub" class="alpha-popdown">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>

<ul id="b-sub" class="alpha-popdown">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>


<ul id="c-sub" class="alpha-popdown">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>

If I wanted to write a little snippet for each case, I could do:

$('li.alpha-init #a-init').click(function(){
    $('ul#a-sub').slideToggle(200);
}

But that means writing as many snippets as there are sets of links and submenus. How can I write this into a function? I'm not looking to "eat for a day", so as much explanation as you feel up to writing would be much appreciated. Thanks very much!

+2  A: 
$('li.alpha-init').click(function(){
    $('ul#'+this.id.substr(1) + "-sub").slideToggle(200);
}
Artem Barger
If you don't want to do the string manipulation, this would be a case where I would consider storing the related ul ID value in the 'rel' attribute of the alpha-init elements then replace the substr call above with this.attr("rel")
John Sheehan
This is excellent. I was thinking of something else all together, like arrays and each(), but this works great. Thanks.
littlerobothead
+1  A: 

Have you considered using jQuery UI Tabs for this? It sounds nearly exactly like what you want. You can just style the tabs differently than the default!

Jason Berry
jQuery UI has some really nice tricks, but it can also be overkill for simple effects, and it also doesn't help 'littlerobothead' here learn anything.
Gabriel Hurley
True. Though UI Tabs might be the right path to go down depending on his requirements.
Jason Berry
I'm using jQuery UI on this project for a few things, but the overhead is awfully steep. I was hoping to edge ever closer to building some plugins and functions of my own, and this seemed like a good thought problem to help me start down that road.
littlerobothead
No worries. Make sure you're using Google AJAX Libraries (http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery) to serve jQuery and jQuery UI if possible - that will reduce your overhead and make sure your libraries are served as fast as possible.
Jason Berry
A: 

First off, id's should be unique on your page. You only need to use the selector $('#a-init') to access it.

I would write that like so (for each item):

html:

<li class="alpha-init" id="a-init">
<div>A</div>
<ul id="a-sub" class="alpha-popdown">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>
</li>

And then write the jquery as:

$('li.alpha-init').click(function(){
    $(this).children('ul.alpha-popdown').slideToggle(200);
}

The basic idea would be to use the $(this) method to access the item that was clicked and select your menu element relative to the parent element.

Gabriel Hurley
Have another look at his markup. I'm not sure that the structure of his markup is the same as the solution you've mentioned.
Jason Berry
It's true. Depending what he's doing, my markup change could change the actual effect/layout/meaning of the page. Artem's solution is the best here.
Gabriel Hurley
A: 

I used a combination of Artem Barger and John Sheehan's code. Thanks everyone for your help; now I get to sleep!

littlerobothead
Would be nice if you'll correct my name spelling. ;)
Artem Barger