tempid
tempid

Reputation: 8208

jquery - get all td's in a table except those in the first two columns?

How do I retrieve the td's in a tr where the td index (within the row) is not 1 or 2? That is, I want to skip the first two columns. The following code gets the job done but is there a better way to do it? I'm thinking (td eq(0) || eq(1)) something like that.

  $("#time-entry tr").each(function () {
            var trId = $(this).attr('id');
            $(String.format("#{0} td input[id^=txt]", trId)).each(function () { //rewrite
                var tdIndex = $(this).index();
                if(tdIndex != 1 && tdIndex != 2) {

                }
            });
        });

Upvotes: 2

Views: 12587

Answers (5)

rkw
rkw

Reputation: 7297

Here's the fish. note: nnnnnn's solution is the one that should be used.

$("#time-entry tr").each(function () {
    var tr = $(this),
        total = tr.find('td input:last'),
        entries = tr.find('td:gt(1):not(td:last)').find('input'),
        totalVal = 0;

    entries.each(function() { totalVal += parseInt($(this).val()); });
    total.val(totalVal);
});

Upvotes: 0

nnnnnn
nnnnnn

Reputation: 150030

I'd like to suggest an alternative approach, completely ignoring how to do things by index (which you can already see how to do from the other answers) and instead try to solve the underlying problem in a simple and maintainable way.

You said in a comment that what are really trying to do is add up some textboxes and put the row total in the last column, so to me it makes sense to select them directly rather than selecting the containing td elements. You did note that the first two columns have textboxes that you don't want to select but we can easily allow for that.

Rather than messing around with column indexes, which means you'll have to change your code if you later insert/delete/re-order columns, I suggest you give a common class to the elements you want to add up and then another class to the (last column) row-total elements. So something like this in your markup:

<tr>
   <td><input></td>
   <td><input></td>
   <td><input class="addup"></td>
   <td><input class="addup"></td>
   <td><input class="addup"></td>
   <td><input class="total"></td>
</tr>

(Obviously you'll have other attributes but that was just a sample to show the classes.)

Then the JS is really simple:

// process each row
$("tr").each(function() {
   var total = 0;
   // select all "addup" elements in the current row
   $(".addup", this).each(function() {
      // add to the row total, converting to a number with
      // the unary plus operator. TODO: add some validation to be
      // sure the user actually entered numeric data
      total += +this.value;
   });
   // display the total
   $(".total", this).val(total);
});

If you insert extra columns in the middle that shouldn't be added, no problem: without the "addup" class they'll be ignored automatically.

Note also that your code: $(String.format("#{0} td input[id^=txt]", trId)) seems to be trying to use a C# method in the middle of your JavaScript, which won't work. But you don't need to worry about trying to select elements based on the current row's id because within the $("tr").each() handler the keyword this will refer to the current row so you can pass that to the $() function as context for the selection. So like $(".addup", this) as shown above.

Upvotes: 2

j08691
j08691

Reputation: 207901

$('tr:gt(1) td') should do it.

Edit: I misunderstood your original request and thought you wanted to select the cells in all but the first two rows. To get all cells in everything but the first column, try:

$('tr').each(function(){ 
    $('td:gt(1)',this).css('background','red')  
});

Which would color the background of all cells except those in the first two columns.

Upvotes: 0

James Khoury
James Khoury

Reputation: 22319

On the assumption that the 'index' is the index of that td in its parent tr

$("#time-entry tr td").not(":nth-child(1), :nth-child(2)");

EDIT:- this one is shorter

$("#time-entry td:not(:nth-child(1), :nth-child(2))");

EDIT 2:-
About the index passed through the .each() function:
the selector (e.g. $("td")) will get you a list of elements the index it passes is the index it is in that list.

EDIT 3:- asking about :gt()

it looks for the index of the matched set. So if the matched set is all the <td> elements in the table it won't work for you. It will work this way though:

$("#time-entry tr").each(function () {
    $("td:gt(1)", this).each(function(){
    });
});

But i don't know why one would favour this way over the other suggested ways.

Upvotes: 6

solidau
solidau

Reputation: 4081

you can specify the index in the callback as such:

$("#time-entry tr").each(function (index, value) {
  if (index != 1 || index != 2) 
  {
    //do stuff
  }
});

Upvotes: 0

Related Questions