Returning row data in responsive datatable table

I am using the jquery datatable with the responsive option turned on. I am having trouble returning row data when the table is in responsive mode:

My table:

$('#productsTable').DataTable({
        responsive: true
});

The table has a column for product code, brand, category, price, and an 'add to cart' button. The button is supposed to retrieve the row data. However, when the table is in responsive mode (aka it's shrunk and some of the columns have collapsed) and i click my button, it does not return any data.

My html table:

<table id="productsTable" class="table table-striped table-bordered dt-responsive nowrap" cellspacing="0" width="100%">
<thead>
    <tr>
        <th>Product Code</th>
        <th>Brand</th>
        <th>Category</th>
        <th>Price ($)</th>
        <th></th>
    </tr>
</thead>
<tbody>
    {{#each context}}
    <tr>
        <td class="product_code">{{product_code}}</td>
        <td class="brand">{{brand}}</td>
        <td class="category">{{category}}</td>
        <td class="price">{{invoice_price}}</td>
        <td><button type="button" class="btn btn-primary">Add to Cart</button></td>
    </tr>
    {{/each}}
</tbody>
</table>

My add to cart event:

$(".btn-primary").click(function(e) {

    var price = $(this).parent().parent().children('td.price').text();

    var context = {
        product_code: $(this).parent().parent().children('td.product_code').text(),
        brand: $(this).parent().parent().children('td.brand').text(),
        category: $(this).parent().parent().children('td.category').text(),
        price: $(this).parent().parent().children('td.price').text(),
    };

     console.log(context) //console.logs context

});

Image of collapsed table:

Image of collapsed table

Can someone help?

Thanks in advance!


Solution 1:

Well, i was searching a solution for this and I didn't find anything that solve this problem so i made this:

$(document).on('click', '.button', function () {//Button inside a cell
    var current_row = $(this).parents('tr');//Get the current row
    if (current_row.hasClass('child')) {//Check if the current row is a child row
        current_row = current_row.prev();//If it is, then point to the row before it (its 'parent')
    }
    var data = products.row(current_row).data();//At this point, current_row refers to a valid row in the table, whether is a child row (collapsed by the DataTable's responsiveness) or a 'normal' row
    console.log('Row data:'+data);
});

Solution 2:

Datatables.js stores the table data in memory, you should really look for the values there, instead of in the DOM. Keeping data manipulation logic separate from presentation will lead to cleaner, modular code.

You need the data of the clicked row. One way to get that data is to provide the datatables API a reference to the <tr> element.

$(".btn-primary").click(function(e) {
    var $tr = $(this).closest('tr');
    var rowData = $('#productsTable').DataTable().row($tr).data();
    console.log(rowData);
});

Solution 3:

thank you for two answers above. i developed datatable with server side . so i combine this two things together. That is my solution for datatable with server side

$('#list_quoation tbody').on( 'click', 'button', function () {

    var data = table.row( $(this).parents('tr') ).data();

    // This work when data table is responsive
    if(data == undefined) {

        var selected_row = $(this).parents('tr');
        if (selected_row.hasClass('child')) {
            selected_row = selected_row.prev();
        }

        var rowData = $('#list_quoation').DataTable().row(selected_row).data();

        window.location.href = "/preapplication/" + rowData.quot_id;

    } else {

        window.location.href = "/preapplication/" + data.quot_id;
    }

});