views:

3959

answers:

7
<table>
  <tr id="parent_1">
    <td>Parent 1</td>
  </tr>
  <tr class="child">
    <td>Child 1</td>
  </tr>
  <tr class="child">
    <td>Child 2</td>
  </tr>
  ...
  <tr id="parent_2">
    <td>Parent2</td>
  </tr>
  ...
</table>

How can I find the number of child rows between parent_1 and parent_2 using jQuery?

Edit: Sorry, didn't make it clear that this is just an example, the table could contain any number of parent rows, and any number of child rows

A: 

Assuming parent_1 and parent_2 are the start and the end rows respectively:

$("#parent_1").siblings().size() - 1
qpingu
-1 - why the assumption that #parent_2 is the last row?
vladr
Why would it matter what order they're in?
eyelidlessness
+1  A: 

First idea that came to mind. I'm sure there's some elaborate way to select the elements in question, (meaning you would just have to do $(selector).length) but I can't think of one off the top of my head.

var doCount = false;
var numberOfChildren = 0;

$('tr').each(function(i){
    if($(this).is("#parent_2"))
        doCount = false;

    if(count)
        numberOfChildren++;

    if($(this).is("#parent_1"))
        doCount = true;
});
Stuart Branham
-1 - Poor performance; scans all rows in the table, even if you have 1 million and are only going to end up counting two (which happen to be at the end of the table.)
vladr
How often are you going to have so many rows that counting them kills performance? I agree there are better solutions, but I wouldn't worry about O(n) too much in this context.
Stuart Branham
+6  A: 

This:

$('#parent_1 ~ .child:not(#parent_2 ~ *)').size()

Translation: match all elements of class child that are a sibling of, and come after, #parent_1, but not those that are a sibling of and come after #parent_2.

Miles
This was what I was hoping someone would think of. Thanks for teaching me something! ;)
Stuart Branham
@Vlad: jQuery doesn't use XPATH.
Crescent Fresh
It's a CSS 3 selector, not XPath, but your point stands—this is probably not the most efficient solution.
Miles
@crescentfres - I stand corrected, sorry, I had Prototype in mind; but the selector above will still do an order of magnitude more work (i.e. calls to the DOM API) than Chatuman's solution according to the jQuery source code. :)
vladr
@Miles, sorry, my mind was at Prototype which *will* attempt to use the browser's built-in xpath support (document.evaluate functionality)
vladr
If I weren't dealing with a table with millions of rows, (which you wouldn't be doing 99.9% of the time unless you want to bombard users w/ data) I would still rather use this solution. I probably will want to do something with those rows later, and it's easier to read if you know jQuery.
Stuart Branham
A: 

I think the best way is probably to count manually. It'll be faster because you can break off when you know you've done counting (useful if your table is huge).

var rowid1 = 'parent_1';
var rowid2 = 'parent_2';

var rows = $("#"+rowid1).parent().find('tr');
var count = 0;

for (var i = 0; i < rows.size(); i++) {
    var el = rows.get(i);

    // Done counting
    if (el.id == rowid2) break;

    if (el.id != rowid1) {
     ++count;
    }
}

alert("There are " + count + " rows between");
Christopher Nadeau
Still bad if the table's huge and parent_1 is towards the end of the table!
vladr
A: 

Some people have some nice answers here, i was already started on mine so ill just add it for extra info.

$(document).ready(function() {
    n = 0;
    var x = new Array(0,0,0);

    $("table tr").each(function(i)
    {
        if($(this).hasClass("child"))
        {
         x[n] += 1;
        }
        else
        {
         n += 1;
        }
    });

    for(var y = 0; y < x.length; y++)
    {
        alert(x[y]);
    }
});

EDIT btw mine does not care how many parents are there, it will just keep counting as long the array is big enough.

Ólafur Waage
+7  A: 

This will get you what you want

var childCount = ($('#parent_2').get(0).rowIndex - $('#parent_1').get(0).rowIndex) - 1;
Chatu
+1 excellent! but why bother with intermidiaries? Hit the API directly: document.getElementById('parent_2').rowIndex - document.getElementById('parent_1').rowIndex - 1;
vladr
Nice answer. Plus, @Vlad is right: jQuery gives you nothing in this case.
Crescent Fresh
+1 Vlad's comment! Of course this assumes there are no other rows in between which are neither ‘parent’ nor ‘child’, which is probable but the question's not entirely clear.
bobince
good solution-very simple
praveenjayapal
A: 

I'm very new to Jquery. Instead of alert, how do I append the value or count next to the Parent 1. e.g. I wanted "Parent 1" text to change to "Parent 1(2)" where '2' is the number of childs for the given parent. Please let me know.