jQuery - Count list children not containing div with class
Asked Answered
I

5

11

I have a simple js script that counts the number of children an unordered list has. I'm trying to change the script so it doesn't count any children (li) which contain a div with the class 'hiddenItem'. Here's the list and the js.

    <ul id="dlist" class="sortable">
        <li id="listItem_000002">
            <div>
                <div><a class="itemCollapse"></a>
                </div>Item 2</div>
        </li>
        <li id="listItem_000003">
            <div>
                <div><a class="itemCollapse"></a>
                </div>Item 3</div>
        </li>
        <li id="listItem_000009">
            <div>
                <div><a class="itemCollapse"></a>
                </div>Item 9</div>
        </li>
        <li id="listItem_000012">
            <div class="hiddenItem">
                <div><a class="itemCollapse"></a>
                </div>Item 12 (Hidden)</div>
        </li>
    </ul>
    <br>
    <br>

    <a class="count">Count</a>

.

    $(".count").click(function () {
        var tcount = $("#dlist").children("li").length;
        alert(tcount);
    });

In this example the js alerts that there are 4 items. But, I'm trying to change the code so it alerts 3 items, due to the last list item containing the div with the class 'hiddenItem.' I've tried to use .filter() as well as a few other transverseing methods with no luck. Anyone have a better idea?

Here's a working fiddle: http://jsfiddle.net/YeDdq/1/

Any help would be appreciated. Thanks!

Imbricate answered 8/2, 2013 at 9:7 Comment(0)
P
13

You can use not method.

var tcount = $("#dlist > li").not(':has(div.hiddenItem)').length;

Or filter method:

var tcount = $("#dlist > li").filter(function(){
                 return $('div.hiddenItem', this).length === 0;
             }).length;
Proclitic answered 8/2, 2013 at 9:11 Comment(2)
Ah, brilliant suggestion. I completely forgot about the not method and it makes plenty sense. Thanks! Cheers!Imbricate
Answer accepted and here's an updated fiddle for those who come along later.. jsfiddle.net/YeDdq/10 Thanks undefined!Imbricate
W
5

.not works, and it's more readable:

$('#dlist > li').not('.hiddenItem').length;

Edit: just realized the first answer also has .not listed, but I'm not sure why they made it so complicated with the has pseudo-class.

Wavellite answered 21/12, 2013 at 1:58 Comment(0)
C
1

Filter should definitely do want you want in this instance. From your fiddle:

$(".count").click(function () {
    var tcount = $("#dlist").children("li")
    .filter(function() { return !($(this).children().is('.hiddenItem')); })
    .length;
    alert(tcount);
});

I've updated your fiddle to reflect this: http://jsfiddle.net/YeDdq/8/

Coltin answered 8/2, 2013 at 9:13 Comment(0)
C
1

You can use the :not and :has selectors

$(function() {
    var tcount = $("#dlist li:not(:has(.hiddenItem))").length;
    alert(tcount);
});
Cole answered 8/2, 2013 at 9:26 Comment(0)
A
0

Try this:

var tcount = $("#dlist > li").filter(function(){
                                         return $(this).find(".hiddenItem")
                                                       .length==0;
                                     }).length
Announcer answered 8/2, 2013 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.