views:

6042

answers:

7

Hi stackoverflow! (first post!)

Ive been trying to get this problem solved, but I cant seem to figure it out without some serious workarounds. if I have the following html code:

<ul>
<li class="parent"> headertext </li>
<li> text </li>
<li> text </li>
<li> text </li>
<li class="parent"> headertext </li>
<li> text </li>
<li> text </li>
</ul>

Now, how do I now just select the li's following the first parent (or second, for that matter)? Basically selecting an li with class=parent and the following siblings until it reaches another li with the parent class.

I could restructure the list with nested lists, but I dont want to do that.

Any suggestions?

A: 
$("li.parent ~ li");
Ropstah
$("li.parent ~ li:not(li.parent)"); <<<<< this will leave out the next class="parent"s . It doesn't stop at that point however....
Ropstah
yeah I just wrote that exact same code, but as you mentioned it doesnt stop when it reaches the next class=parent
Contra
+4  A: 

The root of your problem is that the <li>s you have classed as parent really are NOT parents of the <li>s "below" them. They are siblings. jQuery has many, many functions that work with actual parents. I'd suggest fixing your markup, really. It'd be quicker, cleaner, easier to maintain, and more semantically correct than using jQuery to cobble something together.

Mark Hurd
I agree with this, though, I have posted a potential solution. It would be much easier if the DOM relationships matched the actual relationships.
tvanfosson
yeah, actually, I figured the "parent" classname was a bit wrong after I posted it. calling it "header" might be better. I may have to use nested lists after all
Contra
I think in the long run that's the better approach. I know you don't want to redo it now, but you may thank yourself later.
Mark Hurd
I should've redone it at first when I noticed the difficuly on selecting the elements I wanted, since the work redoing the markup is alot less work then beating my jquery code to death :) lesson learned.
Contra
+2  A: 

I don't think there is a way to do this without using each since any of the other selectors will also select the second parent and it's next siblings.

function getSibs( elem ) {
    var sibs = [];
    $(elem).nextAll().each( function() {
        if (!$(this).hasClass('parent')) {
            sibs.push(this);
        }
        else {
            return false;
        }
    });
    return $(sibs);
 }
tvanfosson
*shudder* Great idea, but geez, I'd hate to use it myself. :)
Mark Hurd
haha, actually, that is veery close to the workaround im using atm :) *shame*
Contra
+1  A: 

You will have to run the loop yourself since jQuery does not know how to stop on a specific condition.

jQuery.fn.nextUntil = function(selector)
{
    var query = jQuery([]);
    while( true )
    {
        var next = this.next();
        if( next.length == 0 || next.is(selector) )
        {
            return query;
        }
        query.add(next);
    }
    return query;
}

// To retrieve all LIs avec a parent
$(".parent:first").nextUntil(".parent");

But you may be better using a really structured list for your parent/children relationship

<ul>
<li class="parent"> <span>headertext</span>
    <ul>
    <li> text </li>
    <li> text </li>
    <li> text </li>
    </ul>
</li>
<li class="parent"> <span>headertext</span>
    <ul>
    <li> text </li>
    <li> text </li>
    </ul>
</li>
</ul>
Vincent Robert
Yep, I realized now that this is more clean. Also alot more easy to work with, as someone mentioned. I just thought there were some selector wizardry I couldnt figure out, but It seems that it isnt possible without manipulating the array afterwards.
Contra
A: 

Thanks alot for the all the quick answers! I have to start using this site :)

I've redone my markup now, and I have no problems getting the elements that I wanted.

now.. how do I mark this question as answered..

Contra
Make sure you are not blocking any images from the site, I once put on too much of a restrictive ad filter and was stumped for a while, since the 'checkmark' that you use to select the right answer was no longer showing up.
dalbaeb
ah, I diddnt notice that image at all. thanks for pointing it out :)
Contra
A: 
John Guise
A: 

actually, you can easily do this using nextUntil(). no need to write your own "nextUntil" since it already exists.

ex. - $(".a").nextUntil(".b");

or as suggested by Vincent - $(".parent:first").nextUntil(".parent");

This did not exist before version 1.4 of jQuery, which dropped a bit after the time of the question. But yeah, this will work now :)
Contra