dukevin
dukevin

Reputation: 23178

Get first td in a tr from $(this) element

I have a table and want to access the first td in the tr's contents, when a button in the same row is pressed.

Here's the fiddle: http://jsfiddle.net/dLyxrh8r/2/

jQuery code

$('button').click(function(){
     console.log($(this).closest('tr td:first-child').html()); //get package name (prints null though)
    $('input[type=checkbox]:checked').each(function(i,elem) {
           if( $(elem).closest('tr td:first-child') == $(this).closest('tr td:first-child') ) //only count the ones in the same row
               console.log($(elem).prop("name");
    });
});

What am I doing wrong?

Update: http://jsfiddle.net/dLyxrh8r/3/

Upvotes: 1

Views: 6903

Answers (3)

Roamer-1888
Roamer-1888

Reputation: 19288

Best way is probably to find the appropriate row with $(this).closest('tr'), and from there use .find() twice to find :

  • the row's first <td> and thence its .text()
  • the row's checkboxes, and thence compose the required "x of n" text

It'll look something like this :

$('button').click(function() {
    var $row = $(this).closest('tr');
    var packageName = $row.find('td:first-child').text();
    var $checkboxes = $row.find('input:checkbox'); //select the checkboxes in the same row
    var checked = 0;
    $checkboxes.each(function(i, elem) {
        //console.log($(elem).prop("name"));
        if(elem.checked) {
            checked += 1;
        }
    });
    console.log(packageName);
    console.log(checked + ' of ' + $checkboxes.length + ' boxes are checked');
});

Updated fiddle

Or if you need to do nothing else with the checkboxes in the each loop, from $checkboxes, you can use .filter() to find those that are checked.

$('button').click(function() {
    var $row = $(this).closest('tr');
    var packageName = $row.find('td:first-child').text();
    var $checkboxes = $row.find('input:checkbox'); //select the checkboxes in the same row
    var checked = $checkboxes.filter(":checked").length;
    console.log(packageName); //get package name (prints null though)
    console.log(checked + ' of ' + $checkboxes.length + ' boxes are checked');
});

Upvotes: 1

Josh Crozier
Josh Crozier

Reputation: 240938

In order to access the first td's contents of the clicked element, change:

$(this).closest('tr td:first-child').html();

to any of the following:

$(this).closest('tr').find('td:first-child').html();
$(this).closest('tr').find('td').eq(0).html();
$(this).closest('tr').find('td:first').html();

Based on the output you are trying to achieve, you would use the following:

Updated Example

$('button').click(function () {
     console.log($(this).closest('tr').find('td:first-child').text());
    $(this).closest('tr').find('input:checked').each(function () {
        console.log(this.name);
    });
});

This will log the name of the package, and then any checked checkboxes within the row of the clicked button.

Upvotes: 3

royhowie
royhowie

Reputation: 11171

Your problem was that you weren't targeting the correct elements.

$("button").click(function () {
    // get the tr (two parents up from the button)
    var tr = $(this).parent().parent();
    // row name is the name of the first child's text
    var row_name = tr.children().first().text();
    // we want to target children of the row's child (td) at index 1
    var b = $(tr).children().eq(1).children()
        .filter(function (index, d) {
            // filter them based on whether they're checked
            return $(d).attr("checked");
        }).map(function (index, d) {
            // and then map the name of the input to the array
            return $(d).attr("name");
        })
    console.log(row_name, b);
})

fiddle

Upvotes: 1

Related Questions