javascripthtmldatatables

Datatable undefined error obtaining row data


I'm having an error getting the data of a row in Datatables and I can't figure it out why it's happening.

Reading the Docs, getting the row data it's as simple as:

var table = $('#example').DataTable();

$('#example tbody').on( 'click', 'tr', function () {
    console.log( table.row( this ).data() );
} );

So, I've a Jinja2 template that it's filled in server-side (in Python 3 using flask):

<table id="table" class="dataTable display responsive nowrap" cellspacing="0" width="100%">
   <thead>
      .....
   </thead>
   <tbody>
      .....
   </tbody>
</table>

And I initialize the Datatable with:

function createDatatable() {
    $('#table').DataTable({
        "select": "single",
        "order": [[2, "asc"]],
        "language": {.....}
        }
    });
}

And attach some events:

function attachEvents() {
   $('#table tbody').on('click', 'td.tdCredits', function () {
        var table = $('#table').DataTable();
        var rowId = table.row(this).data()[0];
    });
    .....
}

Then I do:

$(document).ready(function() {
    createDatatable();
    attachEvents();
});

So, when I want to get the data of the row that I've clicked (regardless of whether it is selected or not) with this code I get an error on the console:

TypeError: table.row(...).data(...) is undefined

What I'm doing wrong? Because I can see the table rendered, with the pagination buttons and I can order the columns as well.

$(document).ready(function() {
	createDatatable();
	attachEvents();
});

function createDatatable() {
    $('#table').DataTable({
        "select": "single",
        "order": [[2, "asc"]]
    });
}

function attachEvents() {
   $('#table tbody').on('click', 'td.tdCredits', function () {
        var table = $('#table').DataTable();
        var rowData = table.row(this).data();
        console.log('Clicked row data: ' + rowData);
        var rowId = table.row(this).id();
        console.log('Clicked row id: ' + rowId);
        // Other code
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet"/>

<table id="table" class="dataTable display responsive nowrap" cellspacing="0" width="100%">
	<thead>
		<tr>
			<th style="display: none;"></th>
			<th class="text-center">Header 1</th>
			<th class="text-center">Header 2</th>
			<th class="text-center">Header 3</th>
			<th class="text-center">Header 4</th>
			<th class="text-center">Header 5</th>
			<th class="text-center">Header 6</th>
			<th class="text-center">Header 7</th>
		</tr>
	</thead>
	<tbody>
		<tr id="someId" class="filter">
			<td style="display: none;"></td>
			<td class="text-center">Cell 1</td>
			<td class="text-center">Cell 2</td>
			<td class="text-center">Cell 3</td>
			<td class="text-center">Cell 4</td>
			<td class="text-center tdCredits">Click here</td>
			<td class="text-center">Cell 6</td>
			<td class="text-center">Cell 7</td>
		</tr>
	</tbody>
</table>


Solution

  • Ok, I've found a trick that solved my problem and I don't need to access the '.data()'.

    The problem I was having is due as you can edit some fields on each row, so the first time you click in one of the filds of the row, the row it's selected so you can use:

    table.row({ selected: true }).index();
    

    But if you click again on other field, the row is deselected and the filter selected:true doesn't work.

    Doing the fiddle I discovered that Datatables uses the ID specified in

    <tr id="someId" ..>
    

    instead of some internal value. So I pass the ID value to my method and force the row to be selected:

    table.row('#' + id).select();
    

    And then I can use:

    var rowIndex = table.row({ selected: true }).index();
    

    And update the proper field instead the field of the first visible row:

    table.cell({row:rowIndex, column:columnIndex}).data(newValue).draw();
    

    Regards!