Datatables add multiple child-rows

32,311

Solution 1

If you want to keep data attributes for your data source, you can do something like this

function format ( dataSource ) {
    var html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
    for (var key in dataSource){
        html += '<tr>'+
                   '<td>' + key             +'</td>'+
                   '<td>' + dataSource[key] +'</td>'+
                '</tr>';
    }        
    return html += '</table>';  
}

$(function () {

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

      // Add event listener for opening and closing details
      $('#example').on('click', 'td.details-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({
                  'Key 1' : tr.data('key-1'),
                  'Key 2' :  tr.data('key-2')
              })).show();
              tr.addClass('shown');
          }
      });
  });
 td.details-control {
    background: url('http://www.datatables.net/examples/resources/details_open.png') no-repeat center center;
    cursor: pointer;
}
tr.shown td.details-control {
    background: url('http://www.datatables.net/examples/resources/details_close.png') no-repeat center center;
}
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://cdn.datatables.net/responsive/1.0.1/js/dataTables.responsive.min.js"></script>
<script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.css" />

<table id="example" class="display nowrap" cellspacing="0" width="100%">
    <thead>
        <tr>
            <th></th>
            <th>Item 1</th>
            <th>Item 2</th>
            <th>Item 3</th>
            <th>Item 4</th>
        </tr>
    </thead>
    <tbody>
        <tr data-key-1="Value 1" data-key-2="Value 2">
            <td class="details-control"></td>
            <td>data 1a</td>
            <td>data 1b</td>
            <td>data 1c</td>
            <td>data 1d</td>
        </tr>
        <tr data-key-1="Value 1" data-key-2="Value 2">
            <td class="details-control"></td>
            <td>data 2a</td>
            <td>data 2b</td>
            <td>data 2c</td>
            <td>data 2d</td>
        </tr>
    </tbody>
</table>

Solution 2

You can create an array of the data you need to show for each row

EG :

var data = [
  { key1 :'value1', key2 :'value2', key3 :'value3'}, //Row1
  { key1 :'value1', key2 :'value2'} //Row2
];

And updated the format()

function format (index ) {
  var json_data =  data[parseInt(index)];
  var op = '';
  $.each(json_data, function(key, value){
    op +='<div>' + key + ': '+ value + '</div>';
  });
  return op;
}

Now just add the index of the array in a custom attribute <tr data-child-index="1">

And finally row.child(format(tr.data('child-index'))).show();

EDIT : No html changes needed.

Calculate the index dynamically using jQuery index()

row.child(format($('#example td.details-control').index($(this)))).show();

DEMO

Share:
32,311
Tony Clifton
Author by

Tony Clifton

Updated on July 09, 2022

Comments

  • Tony Clifton
    Tony Clifton almost 2 years

    I have a table hooked up to the jQuery datatable. Based on this example I want to add "hidden" child rows to show extra information.

    I have the following jsfiddle where I have a name/value pair.

    <tr data-child-name="Name1" data-child-value="Value 1">
        <td class="details-control"></td>
    
    function format ( name, value ) {
        return '<div>' + name + ': '+ value + '</div>';
    }
    
    $(document).ready(function () {
        var table = $('#example').DataTable({});
    
        // Add event listener for opening and closing details
        $('#example').on('click', 'td.details-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(tr.data('child-name'), tr.data('child-value') )).show();
                tr.addClass('shown');
            }
        });
    });
    

    My question is how do I add more than one name/value pair? So that I can define various rows like in the datatables.net example.

    My source is a php-script that generates html like in the jsfiddle example.

    It's probably an easy task but my jQuery skills are very limited :-)

    Thank you.

    UPDATE: The data comes from an ldap query:

    $ldapResults[$i]
    echo "<td>" . utf8_encode($ldapResults[$i]['sn'][0]) . "</td>"
    
  • Tony Clifton
    Tony Clifton over 9 years
    the data comes from an ldap query: $ldapResults[$i] echo "<td>" . utf8_encode($ldapResults[$i]['sn'][0]) . "</td>" I can't modify this at the moment.
  • karan3112
    karan3112 over 9 years
    I did not understand. So what in the above code you cannot edit??
  • BenKoshy
    BenKoshy almost 8 years
    @Freeez hi and thank you - a further question: what if you want another child in the child?
  • Freez
    Freez almost 8 years
    @BKSpurgeon can you be more specific please ?
  • BenKoshy
    BenKoshy almost 8 years
    thank you i meant, what if you want a sub heading within a subheading which shows a bunch of records (rather than listing key value paris)?
  • John Doe
    John Doe about 3 years
    @BKSpurgeon You managed to add a child row within a child row, I am looking to do it that way?
  • BenKoshy
    BenKoshy about 3 years
    @JohnDoe it's been five years! I have no recollection of the original code :P, but am certain some sort of solution can be found