Using a class name in jQuery's .closest()

89,067

Solution 1

You need to find the .cost_of_items in the <tr> containing this:

$(this).closest('tr').find('.cost_of_items')

Solution 2

Closest will find the closest ancestor (parent, grandparent), but you will then need to do a find in order to find the correct element to update. For example, if you have an element in a table row and you need another element in that same row:

$('.myElement').closest('tr').find('.someOtherElement');

Edit:

In your case, you will want

$(this).closest('tr').find('.cost_of_items').text(totalTotal.toFixed(2));

Solution 3

I wouldn't use .find(). I'm guessing it will probably be a bit more efficient to traverse up to the closest <td> and get the sibling <td> with the .cost_of_items class using jQuery's .siblings() method.

$(this).closest('td').siblings('.cost_of_items');

EDIT: To clarify, here's the markup from the .append():

<tr class="tableRow">
     <!-- NOTE THAT THE CLOSING </td> IS MISSING FOR THE FIRST <td> -->
    <td><a class="removeItem" href="#"><img src="/admin/images/delete.png"></img></a>
    <td class="om_part_no">' + omPartNo + '</td>
    <td>' + supPartNo + '</td>
    <td>' + cat + '</td>
    <td class="description">' + desc + '</td>
    <td>' + manuf + '</td>
    <td>' + list + '</td>
    <td>' + disc + '</td>
     <!-- TRAVERSE TO HERE -->
    <td>
       <p class="add_edit">Add/Edit</p>
        <!-- START HERE -->
       <input type="text" class="quantity_input" name="quantity_input" />
    </td>
    <td class="price_each_nett price">' + priceEach + '</td>
     <!-- SIBLING IS HERE -->
    <td class="cost_of_items"></td>
    <td><p class="add_edit">Add/Edit</p><input type="text" class="project_ref_input" name="project_ref_input" /><p class="project_ref"></p></td>
</tr>
Share:
89,067
benhowdle89
Author by

benhowdle89

Consultant software engineer and advisor to companies building software products.

Updated on November 05, 2020

Comments

  • benhowdle89
    benhowdle89 over 3 years

    I'm attempting to do some calculations for a "running total", this is my code:

    $('.quantity_input').live('change',function(){         
                    var ValOne = parseFloat($(this).val());
                    var ValTwo = parseFloat($(".price").text())
                    var totalTotal = ((ValOne) * (ValTwo));                         
                    $('.cost_of_items').closest('.cost_of_items').text(totalTotal.toFixed(2));
                    calcTotal();
                });     
    

    .quantity_input is an input, .price is the price of the product, .cost_of_items is where i want to update the total cost for the item, ie. item1 = £5 x 3 quantity = £15 total for item1 calcTotal() is a function that just updates a total cost for the order. The problem is keeping all the math in one row of the table, ie i'm doing the calc in the code above and its not sticking to its row, its updating all the fields with class .cost_of_items etc...

    the problem with showing my html is that its dynamically added by jQuery .appends() but here is the relevant jQuery:

    $('#items').append('<tr class="tableRow"><td><a class="removeItem" href="#"><img src="/admin/images/delete.png"></img></a><td class="om_part_no">' + omPartNo + '</td><td>' + supPartNo + '</td><td>' + cat + '</td><td class="description">' + desc + '</td><td>' + manuf + '</td><td>' + list + '</td><td>' + disc + '</td><td><p class="add_edit">Add/Edit</p><input type="text" class="quantity_input" name="quantity_input" /></td><td class="price_each_nett price">' + priceEach + '</td><td class="cost_of_items"></td><td><p class="add_edit">Add/Edit</p><input type="text" class="project_ref_input" name="project_ref_input" /><p class="project_ref"></p></td></tr>');
    

    EDIT:

    Working solution:

    $('.quantity_input').live('change',function(){         
                    var ValOne = parseFloat($(this).val());
                    var ValTwo = parseFloat($(this).closest('tr').find('.price').text())
                    var totalTotal = ((ValOne) * (ValTwo));                         
                    $(this).closest('tr').find('.cost_of_items').text(totalTotal.toFixed(2));
                    calcTotal();
                });     
    
  • user113716
    user113716 over 13 years
    The context parameter just makes it so that the result returned must be within the context of a specific ancestor. Because thee .cost_of_items is not an ancestor of .quantity_input, some other method is still needed, like .find().
  • Keith Rousseau
    Keith Rousseau over 13 years
    cost_of_items isn't a sibling - it is a descendant of a sibling.
  • user113716
    user113716 over 13 years
    @Keith - Thanks for the down-vote, but you're wrong. <td class="cost_of_items"></td>.
  • Keith Rousseau
    Keith Rousseau over 13 years
    Sorry - I read it quick and thought it was tr. I'll undo my vote
  • Bjorn
    Bjorn over 13 years
    Yes downvote me because the asker's code is so problematic that he has to use a find() with a call to closest in an event instead of having the context readily available.
  • user113716
    user113716 over 13 years
    Not sure if you're referring to me, but if so, I didn't down-vote you. I just pointed out the mistake.
  • user113716
    user113716 over 13 years
    @Keith - No problem. Thanks for the undo.
  • user113716
    user113716 over 13 years
    @user - Your code is fine. You have a starting point at the element that received the event and need to get the proper .cost_of_items element relative to that starting point. Nothing wrong with traversing over to it.
  • Bjorn
    Bjorn over 13 years
    General comment to whoever downvoted what I think is an ok answer. I guess I should have stipulated that you should probably have the context already available based on how the event is bound.
  • user113716
    user113716 over 13 years
    I think you're mis-understanding how either .closest() or its context parameter works. The .closest() method only looks at ancestors. Because the targeted element is not an ancestor of this, .closest() will not find it. All the context does is limit the ancestors to those within the context.