views:

617

answers:

3

A little odd situation. I'm writing a greasemonkey script on some legacy HTML where everything is put into one table. I want to select all TR elements from the one I click and the next 3-4-5-6 rows up to the next row that contains a TD.class_name

table
  ...
  tr -> td.class_name
  tr
  tr
  tr
  tr -> td.class_name
  ...
/table

So, in the above example I want to select rows 2,3,4 (and hide them, which is the trivial part). The challenge is that I don't know how many rows there are, and this table could be very long.

How could I do that in an elegant way in jQuery?

A: 
var in_selection = false;
$('table#id tr').each(function () {
    if ($('td.class_name', this)) {
        if (in_selection) return false;
        in_selection = true;
    }
    if (in_selection) {
        $(this).addClass('selected');
    }
    return true;
});
not tested
Anatoliy
+1  A: 

I hope you understand the example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
$(function(){

    var fnc = function(){
     $(this).nextAll().each(function() {
         if (($(this)[0]) && ($(this)[0].tagName.toLowerCase()=="tr")) {

          var td_lst = $(this).find('td[class="stop"]');
          if ($(td_lst).length!=0)
           return false;

          $(this).css("background-color","#00FF66");

         } else {
          return false;
         }
    });
  }

  $('table tr[class="xevent"]').bind("click",   fnc);

}); 
</script>
<style>
    .stop{
        background-color:#009999;
    }
</style>
</head>
<body>
<table border="1">
    <tr class="xevent"><td>text a</td><td class="stop">text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr class="xevent"><td>text a</td><td class="stop">text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr class="xevent"><td>text a</td><td class="stop">text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr class="xevent"><td>text a</td><td class="stop">text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
    <tr><td>text a</td><td>text b</td><td>text c</td></tr>
</table>
</body>
</html>
andres descalzo
One thing I learned is that .next() does not return hidden TR elements. Your example works because it traverses through .nextAll()
Jesper Rønn-Jensen
My first example was using .next() with a "while (true)". It worked but I did not think performer. then I switch to .nextAll() to improve
andres descalzo
A: 

Try this... I wasn't sure if you wanted to include the last row (highest up) with the .class_name, so I made an demo of the script on this pastebin site and highlighted the rows it finds. You can remove the commented marks when you want it to actually remove the rows.

Here is the basic code:

$(document).ready(function(){
 $('.class_name').click(function(){
  var row = $(this)[0].rowIndex - 1;
  $(this).addClass('removeme');
  for (j=0;j<row+1;j++){
   var el = $('table tr:eq('+(row-j)+')'); 
   if (el.hasClass('class_name')) {
    // el.addClass('removeme'); // Remove comment marks if you want this row included
    break;
   }
  el.addClass('removeme');
  }
 // $('.removeme').remove();  // Remove comment marks when you want to remove the rows
 });
});

If you did want to include the last (highest up) row with the .class_name class, then just un-comment out the el.addClass('removeme'); before the break

fudgey