Nested DataTables

Nesting jQuery DataTables Plugin within itself

by Steve Coffman

HTML

<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables_themeroller.css">
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/jquery.dataTables.min.js"></script>
<table id="exampleTable">
    <thead> 
        <tr>
            <th>Year</th>
            <th>Month</th>
            <th>Savings</th>
        </tr>
    </thead>
    <tbody>
         <tr>
      <td>2012</td>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>February</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>March</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>April</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>May</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>June</td>
      <td>$180</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>July</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>August</td>
      <td>$230</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>September</td>
      <td>$40</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>October</td>
      <td>$16</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>November</td>
      <td>$590</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>December</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>February</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>March</td>
      <td>$80</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>April</td>
      <td>$80</td>
    </tr>
    </tbody>
</table>

JavaScript

function fnFormatDetails(table_id, html) {
    var sOut = "<table id=\"exampleTable_" + table_id + "\">";
    sOut += html;
    sOut += "</table>";
    return sOut;
}



var iTableCounter = 1;
    var oTable;
    var oInnerTable;
    var TableHtml;

    //Run On HTML Build
    $(document).ready(function () {
        TableHtml = $("#exampleTable").html();


        //Insert a 'details' column to the table
        var nCloneTh = document.createElement('th');
        var nCloneTd = document.createElement('td');
        nCloneTd.innerHTML = '<img src="http://i.imgur.com/SD7Dz.png">';
        nCloneTd.className = "center";

        $('#exampleTable thead tr').each(function () {
            this.insertBefore(nCloneTh, this.childNodes[0]);
        });

        $('#exampleTable tbody tr').each(function () {
            this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
        });

        //Initialse DataTables, with no sorting on the 'details' column
        var oTable = $('#exampleTable').dataTable({
            "bJQueryUI": true,
            "sPaginationType": "full_numbers",
            "aoColumnDefs": [
            { "bSortable": false, "aTargets": [0] }
        ],
            "aaSorting": [[1, 'asc']]
        });

        /* Add event listener for opening and closing details
        * Note that the indicator for showing which row is open is not controlled by DataTables,
        * rather it is done here
        */
        $('#exampleTable tbody td img').live('click', function () {
            var nTr = $(this).parents('tr')[0];
            if (oTable.fnIsOpen(nTr)) {
                /* This row is already open - close it */
                this.src = "http://i.imgur.com/SD7Dz.png";
                oTable.fnClose(nTr);
            }
            else {
                /* Open this row */
                this.src = "http://i.imgur.com/d4ICC.png";
                oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details');
               ...