How to make childrow always open without getting performance hit

Viewed 30

I have a Datatable with childrow:

$(document).ready(function () {
    var table = $('#example').DataTable({
        ajax: 'static/ajax/data/data.json',
        
        columns: [
            {
                className: 'dt-control',
                orderable: false,
                data: null,
                defaultContent: '',
            },
            { data: 'Value1' },
            { data: 'Value2' },
            { data: 'Value3' },
        ],
        order: [[1, 'asc']],
    });
    
    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.dt-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row(tr);
 
        if (row.child.isShown()) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        } else {
            // Open this row
            row.child(format(row.data())).show();
            tr.addClass('shown');
        }

});

How can I make the child row always open without a performance hit and remove the default green cross? I'm using ajax as a data source.

1 Answers

To create a DataTable with all child data always displayed, you can take the standard approach (for example, using the demo shown here), and then make the following changes:

1 - remove the first (empty) column from the header <th></th> - and also from the footer if needed.

2 - remove the first body column also, as defined in the DataTable itself:

{
  className: 'dt-control',
  orderable: false,
  data: null,
  defaultContent: '',
},

The above 2 changes ensure there still the same number of body columns as there are header (and footer) columns.

3 - remove the event listener code (it is no longer needed):

$('#example tbody').on('click', 'td.dt-control', function () { ... });

4 - Add an initComplete section to the DataTable:

initComplete: function( settings, json ) {
  this.api().rows().every( function () {
    this.child( format(this.data()) ).show();
  });
}

The following example shows the above approach, but it uses a small JavaScript-sourced data set instead of Ajax data.

That does not make a difference to the above steps. Just replace my data: dataSet, option with your ajax option.

var dataSet = [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Zürich",
      "extn": "5421"
    },
    {
      "id": "57",
      "name": "Donna Snider",
      "position": "Customer Support",
      "salary": "$112,000",
      "start_date": "2011/01/25",
      "office": "New York",
      "extn": "4226"
    }
  ];

/* Formatting function for row details - modify as you need */
function format ( d ) {
    // `d` is the original data object for the row
    return '<table class="cell-border" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
        '<tr>'+
            '<td>Full name:</td>'+
            '<td>'+d.name+'</td>'+
        '</tr>'+
        '<tr>'+
            '<td>Extension number:</td>'+
            '<td>'+d.extn+'</td>'+
        '</tr>'+
        '<tr>'+
            '<td>Extra info:</td>'+
            '<td>And any further details here (images etc)...</td>'+
        '</tr>'+
    '</table>';
}

$(document).ready(function() {

    var table = $('#example').DataTable( {
        data: dataSet,
        columns: [
            { data: "name" },
            { data: "position" },
            { data: "office" },
            { data: "salary" }
        ],
        
        initComplete: function( settings, json ) {
          this.api().rows().every( function () {
            this.child( format(this.data()) ).show();
          });
        }
        
    } );

} );
<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

</head>

<body>

<div style="margin: 20px;">

    <table id="example" class="display dataTable cell-border" style="width:100%">
    <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Salary</th>
            </tr>
        </thead>
    </table>

</div>

</body>
</html>

Related