Datatables - Drill down rows with nested independe

2019-01-31 01:30发布

问题:

Is anyone using DataTables with drill down rows and nested independent table? Similar to powerTable?

Can you post any links/examples?

回答1:

Here's my JSFiddle(press "Run" for icons to show) which implements independent nested jQuery DataTables. In this case I just copy the html of the original Table, and post it into the Details row, to save me the hassle of making a new Table.

Here's the only interesting part of the code really, that makes the NestedTables different from simple DrillDown:

else {      /* Open this row */

            this.src = "http://i.imgur.com/d4ICC.png";

            // fnFormatDetails() pieces my Table together, instead you can 
            // use whatever code you like to create your nested Table html
            oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details');

            // ... and here I cast dataTable() on the newly created nestedTable 
            oInnerTable = $("#exampleTable_" + iTableCounter).dataTable({
                "bJQueryUI": true,
                "sPaginationType": "full_numbers"
            });
            iTableCounter = iTableCounter + 1;
        }

Notice how you can Filter, Sort, etc.. on each table independently.



回答2:

I built on top of Rafael Cichocki's excellent jsfiddle adding dynamic data and two different datatables to emphasize that the fact that detail table can be different from the master table:

http://jsfiddle.net/headwinds/zz3cH/

$('#exampleTable tbody td img').live('click', function () {
            var nTr = $(this).parents('tr')[0];
            var nTds = this;

            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 */
                var rowIndex = oTable.fnGetPosition( $(nTds).closest('tr')[0] ); 
                var detailsRowData = newRowData[rowIndex].details;

                this.src = "http://i.imgur.com/d4ICC.png";
                oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, detailsTableHtml), 'details');
                oInnerTable = $("#exampleTable_" + iTableCounter).dataTable({
                    "bJQueryUI": true,
                    "bFilter": false,
                    "aaData": detailsRowData,
                    "aoColumns": [
                    { "mDataProp": "name" },
                    { "mDataProp": "team" },
                    { "mDataProp": "server" }
                ],
                    "bPaginate": false,
                    "oLanguage": {
                        "sInfo": "_TOTAL_ entries"
                    }
                });
                iTableCounter = iTableCounter + 1;
            }
        });


回答3:

My version of the nested datatables from @Rafael and @Headwinds but with Datatables version 1.10.11 with new API. Also uses bootstrap. Picks best of both.

See Nested Datatables 1.10.11 .

 $('#opiniondt tbody td.details-control').on('click', 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(iTableCounter) ).show();
        tr.addClass('shown');
        // try datatable stuff
        oInnerTable = $('#opiniondt_' + iTableCounter).dataTable({
            data: sections, 
            autoWidth: true, 
            deferRender: true, 
            info: false, 
            lengthChange: false, 
            ordering: false, 
            paging: false, 
            scrollX: false, 
            scrollY: false, 
            searching: false, 
            columns:[ 
               { data:'refCount' },
               { data:'section.codeRange.sNumber.sectionNumber' }, 
               { data:'section.title' }
             ]
        });
        iTableCounter = iTableCounter + 1;
    }
 });


回答4:

I also needed something similar to this, and below a sample how I did. Might help someone.

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script type="text/javascript" >
    $(document).ready(function () {

        $('tr.tree-toggler').click(function () {
            $(this).parent().find('tr').eq(2).find('td.tree').toggle(300);
        });
    });

</script>
</head>
<body>

<table>
    <tbody>
    <tr>
        <td>

            <table>
                    <tbody>

                    <tr class="tree-toggler nav-header">
                        <td>
                            <table border="1" style="width: 100%">
                                <tbody>
                                    <tr class="tree-toggler nav-header">
                                        <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </td>
                    </tr>
                    <tr>
                        <td class="nav nav-list tree" style="display: none;">
                            <table class="table" border="1">
                                <tbody>
                                    <tr>
                                            <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>
                                    <tr>
                                            <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>

                                </tbody>
                            </table>
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>
    <tr>
        <td>        
            <table>
                    <tbody>

                    <tr class="tree-toggler nav-header">
                        <td>
                            <table border="1" style="width: 100%">
                                <tbody>
                                    <tr class="tree-toggler nav-header">
                                        <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </td>
                    </tr>
                    <tr>
                        <td class="nav nav-list tree" style="display: none;">
                            <table class="table" border="1">
                                <tbody>
                                    <tr>
                                        <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>
                                    <tr>
                                        <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>

                                    <tr>
                                        <td style="width: 30px;">
                                            Demo
                                        </td>
                                        <td style="width: 200px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                        <td style="width: 100px;">
                                            Demo
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>
</tbody>
</table>
</body>
</html>


回答5:

Here is an example (based on Nicholas' above) where the child datatable uses an ajax call to get info from database. Note BuildBoMDataTable() builds the parent table, while BuildBoMPartsDataTable() handles each child table.

var iTableCounter = 1;
var oInnerTable;
var boMDataTable = new Object;

$(document).ready(function () {
    BuildBoMDataTable();
    AddBomDataTableListener();
});

function AddBomDataTableListener() {

    // Add event listener for opening and closing details
    $('#boMDataTable tbody').on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = boMDataTable.row(tr);

        if (row.child.isShown()) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Add the html table shell of the datatable.
            row.child(formatBomDataTableDetailRow(iTableCounter)).show();

            //show the datatable row.
            tr.addClass('shown');

            // try datatable stuff
            BuildBoMPartsDataTable(row.data(), iTableCounter);
            iTableCounter = iTableCounter + 1;
        }
    });
}

function BuildBoMDataTable() {

    if ($.isEmptyObject(boMDataTable)) {
        boMDataTable = $("#boMDataTable").DataTable({
            lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
            pageLength: 10,
            dom: "tip",
            pagingType: "simple",
            serverSide: true,
            autowidth: false,
            language: {
                emptyTable: "You have no bill of materials associated with your groups and/or projects."
            },
            ajax: {
                url: "/remote/GetParentTableData",
                type: "POST",
                data: function (d) {
                    var searchData =
                        {
                            personID: $("#PersonID").val(),
                            selecttype: $("#SelectType").val(),
                            draw: d.draw,
                            length: d.length,
                            start: d.start,
                            order: d.order,
                            columns: d.columns,
                            orderbyfield: d.columns[d.order[0].column].data
                        };
                    d.sData = JSON.stringify(searchData);
                }
            },
            columns: [
                {
                    className: 'details-control',
                    orderable: false,
                    data: null,
                    defaultContent: '<img class="details-control-mouseover" src="/Content/images/details_transparent_background.png" title="Click to see included parts." alt="Click to see included parts."/>'
                },
                { data: "RecordSelector", orderable: false, class: 'dt-center', width: "6%" },
                { data: "Description", width: "25%" },
                { data: "TeamDetails", width: "25%" },
                { data: "CustomerGroupName", width: "13%" },
                { data: "ProjectGroupName", width: "13%" },
                { data: "ClassificationTypeDescription", width: "10%" },
                { data: "AuditDateFormatted", name: "AuditDateFormatted", className: 'dt-center', width: "10%" }
            ],
            order: [[2, "asc"]]
        });
    }
}

function BuildBoMPartsDataTable(parentObjData, tableCounter) {
    oInnerTable = $("#boMPartDataTable_" + tableCounter).DataTable({
        autoWidth: true,
        dom: "tip",
        pagingType: "simple",
        serverSide: true,
        //processing: true,
        autowidth: false,
        language: {
            emptyTable: "This bill of material contains no part."
        },
        ajax:
        {
            url: "/remote/GetChildTableData",
            type: "POST",
            data: function (d) {
                var searchData =
                    {
                        bomID: parentObjData.BomID,
                        draw: d.draw,
                        length: d.length,
                        start: d.start,
                        order: d.order,
                        columns: d.columns,
                        orderbyfield: d.columns[d.order[0].column].data
                    };
                d.sData = JSON.stringify(searchData);
            }
        },
        columns: [
           { data: 'RecordSelector' },
           { data: 'PartNumber' },
           { data: 'Quantity' },
           { data: 'UomAbbreviation' },
           { data: 'StatusName' },
           { data: 'PartNotes' },
           { data: 'IsBomDescription' }
        ]
    });
}

function formatBomDataTableDetailRow(table_id) {
    return  '<div class="table-responsive">' +
            '    <table id="boMPartDataTable_' + table_id + '" class="table table-striped table-bordered">' +
            '        <thead>' +
            '            <tr>' +
            '                <th></th>' +
            '                <th title="Click to sort by part number." alt="Click to sort by part number.">PartNumber</th>' +
            '                <th title="Click to sort by quantity." alt="Click to sort by quantity.">Quantity</th>' +
            '                <th title="Click to sort by unit of measurement." alt="Click to sort by unit of measurement.">UoM</th>' +
            '                <th title="Click to sort by status name." alt="Click to sort by status name.">Status Name</th>' +
            '                <th title="Click to sort by part notes." alt="Click to sort by part notes.">Part Notes</th>' +
            '                <th title="Click to sort by BoM indicator." alt="Click to sort by BoM indicator.">Is BoM</th>' +
            '            </tr>' +
            '        </thead>' +
            '        <tbody></tbody>' +
            '    </table>' +
            '</div>';

}


回答6:

Came across this post some days ago*: -- seems like the example has a 'minor bug', occurring when "iTableCounter > newRowData.length": the implication is that the table 'stops expanding and contracting' on mouse-clicks.

Suggested solution: resetting the counter to '0'. -- if anyone would be able to refute/verify my suggestions (as JavaScript is not my language of experience), I would be more than grateful! ;)


(* If my post is a year too late, I apologize. However, given the great functionality which the example illustrates, I hope I'll be forgiven.)


Ole Kristian Ekseth, NTNU, Norway