views:

146

answers:

2

Hi folks, Really hoping to get this finished up, and sadly I don't have enough experience to do these last steps. I have a long unordered list that will toggle closed with a button push and show only certain elements of the list. That is working great, but the problem is that I need to only show text within a span in that list. I saw a tutorial online yesterday that was doing something like this: $("#bio li:not(.remain>span)").toggle("slow");

but that doesn't work-I think I'm doing it wrong. What I have so far is this:

$(function() {
    $("#toggle_bio").click(function() {
        $(this).toggleClass("collapsed");
        $("#bio li:not(.remain)").toggle("slow");
        return false;
    });
});


<ul id="bio">
    <li>Long bio text.</li>
    <li class="remain">text will remain.</li>
    <li>Long bio text.</li>
    <li class="remain">text will remain.</li>
    <li>Long bio text.</li>
    <li>Long bio text.</li>
</ul>

<a id="toggle_bio" href="#">Toggle bio</a>

Now this works great, but I need to accomplish two more things:

1) I need to have only the text inside a span remain within the .remain list:

<li class="remain">This text will go away <span>But this text will stay</span></li>

And, I need to change this toggle button to be two buttons:

<a id="toggle_bio" href="#">Toggle bio</a>

into something like:

<a id="longBio" href="#">Long Bio</a><a id="shortBio" href="#">Short Bio</a>

I'm still really new to javascript, so please keep that in mind when you answer. If possible, I don't want to have to change the whole logic of the solution I have-rather modify one or two elements to make this work. Thank you!

+3  A: 

The problem with your new markup is that the span is on the same level as the text node, but text nodes cannot be targeted directly by css.

There are two approaches you could take to make this work.

  1. Surround the text you want to HIDE with the span, or...
  2. Use javascript to remove the text you want to hide and reinsert it on show.

The former is far simpler so instead of using

<li class="remain">This text will go away <span>But this text will stay</span></li>

Use

<li class="remain"><span>This text will go away</span> But this text will stay</li>

Then your code becomes

$("#bio li:not(.remain), #bio li.remain span").toggle("slow");

As for the links, that should be fairly simple. Just modify your click handler like this

$("#longBio, #shortBio").click(function() {
    if ($(this).attr("id") == "longBio")
        $("#bio li:not(.remain), #bio li.remain span").show("slow");
    else
        $("#bio li:not(.remain), #bio li.remain span").hide("slow");
    return false;
})

EDIT:

If you need more control of the display value used for show and hide, you can use a css class. For example:

.hidden { display:none; }

Then change your toggle function to

$("#longBio, #shortBio").click(function() {
    if ($(this).attr("id") == "longBio")
        $("#bio li:not(.remain), #bio li.remain span").removeClass("hidden");
    else
        $("#bio li:not(.remain), #bio li.remain span").addClass("hidden");
    return false;
});
Joel Potter
Perfect! Thank you for the span tip-works great!! Can you elaborate on how to seperate the toggle into two buttons?
Joel
@Joel, Just updated.
Joel Potter
Awesome! Thank you, Joel!
Joel
A strange thing is happening-when I collapse the list and then expand it, the list is taking on a display:block element. Not sure why?
Joel
#bio? that is strange. If you want better control over what display value is used for show and hide on the lis and spans, you should use addClass and removeClass with a class which contains the display style you prefer.
Joel Potter
Well it seems to just be an act of the collapse, expand. When collapsing, hidden list items are taking on display:none. When they expand, the element properties change to display:block. How can I make ul.bio li.lessonslist span{display:block} become ul.bio li.lessonslist span{display:inline} when expanding? That fixes the issue in firebug.
Joel
You'll have to use your own class. I'll edit my answer with an example.
Joel Potter
Cool. That worked well. Thanks again Joel!
Joel
+1  A: 

Alternatively, something along the lines of:

$("#bio li:not(.remain)).hide().children('span').show();

I didn't test that code, but it should work because the CDATA text get's styled first to display: none, then we show the span nodes.

jsapara
Hiding the `li` will cause all children to be hidden. This would most likely produce the markup: `<li class="remain" style="display:none">blah <span style="display:inline;">blah</span></li>` in which the span would obviously be hidden.
Joel Potter
Yup, I gave it a try after work to test it. Was just about to update to say it wouldn't work.
jsapara