11
<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

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Callum
  • 1,004
  • 2
  • 12
  • 18

6 Answers6

16

This will get you what you want

var childCount = ($('#parent_2').get(0).rowIndex - $('#parent_1').get(0).rowIndex) - 1;
Chatu
  • 4,688
  • 3
  • 22
  • 15
  • 3
    +1 excellent! but why bother with intermidiaries? Hit the API directly: document.getElementById('parent_2').rowIndex - document.getElementById('parent_1').rowIndex - 1; – vladr Mar 05 '09 at 00:32
  • Nice answer. Plus, @Vlad is right: jQuery gives you nothing in this case. – Crescent Fresh Mar 05 '09 at 00:33
  • +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 Mar 05 '09 at 00:48
11

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
  • 31,360
  • 7
  • 64
  • 74
  • This was what I was hoping someone would think of. Thanks for teaching me something! ;) – Samantha Branham Mar 05 '09 at 00:02
  • @Vlad: jQuery doesn't use XPATH. – Crescent Fresh Mar 05 '09 at 00:31
  • It's a CSS 3 selector, not XPath, but your point stands—this is probably not the most efficient solution. – Miles Mar 05 '09 at 00:36
  • @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 Mar 05 '09 at 00:38
  • @Miles, sorry, my mind was at Prototype which *will* attempt to use the browser's built-in xpath support (document.evaluate functionality) – vladr Mar 05 '09 at 00:44
  • 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. – Samantha Branham Mar 05 '09 at 01:50
2

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;
});
Samantha Branham
  • 7,350
  • 2
  • 32
  • 44
  • -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 Mar 05 '09 at 00:14
  • 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. – Samantha Branham Mar 05 '09 at 01:52
2

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");
chroder
  • 4,393
  • 2
  • 27
  • 42
2

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
  • 68,817
  • 22
  • 142
  • 198
0

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

$("#parent_1").siblings().size() - 1
qpingu
  • 950
  • 7
  • 11