views:

1194

answers:

5

Hi folks, looking for some help please with the JQuery CSS selector. I want to identify the first and last LI from the main UL list and alter the CSS class. The first should be class="grid_4 alpha" and the last class="grid_4 omega"

<ul>
    <li id="linkcat-2" class="grid_4 this should be alpha"><h4 class="widgettitle">Blogroll</h4>
     <ul class='xoxo blogroll'>
      <li><a href="http://wordpress.com/"&gt;WordPress.com&lt;/a&gt;&lt;/li&gt;
      <li><a href="http://wordpress.org/"&gt;WordPress.org&lt;/a&gt;&lt;/li&gt;
     </ul>
</li>
<li id="linkcat-2" class="grid_4"><h4 class="widgettitle">Blogroll</h4>
 <ul class='xoxo blogroll'>
  <li><a href="http://wordpress.com/"&gt;WordPress.com&lt;/a&gt;&lt;/li&gt;
  <li><a href="http://wordpress.org/"&gt;WordPress.org&lt;/a&gt;&lt;/li&gt;
 </ul>
</li>
<li id="linkcat-2" class="grid_4"><h4 class="widgettitle">Blogroll</h4>
 <ul class='xoxo blogroll'>
  <li><a href="http://wordpress.com/"&gt;WordPress.com&lt;/a&gt;&lt;/li&gt;
  <li><a href="http://wordpress.org/"&gt;WordPress.org&lt;/a&gt;&lt;/li&gt;
 </ul>
</li>
<li id="linkcat-2" class="grid_4 this should be omega"><h4 class="widgettitle">Blogroll</h4>
 <ul class='xoxo blogroll'>
  <li><a href="http://wordpress.com/"&gt;WordPress.com&lt;/a&gt;&lt;/li&gt;
  <li><a href="http://wordpress.org/"&gt;WordPress.org&lt;/a&gt;&lt;/li&gt;
 </ul>
</li>
</ul>

I just cannot get the right JQuery.css functio to work.

Help much appreciated - I can add an id to the master ul if requyired

+4  A: 

Use :first-child and :last-child with the child (>) selector:

$("#master > :first-child").addClass("grid_4 alpha");
$("#master > :last-child").addClass("grid_4 omega");

Bear in mind that classes can't have spaces in them. This markup:

<li class="grid_4 alpha">...

defines a list element that has two classes. If you want to select it you can use:

$("li.grid_4.alpha")...

meaning select all the list elements that have both the grid_4 and alpha classes.

cletus
This of course assumes an id of `master` on the top level list.
cletus
slight alteration but $j('#headline > li:first').addClass('alpha');$j('#headline > li:last').addClass('omega'); works for me (changed #master for #headline = thanks
russell
@russell: you want `first-child` and `:last-child` not `:first` and `:last` for this. You need to learn the difference or you'll get bitten, which will come up when (say) you have multiple parents and you'll end up selecting the first child of the first parent and the last child of the last parent and nothing in between.
cletus
Why not just use ">" to make clear the parent-child relationship of the "ul" and "li" tags? Of course this only works if the "ul" reference is pinned to the particular "ul" of interest (the outer one, in the example from the original question).
Pointy
+2  A: 

You should use the following selectors:

http://api.jquery.com/first-selector/

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

e.g.:

$("ul li:first").addClass("alpha");
$("ul li:last").addClass("omega");
brainfck
Except note that the last li has its own ul - so your first selector would select the first li in there too!
Pointy
This selector will also add the alpha and omega classes to the first and last li child of every ul in the list. The top ul should probably be given an ID or class to identify it.
PetersenDidIt
This is patently wrong. Try it. The second one will add the class to the last list element of the xoxo blogroll child list. Try running `$("ul li:last").css("background", "yellow")` on that markup and see what happens.
cletus
A: 

How about this:

$('ul li:first').addClass('alpha');
$('ul li:last').addClass('omage');

Hope this helps :)

Mike P.
You really need to use "ul > li:first" to avoid tagging the first "li" in the sub-UL block in the last outer list item.
Pointy
This is wrong for the same reason as the other same answers are wrong.
cletus
+1  A: 
$('ul > li:first').addClass('alpha');
$('ul > li:last').addClass('omega');

Hey remember the end of Beneath The Planet Of The Apes? That was pretty cool, with the big bomb and everything. Oops I hope I didn't give it away for anybody!

Pointy
Wrong wrong wrong. I see this mistake really often. `:first` and `:last` don't do what you think they do. You want `:first-child` and `:last-child`
cletus
Hmm well I understand that they're different, but can you explain how it'd be possible (assuming correct markup) for those to be different in this case? The only valid children of the "ul" tag are "li" tags anyway, and the selector has the explicit ">" to limit depth of the relationship. (Oh and I understand that the naked "ul" in the selector should include an id value for the outermost block; I didn't make a note of that but clearly that's what you'd want, failing some other way of uniquely targeting it.)
Pointy
A: 

One thing that may cause you a problem in your example is that you have assigned the same id to many items:

id="linkcat-2"

The id is supposed to be unique.

However, this is how you select first and last:

<ul id="main">
    <li>One</li>
    <li>Two
        <ul>
            <li>Two A</li>
            <li>Two B</li>
        </ul>
    </li>
    <li>Three</li>
    <li>Four
        <ul>
            <li>Two A</li>
            <li>Two B</li>
        </ul>
    </li>
</ul>

<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
    alert($("#main > :first-child").text());
    alert($("#main > :last-child").text());
</script>
Sohnee
Now put a child list in the last element of the main list and you'll see exactly why this is wrong.
cletus