Ryan
Ryan

Reputation: 45

Find the last child or grandchild in a UL

I have a CMS generating a basic navigation using a UL. Each first-level LI is styled to be a group. I need to apply a style to the last element within each of the first level LI "groups". Meaning; if a first-level LI has no children, I want to apply a style to it (as the "bottom" of the group); if it does have children, I want to find the last child OR grandchild element that appears (again, the "bottom" of the group). I have used both CSS and Javascript "last" classes, and have successfully applied styles to the last child of a certain depth within the first-level LI, but that isn't helpful since the bottom button of the list is of an unknown depth.

My line of thinking involves a IF statement that finds the last child of the first level, checks if it has children, and if it does, go another level deep and find that last child and checks for children, repeating this process until it finds the last LI that does not have children within the first-level LI groups. However, I am a JS noob and am not sure how to go about that.

I am open to CSS or JavaScript/jQuery solutions. I have been banging my head on this one for a while and appreciate any input or better ideas. Thanks for your help!!

--

Update: here's a code sample of what I am hoping for:

<ul id="navigation>
  <li>Item one</li>  <!--Style this one-->
  <li>Item Two
    <ul>
      <li>Item Two-One</li>
      <li>Item Two-Two</li>  <!--Style this one-->
    </ul>
  <li>
  <li>Item Three
    <ul>
      <li>Item Three-One</li>
      <li>Item Three-Two
        <ul>
          <li>Item Three-Two-One</li>
          <li>Item Three-Two-One</li>  <!--Style this one-->
        </ul>
      </li>
    </ul>
  <li>
  <li>Item Four
    <ul>
      <li>Item Four-One</li>
      <li>Item Four-Two
        <ul>
          <li>Item Four-Two-One</li>
          <li>Item Four-Two-One</li>
        </ul>
      </li>
      <li>Item Four-Three</li>  <!--Style this one-->
    </ul>
  <li>
</ul>

The reason the .last selector doesn't work is because, in the above example, it would style item Four-Two-One since it is the last element of its UL.

Upvotes: 2

Views: 2552

Answers (3)

rlemon
rlemon

Reputation: 17666

To clean up my answer, incase this is read at a later date.

here is my solution to your problem:

var checkChildren = function($this) {
    if (!$this.children().length) {
        $this.css({
            color: '#f00',
            fontWeight: '700',
            textDecoration: 'underline'
        });
        return false;
    }
    return true;
};
$("#navigation").children("li").each(function() {
    $these = $(this);
    while (checkChildren($these)) {
        $these = $these.children().last() || $these.next();
    }
});

Upvotes: 2

tedski
tedski

Reputation: 2311

I think this is what you want. It's part of the jQuery API.

http://api.jquery.com/last/

HTML

<ul>
  <li>list item 1</li>
  <li>list item 2</li>
  <li>list item 3</li>
  <li>list item 4</li>
  <li>list item 5</li>
</ul>

jQuery

$('li').last().css('background-color', 'red');

EDIT:

Okay I figured out a way for you to do it.. the only caveat is that you need to be able to set a class for the first level of <li>'s. I've posted my findings here:

http://jsfiddle.net/TTXch/54/

It selects the last of the <li>'s for each main navigation element. Your posted structure was a little off... the end tags didn't all match up. Anyway, check out the jQuery in the javascript window in the jsFiddle.

Upvotes: 2

ckpepper02
ckpepper02

Reputation: 3437

You should be able to use the jQuery last selector for this (http://api.jquery.com/last-selector/).

Upvotes: 0

Related Questions