Search code examples
javascriptjquerydatatables

Why can't I retrieve the row of an input field in a jquery datatable


I am trying to create a datatable, and respond to user input in it. When I get a change event on an input field in the table, I want to find out which row the event is in. As I understand it, table.api().row(item) should return the row object containing the item. But it doesn't. What am I doing wrong?

<html>
<head>
<link href="//datatables.net/download/build/nightly/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="//datatables.net/download/build/nightly/jquery.dataTables.js"></script>
<script>
function drawInput(data, type, row, meta) {
    return '<input id="r' + meta.row + 'c' + meta.col + '" val="' + data + '"></input>';
}
var data = [ { c1: 'r1c1', c2: 'r1c2' }, { c1: 'r2c1', c2: 'r2c2' }];
$(function() {
    var table = $('table').dataTable({
        info: false,
        searching: false,
        ordering: false,
        paging: false,
        columns: [
            {
                data: 'c1',
                name: 'c1',
                heading: 'Col 1',
                defaultContent: '<input></input>',
                render: drawInput
            },
            {
                data: 'c2',
                name: 'c2',
                heading: 'Col 2',
                defaultContent: '<input></input>',
                render: drawInput
            }
        ]
    });
    table.api().rows.add(data);
    table.api().draw();
    $('body').on('change', 'table :input', function(e) {
        // Find the row that contains the input field
        console.log(this);
        var row = table.api().row(this);
        // Show the row index - result is undefined! Why?
        console.log(row.index());
    });
});
</script>
</head>
<body>
 <table width="100%">
  <thead>
   <tr>
    <th>Col 1</th>
    <th>Col 2</th>
   </tr>
  </thead>
  <tbody>
 </table>
</body>
</html>

P.S. I'm sure I used to be able to make code snippets executable on Stack Overflow. But I've forgotten how?


Solution

  • This should solve your issue.

    Your not using the API correctly.

    https://datatables.net/reference/api/cell().index() https://datatables.net/reference/api/row().index()

    function drawInput(data, type, row, meta) {
      return '<input id="r' + meta.row + 'c' + meta.col + '" val="' + data + '"></input>';
    }
    
    $(function() {
      var data = [{
        c1: 'r1c1',
        c2: 'r1c2'
      }, {
        c1: 'r2c1',
        c2: 'r2c2'
      }];
      var table = $('table').dataTable({
        info: false,
        searching: false,
        ordering: false,
        paging: false,
        columns: [{
            data: 'c1',
            name: 'c1',
            heading: 'Col 1',
            defaultContent: '<input></input>',
            render: drawInput
          },
          {
            data: 'c2',
            name: 'c2',
            heading: 'Col 2',
            defaultContent: '<input></input>',
            render: drawInput
          }
        ]
      });
      table.api().rows.add(data);
      table.api().draw();
      $('body').on('change', 'tbody td', function(e) {
        console.log(table.api().cell(this).index());
        console.log(table.api().row(this).index());
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="//cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
    <link href="//cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" rel="stylesheet" />
    <table width="100%">
      <thead>
        <tr>
          <th>Col 1</th>
          <th>Col 2</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>