2

I was trying to show the count of all children elements over multiple nested levels beside all li elements which are dynamically generated.

Eg:

Z(8) 
    A(4) 
      B
      C(2)
        D
        E
    F(2)
      G
      H

What i am getting now: Image

Code I used: Sample HTML:

<li class="li-item">
   <a href="#">B R(None)<span class="count-item" data-cnt="2">[2]</span></a>
   <ul class="sub-parent-ul 237">
      <li class="li-item">
         <a href="#">B R(None)<span class="count-item" data-cnt="3">[3]</span></a>
         <ul class="sub-parent-ul 246">
            <li class="li-item">
               <a href="#">Bhu Rik(None)<span class="count-item" data-cnt="3">[3]</span></a>
               <ul class="sub-parent-ul 258">
                  <li class="li-item"><a href="#">Kai Hiwatari(None)<span class="count-item"></span></a></li>
                  <li class="li-item">
                     <a href="#">B R(None)<span class="count-item" data-cnt="2">[2]</span></a>
                     <ul class="sub-parent-ul 263">
                        <li class="li-item">
                           <a href="#">Bhu Rik(None)<span class="count-item" data-cnt="1">[1]</span></a>
                           <ul class="sub-parent-ul 264">
                              <li class="li-item"><a href="#">B R(None)<span class="count-item"></span></a></li>
                           </ul>
                        </li>
                     </ul>
                  </li>
               </ul>
            </li>
         </ul>
      </li>
   </ul>
</li>

JQuery:

$(".sub-parent-ul").each(function() {
        // reusabilty
        var context = $(this);

        // count and populate
        var count = context.children().length;

        context.prev("a").children().text('['+count+']');
        context.prev("a").children().attr('data-cnt',count);

    });

    $(".sub-parent-ul").each(function() {
        var context2 = $(this);

        // count and populate
        var child_count = context2.children().length;
        //check for inner ul
        var sub_count = 0;
        context2.children('li').each(function () {
            var context3 = $(this);
            if(context3.children('a').children('span').attr('data-cnt') !== undefined){
                sub_count += +context3.children('a').children('span').attr('data-cnt');
            }
            if(context2.hasClass('G52436')){
                console.log(context3.children('a').children('span').attr('data-cnt'));
                console.log(context3.children('a').children('span').html());
                console.log(context3.children('a').children('span'));
            }
        });
        // final count and populate

        var tot_count = child_count+sub_count;

        context2.prev("a").children().text('['+tot_count+']');
        context2.prev("a").children().attr('data-cnt',tot_count);
    });

It works for some levels but not everywhere. I am not sure where i am wrong. What's weird is, I have kept some console logs in the calculation logic which will get the complete count of child count. The js object shows the perfect count which i need, but when i select the attr from the object, it shows different value and that is driving me nuts.

console log As you can see in the screenshot, the object shows the count as 2 but the value of attribute returns 1. It looks like it is ignoring the data-cnt of immediate child and getting the next child's data-cnt in some cases.

Can someone please identify the issue?

Bhuvan Rikka
  • 2,683
  • 1
  • 17
  • 27
  • see here http://stackoverflow.com/questions/4291151/jquery-count-child-elements and http://stackoverflow.com/questions/3546659/how-can-i-count-the-number-of-children – D Coder Jul 05 '16 at 12:07
  • @DCoder That will count the immediate children, not the nested children. if you see my code given above, i have already used it to get count of immediate children. – Bhuvan Rikka Jul 05 '16 at 12:13

1 Answers1

1

The code doesn't seem to be using recursion, but rather tries to enumerate a set depth (context,context2,context3). One solution would be to use recursion within the function itself, the other is to use find instead of children to search multiple levels for all the children:

$(".sub-parent-ul").each(function() {
        var context = $(this),
            children = context.find('li'),
            count = children.length,
            a = context.prev("a").children();
        a.text('['+count+']');
        a.data('cnt', count);
});

Not entirely sure it's exactly according to your goal, but the outcome for the example html can be seen in this fiddle

Me.Name
  • 12,259
  • 3
  • 31
  • 48