Cosmin Cosmin - 1 month ago 7
jQuery Question

Having trouble targeting inputs using class and data attribute with JQuery

I have the following table which is the result of an AJAX call.

Each row in the table refers to a document in the database which has a language and a number of pages. The number of pages can be changed for each document and also a document can be removed from the table.

In the end of the table I have a text input with the total number of pages for each language.

What I want to accomplish is this: when the number of pages of a document is changed, update the total number of pages for the corresponding language. Also, the total number of pages needs to update when a document gets deleted.

<table id="documents">
<thead>
<tr>
<td>Name</td>
<td>Owner</td>
<td>Language</td>
<td>Pages</td>
<td>Price</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr class="doc_item" data-language-id="1">
<td>Lorem ipsum dolor sit amet</td>
<td>John Smith</td>
<td>English</td>
<td><input type="text" name="pages[]" value="3" class="doc_pages"></td>
<td>25 USD</td>
<td><a class="delete">Delete document</a></td>
</tr>
<tr class="doc_item" data-language-id="1">
<td>Quisque egestas dui ac luctus efficitur</td>
<td>Jane Watham</td>
<td>English</td>
<td><input type="text" name="pages[]" value="12" class="doc_pages"></td>
<td>40 USD</td>
<td><a class="delete">Delete document</a></td>
</tr>
<tr class="doc_item" data-language-id="1">
<td>Nam mattis sem vel est tristique congue ut sit amet nulla</td>
<td>Eric Stevenson</td>
<td>English</td>
<td><input type="text" name="pages[]" value="2" class="doc_pages"></td>
<td>20 USD</td>
<td><a class="delete">Delete document</a></td>
</tr>
<tr class="doc_item" data-language-id="2">
<td>Lorem ipsum dolor sit amet</td>
<td>Ian Young</td>
<td>German</td>
<td><input type="text" name="pages[]" value="6" class="doc_pages"></td>
<td>50 USD</td>
<td><a class="delete">Delete document</a></td>
</tr>
<tr class="doc_item" data-language-id="3">
<td>Lorem ipsum dolor sit amet</td>
<td>Matt Jobs</td>
<td>Rusian</td>
<td><input type="text" name="pages[]" value="9" class="doc_pages"></td>
<td>40 USD</td>
<td><a class="delete">Delete document</a></td>
</tr>
<tr>
<td colspan="6">
<input type="text" class="pages_per_language" data-language-id="1" value="17">
<input type="text" class="pages_per_language" data-language-id="2" value="6">
<input type="text" class="pages_per_language" data-language-id="3" value="9">
</td>
</tr>
</tbody>
</table>


Right now I'm having troubles selecting the correct language input by class and attribute. As you can see in the fiddle, when an input is changed I loop through all the inputs available and try to find the new sum of pages and then set that value to the total number of pages input.

$(document).ready(function() {
var new_total_per_language = 0;

$('.delete').on('click', function() {

});

$('.doc_pages').on('change', function() {
// Get the language id for the changed document
var document_language_id = $(this).closest('tr').data('language-id');

// Find all documents with the same language-id and sum the number of pages
$('#documents tr.doc_item').each(function(index, value) {
$tr = $(this);
if ($tr.data('language-id') == document_language_id) {
new_total_per_language += $('input .doc_pages').val();
}
});

// Set the new total in the coresponding input
$('.pages_per_language[language-id='"+document_language_id+"']').val(new_total_per_language);
});
});


jsFiddle

Answer

Look at this line:

new_total_per_language += $('input .doc_pages').val();

First you are looking for an input with a child element, that is not possible. Second, you do not select the input in the TR, you select all inputs

new_total_per_language += $tr.find('input.doc_pages').val();

You also reset new_total_per_language so that total is going to increase on every iteration.

You could also just do

var total = 0;
$('tr.doc_item[data-language-id="'+ document_language_id + '"] input.doc_pages').each( function () {
   total += Number(this.value);
});

$('.doc_pages').on('change', function() {
       
       var document_language_id = $(this).closest('tr').data('language-id');

  var total = 0;
$('tr.doc_item[data-language-id="'+ document_language_id + '"] input.doc_pages').each( function () {
   total += Number(this.value);
});

        $('input[data-language-id="'+document_language_id+'"]').val(total);
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="documents">
    <thead>
        <tr>
            <td>Name</td>
            <td>Owner</td>
            <td>Language</td>
            <td>Pages</td>
            <td>Price</td>
            <td>Action</td>
        </tr>
    </thead>
    <tbody>
        <tr class="doc_item" data-language-id="1">
            <td>Lorem ipsum dolor sit amet</td>
            <td>John Smith</td>
            <td>English</td>
            <td><input type="text" name="pages[]" value="3" class="doc_pages"></td>
            <td>25 USD</td>
            <td><a class="delete">Delete document</a></td>
        </tr>
        <tr class="doc_item" data-language-id="1">
            <td>Quisque egestas dui ac luctus efficitur</td>
            <td>Jane Watham</td>
            <td>English</td>
            <td><input type="text" name="pages[]" value="12" class="doc_pages"></td>
            <td>40 USD</td>
            <td><a class="delete">Delete document</a></td>
        </tr>
        <tr class="doc_item" data-language-id="1">
            <td>Nam mattis sem vel est tristique congue ut sit amet nulla</td>
            <td>Eric Stevenson</td>
            <td>English</td>
            <td><input type="text" name="pages[]" value="2" class="doc_pages"></td>
            <td>20 USD</td>
            <td><a class="delete">Delete document</a></td>
        </tr>
        <tr class="doc_item" data-language-id="2">
            <td>Lorem ipsum dolor sit amet</td>
            <td>Ian Young</td>
            <td>German</td>
            <td><input type="text" name="pages[]" value="6" class="doc_pages"></td>
            <td>50 USD</td>
            <td><a class="delete">Delete document</a></td>
        </tr>
        <tr class="doc_item" data-language-id="3">
            <td>Lorem ipsum dolor sit amet</td>
            <td>Matt Jobs</td>
            <td>Rusian</td>
            <td><input type="text" name="pages[]" value="9" class="doc_pages"></td>
            <td>40 USD</td>
            <td><a class="delete">Delete document</a></td>
        </tr>
        <tr>
            <td colspan="6">
                <input type="text" class="pages_per_language" data-language-id="1" value="17">
                <input type="text" class="pages_per_language" data-language-id="2" value="6">
                <input type="text" class="pages_per_language" data-language-id="3" value="9">
            </td>
        </tr>
    </tbody>
</table>

Comments