6

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>"

3 Answers 3

6

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>

Sign up to request clarification or add additional context in comments.

5 Comments

@Freeez hi and thank you - a further question: what if you want another child in the child?
@BKSpurgeon can you be more specific please ?
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)?
@BKSpurgeon You managed to add a child row within a child row, I am looking to do it that way?
@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
1

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

2 Comments

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.
I did not understand. So what in the above code you cannot edit??
0

If are are getting json data to show as child then try it like,

else {
    // Open this row
    // pass your json data to show in details
    row.child( format(myJsonData)).show();
    tr.addClass('shown');
}

And in the format function change it like,

function format ( json ) {
    var $json=$.parseJSON(json);// if not parsed
    var str='';
    $json.each(function(key,value){
       str += '<div>'+key+':'+value+'</div>';
    });
    return str;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.