如何将 sub-row 添加到数据表中的 child 行

How to add a sub-row to a child row in Datatables

我想在我借助 Datatable 制作的 table 上的辅助行中添加一个新的子关卡,这次我想生成一个新的 child 到我的次要行,我附加了一个 example 我想用它来解释并且我从 Datatables 中发现这是我想要得到的,我只是有点困惑通过此处使用的语法和我在当前代码中使用的语法。

我将用于构建数据table的Javascript代码附加到单个child行:

/* Formatting function for row details - modify as you need */
function format1(d) {
    // `d` is the original data object for the row
    console.log(d);      

      let tabla = `<table cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">
                    <thead>
                        <tr>
                            <th>
                                Date
                            </th>
                            <th>
                                No. Consecutivo
                            </th>
                        </tr>
                        </thead>
                        <tbody>`;
                            d.Consecutivo.forEach(f => {
                                tabla += `<tr>
                                <td>${f.Date}</td>
                                <td>${f.Consecutivo}</td>                             
                                </tr>`;
                            });
                       tabla += '</tbody></table>';
                       return tabla;

}

$(document).ready(function () {
   $('#example').dataTable( {
        responsive : true,
         ajax : {
             "type": 'POST',
             "url" : './test.php',  
             "dataType": 'JSON',             
             "cache": false,
             "data": {
                 'param' : 1,                       
             },
         },   
         columns: [          
             {
                 "className":      'details-control',
                 "orderable":      false,
                 "data":           null,
                 "defaultContent": ''
             },
             { "data" : "PurchaseOrder" },
             { "data" : "DatePurchaseOrder" },
             { "data" : "Total"},
             { "data" : "Currency" },
             { "data" : "Status" },                  
        ],
         order : [[1, 'desc']],
    } );

    
    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
      var tr = $(this).closest('tr');
        var row = $('#example').DataTable().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(format1(row.data())).show();
            tr.addClass('shown');
        }
    });
}); 

如果有人能就此主题给我一些指导,我将不胜感激。

更新 1:

看到有些人对我的问题的目的有点困惑,我不厌其烦地手工制作了一个小例子来说明我想要达到的目的。

我再解释一下,PurchaseOrder所在的header是parent行,第号。 Consecutivo header 是 parent PurchaseOrder 行和 Date [=106] 的子行=] 是 号的 child 行。连续

更新二:

在搜索和搜索文档之间我遇到了另一个 example,但它仍然没有给我一个更清晰的想法,我不知道是否有必要修改我正在使用的代码和使其适应我在示例中发现的内容或我正在使用的代码。我计划的可以完成。

更新 3:

再改进一下代码,我已经到了可以找到展开第二行 child 的按钮的地步,但是当点击它时,它并没有展开。我附上一个例子并分享代码已经有点改进:

首先在 format1() 函数中,我将 table 和 return 创建为 jQuery 数组。

当我操作“child行”(child table)时,我在显示时填充并激活数据表,在隐藏时销毁。

/* Formatting function for row details - modify as you need */
    function format1(d) {
        // `d` is the original data object for the row
        console.log(d);      
    
          let tabla = `<table id="tb-${d.PurchaseOrder}" cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">
                        <thead>
                            <tr>
                            <th>
                                No. Consecutivo
                            </th>
                                <th>
                                    Date
                                </th>
                            </tr>
                            </thead>
                            <tbody>
                            </tbody>
                            </table>`;
                            return $(tabla).toArray();                        
    }

    $(document).ready(function () {
       $('#example').dataTable( {
            responsive : true,
             ajax : {
                 "type": 'POST',
                 "url" : './test.php',  
                 "dataType": 'JSON',             
                 "cache": false,
                "data": {
                     'param' : 1,                       
                 },
             },    
             columns: [          
                 {
                     "className":      'details-control',
                     "orderable":      false,
                     "data":           null,
                     "defaultContent": ''
                 },
                 { "data" : "PurchaseOrder" },
                 { "data" : "DatePurchaseOrder" },
                 { "data" : "Total"},
                 { "data" : "Currency" },
                 { "data" : "Status" },                   
            ],
             order : [[1, 'desc']],
        } );
    
        
        // Add event listener for opening and closing details
        $('#example tbody').on('click', 'td.details-control', function () {
          let tr = $(this).closest('tr');
            let row = $('#example').DataTable().row(tr);
    
            let rowData = row.data();
    
            let tbId = `#tb-${rowData.PurchaseOrder}`;
    
            if (row.child.isShown()) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
    
                $(tbId).DataTable().destroy();
            }
            else {
                // Open this row
                row.child(format1(rowData)).show();
    
                $(tbId).DataTable({                
                    data: rowData.Consecutivo,
                "searching": false,
                "bPaginate": false,
                "info" : false,
    
                    columns: [
                    {
                        "className": 'details-control1',
                        "orderable": false,
                        "data": null,
                        "defaultContent": ''
                    }, 
                        
                        { data: 'Consecutivo' },
                        { data: 'Date' },
                    ],
    
                });

$(tbId).on('click', 'td.details-control', function(){
                var tr = $(this).closest('tr');
                var row = $('#example').DataTable().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(format1(row.data())).show();
                    tr.addClass('shown');
                } 
            });
                
                tr.addClass('shown');
            }
        });

如您所见,我仍然找不到 DateNo 的女儿。 Consecutivo,正如我在之前对此问题的更新中所解释的那样。

更新四:

正如一些评论所说,我在此处添加数据源以及 html 和 css。

/* Formatting function for row details - modify as you need */
    function format1(d) {
        // `d` is the original data object for the row
        console.log(d);      
    
          let tabla = `<table id="tb-${d.PurchaseOrder}" cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">
                        <thead>
                            <tr>
                            <th>
                                No. Consecutivo
                            </th>
                                <th>
                                    Date
                                </th>
                            </tr>
                            </thead>
                            <tbody>
                            </tbody>
                            </table>`;
                            return $(tabla).toArray();                        
    }

    $(document).ready(function () {
       $('#example').dataTable( {
            responsive : true,
             ajax : {
                 "type": 'POST',
                 "url" : './test.php',  
                 "dataType": 'JSON',             
                 "cache": false,
                "data": "data": [
             [
                "789",
              "28/04/2021",
              "0",
              "USD",
              "Delivered"               
             ],
             [
                "790",
              "27/04/2021",
              "0",
              "USD",
              "In wait"               
             ],
             [
                "791",
              "28/04/2021",
              "0",
              "USD",
              "Delivered"               
             ],
             [
                "792",
              "28/04/2021",
              "0",
              "USD",
              "Delivered"               
             ],
             ]
             },    
             columns: [          
                 {
                     "className":      'details-control',
                     "orderable":      false,
                     "data":           null,
                     "defaultContent": ''
                 },
                 { "data" : "PurchaseOrder" },
                 { "data" : "DatePurchaseOrder" },
                 { "data" : "Total"},
                 { "data" : "Currency" },
                 { "data" : "Status" },                   
            ],
             order : [[1, 'desc']],
        } );
    
        
        // Add event listener for opening and closing details
        $('#example tbody').on('click', 'td.details-control', function () {
          let tr = $(this).closest('tr');
            let row = $('#example').DataTable().row(tr);
    
            let rowData = row.data();
    
            let tbId = `#tb-${rowData.PurchaseOrder}`;
    
            if (row.child.isShown()) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
    
                $(tbId).DataTable().destroy();
            }
            else {
                // Open this row
                row.child(format1(rowData)).show();
    
                $(tbId).DataTable({                
                    data: rowData.Consecutivo,
                "searching": false,
                "bPaginate": false,
                "info" : false,
    
                    columns: [
                    {
                        "className": 'details-control1',
                        "orderable": false,
                        "data": null,
                        "defaultContent": ''
                    }, 
                        
                        { data: 'Consecutivo' },
                        { data: 'Date' },
                    ],
    
                });

$(tbId).on('click', 'td.details-control', function(){
                var tr = $(this).closest('tr');
                var row = $('#example').DataTable().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(format1(row.data())).show();
                    tr.addClass('shown');
                } 
            });
                
                tr.addClass('shown');
            }
        });
td.details-control {
            background: url(https://www.datatables.net/examples/resources/details_open.png) no-repeat center center;
            cursor: pointer;
            width: 30px;
            transition: .5s;
        }

        tr.shown td.details-control {
            background: url(https://www.datatables.net/examples/resources/details_close.png) no-repeat center center;
            width: 30px;
            transition: .5s;
        }
<link href="https://cdn.datatables.net/buttons/1.5.4/css/buttons.dataTables.min.css" rel="stylesheet"/>
    <link href="https://cdn.datatables.net/responsive/2.2.3/css/responsive.dataTables.min.css" rel="stylesheet"/>
    <link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>


    <section class="content">
             
              <div class="row">
                    <div class="col-xs-12">
                        <div class="box">
                            <div class="box-header">
                            <h3 class="box-title"></h3>
                            </div>
                            <div id="box-body" style="padding: 0px 10px 10px 10px;">  
                                <table id="example" class="table table-bordered table-hover">
                                    <thead>
                                        <tr>  
                                            <th></th>                
                                            <th>PurchaseOrder</th>
                                            <th>DatePurchaseOrder</th>
                                            <th>Total</th>
                                            <th>Currency</th>
                                            <th>Status</th>      
                                        </tr>              
                                    </thead>
                                </table>        
                            </div>             
                        </div>
                    </div>
              </div>

更新 5:

在 ajax 调用中,我使用以下语句,其中我使用 console.log 通过 ajax

获取响应
$(document).ready(function () {
   $('#example').dataTable( {
        responsive : true,
         ajax : {
             "type": 'POST',
             "url" : './test.php',  
             "dataType": 'JSON',             
             "cache": false,
            "data": {
                 function (d) { 
                     console.log(d); 
                    }       
             },
         },

但是在使用 console.log 时,我在控制台中收到以下消息

undefined
          

一种选择是将 child 行创建为数据表。然后为 child 数据表创建第二个格式函数。你可以从这个开始 blog to see how to create a child Datatable. You can ignore the Editor configuration. Also take a look at this example from this thread.

parent 数据表不知道 child 行和数据表 API 的内容,例如 row().child()。 show() (here) 不可用。如果您不希望 child 成为数据表,那么您将需要创建代码来显示 sub-child 行。

我发现了一些问题:

  • 在您的 format1 函数中您只声明了两列,但在数据中table您尝试填充三列
  • 您为内部数据table提供的数据只是 rowData['Consecutivo'] 的值,即“1000”,但数据table 期望数据是一个数组对象;因此,您应该提供用方括号括起来的 rowData 对象:[rowData]
  • 每次单击绿色按钮,都会为第三次单击声明一个新的事件处理程序 table;因此你应该在销毁内部数据table
  • 之前用off('click')关闭它
  • 文档准备功能未关闭(示例中);因此我添加了 });
  • 主数据中的
  • responsive : truetable隐藏状态栏;因此我删除了它
  • class details-control1 未在 css 中定义,因此没有像 details-control 这样的可见按钮;因此我删除了最后一个字符 1 尽管按钮没有功能因为似乎没有更深的嵌套数据显示在第二级数据 table (至少提到了 none在问题中)

由于 ajax 调用在堆栈片段中不起作用,我硬编码了我可以在您的示例图像中看到的数据(如 purchase_data)并想象更多“No. Consecutivo”和其他三个采购订单的“日期”值。所以我替换了那个例子

ajax : {
    "type": 'POST',
    "url" : './test.php',  
    "dataType": 'JSON',             
    "cache": false,
    "data": {
        'param' : 1,                       
    },
}, 

data: purchase_data,

工作示例:

var purchase_data = [
    {
        PurchaseOrder: 789,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 999,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 790,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "In Wait",
        Consecutivo: 1000,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 791,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1001,
        Date: "27/04/2021"
    }, {
        PurchaseOrder: 792,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1002,
        Date: "27/04/2021"
    },
];

/* Formatting function for row details - modify as you need */
function format1(d) {
    // `d` is the original data object for the row
    console.log(d);      

    let tabla = `<table id="tb-${d.PurchaseOrder}" cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">
                    <thead>
                        <tr>
                            <th></th>
                            <th>
                                No. Consecutivo
                            </th>
                            <th>
                                Date
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>`;
                    
    return $(tabla).toArray();                        
}

$(document).ready(function () {


    $('#example').DataTable({
        data: purchase_data,  
        columns: [          
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            { "data" : "PurchaseOrder" },
            { "data" : "DatePurchaseOrder" },
            { "data" : "Total"},
            { "data" : "Currency" },
            { "data" : "Status" }               
        ],
        order : [[1, 'desc']]
    });

    
    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
    
        let tr = $(this).closest('tr');
        let row = $('#example').DataTable().row(tr);
        let rowData = row.data();
        let tbId = `#tb-${rowData.PurchaseOrder}`;

        if (row.child.isShown()) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');

            $(tbId).DataTable().destroy();
        }
        else {
            // Open this row
            row.child(format1(rowData)).show();

            $(tbId).DataTable({                
                data: [rowData],
                "searching": false,
                "bPaginate": false,
                "info" : false,

                columns: [
                    {
                        "className": 'details-control',
                        "orderable": false,
                        "data": null,
                        "defaultContent": ''
                    }, 
                    { data: 'Consecutivo' },
                    { data: 'Date' }
                ]
            });
            
            tr.addClass('shown');
        }
        
    });
    
    
});
.content {
    padding: 15px;
}

td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_open.png) no-repeat center center;
    cursor: pointer;
    width: 30px;
    transition: .5s;
}

tr.shown td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_close.png) no-repeat center center;
    width: 30px;
    transition: .5s;
}

table.dataTable td table.dataTable,
table.dataTable td table.dataTable * {
    border: none;
}
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

<section class="content">
             
    <div class="row">
        <div class="col-xs-12">
            <div class="box">
                <div class="box-header">
                    <h3 class="box-title">Whosebug Test</h3>
                </div>
                <div id="box-body" style="padding: 0px 10px 10px 10px;">  
                    <table id="example" class="table table-bordered table-hover">
                        <thead>
                            <tr>  
                                <th></th>                
                                <th>PurchaseOrder</th>
                                <th>DatePurchaseOrder</th>
                                <th>Total</th>
                                <th>Currency</th>
                                <th>Status</th>      
                            </tr>              
                        </thead>
                    </table>        
                </div>             
            </div>
        </div>
    </div>
    
</section>


顺便说一句:如果真的没有更深层次的嵌套数据(如图所示),则不需要第二个数据table,因为内部table只有一行.所以一个普通的 html table 就足够了,可以用 format1 函数来制作,因为它已经有了 rowData.

工作示例:

var purchase_data = [
    {
        PurchaseOrder: 789,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 999,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 790,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "In Wait",
        Consecutivo: 1000,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 791,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1001,
        Date: "27/04/2021"
    }, {
        PurchaseOrder: 792,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1002,
        Date: "27/04/2021"
    },
];

var tabla;

$(document).ready(function () {

    /* Formatting function for row details - modify as you need */
    function format(d) {
        // `d` is the original data object for the row

        let tabla = '<table id="tb-' + d.PurchaseOrder + '" cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">' + 
                        '<thead>' + 
                            '<tr>' + 
                                '<th>No. Consecutivo</th>' + 
                                '<th>Date</th>' + 
                            '</tr>' + 
                        '</thead>' + 
                        '<tbody>' + 
                            '<tr>' + 
                                '<td>' + d.Consecutivo + '</td>' + 
                                '<td>' + d.Date + '</td>' + 
                            '</tr>' + 
                        '</tbody>' + 
                    '</table>';
        return $(tabla).toArray();                        
    }

    var table = $('#example').DataTable({
        data: purchase_data,
        columns: [          
            {
                className:      'details-control',
                orderable:      false,
                data:           null,
                defaultContent: ''
            },
            { data: "PurchaseOrder" },
            { data: "DatePurchaseOrder" },
            { data: "Total"},
            { data: "Currency" },
            { data: "Status" }
        ],
        order: [[1, 'desc']]
    });

    
    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
    
        let tr = $(this).closest('tr');
        let row = table.row(tr);
        let rowData = row.data();
        let tbId = '#tb-' + rowData.PurchaseOrder;
        
        if (row.child.isShown()) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');

            $(tbId).DataTable().destroy();
        }
        else {
            // Open this row
            row.child(format(rowData)).show();
            
            tr.addClass('shown');
        }
        
    });
    
    
});
.content {
    padding: 15px;
}

td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_open.png) no-repeat center center;
    cursor: pointer;
    width: 30px;
    transition: .5s;
}

tr.shown td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_close.png) no-repeat center center;
    width: 30px;
    transition: .5s;
}

table.dataTable td table,
table.dataTable td table * {
    border: none !important;
}
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

<section class="content">
             
    <div class="row">
        <div class="col-xs-12">
            <div class="box">
                <div class="box-header">
                    <h3 class="box-title">Whosebug Test</h3>
                </div>
                <div id="box-body" style="padding: 0px 10px 10px 10px;">  
                    <table id="example" class="table table-bordered table-hover">
                        <thead>
                            <tr>  
                                <th></th>                
                                <th>PurchaseOrder</th>
                                <th>DatePurchaseOrder</th>
                                <th>Total</th>
                                <th>Currency</th>
                                <th>Status</th>      
                            </tr>              
                        </thead>
                    </table>        
                </div>             
            </div>
        </div>
    </div>
    
</section>


如果您希望内部 table 分成两个嵌套的内部 table,只有一行和一个键值对(如第一张图片所示),您需要第二个格式函数。

工作示例:

var purchase_data = [
    {
        PurchaseOrder: 789,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 999,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 790,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "In Wait",
        Consecutivo: 1000,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 791,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1001,
        Date: "27/04/2021"
    }, {
        PurchaseOrder: 792,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1002,
        Date: "27/04/2021"
    },
];

/* Formatting function for row details - modify as you need */
function format1(d) {
    // `d` is the original data object for the row  

    let tabla = `<table id="tb-${d.PurchaseOrder}" cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">
                    <thead>
                        <tr>
                            <th></th>
                            <th>
                                No. Consecutivo
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>`;
                    
    return $(tabla).toArray();                        
}

function format2(d) {
    // `d` is the original data object for the row

    let tabla = `<table id="tb-${d.Consecutivo}" cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">
                    <thead>
                        <tr>
                            <th></th>
                            <th>
                                Date
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td></td>
                            <td>
                                ${d.Date}
                            </td>
                        </tr>
                    </tbody>
                </table>`;
                    
    return $(tabla).toArray();                        
}

$(document).ready(function () {


    $('#example').DataTable({
        data: purchase_data,  
        columns: [          
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            { "data" : "PurchaseOrder" },
            { "data" : "DatePurchaseOrder" },
            { "data" : "Total"},
            { "data" : "Currency" },
            { "data" : "Status" }               
        ],
        order : [[1, 'desc']]
    });

    
    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
    
        let tr = $(this).closest('tr');
        let row = $('#example').DataTable().row(tr);
        let rowData = row.data();
        let tbId = `#tb-${rowData.PurchaseOrder}`;

        if (row.child.isShown()) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
            
            $(tbId).off('click');
            $(tbId).DataTable().destroy();
        }
        else {
            // Open this row
            row.child(format1(rowData)).show();

            $(tbId).DataTable({                
                data: [rowData],
                "searching": false,
                "bPaginate": false,
                "info" : false,

                columns: [
                    {
                        "className": 'details-control1',
                        "orderable": false,
                        "data": null,
                        "defaultContent": ''
                    }, 
                    { data: 'Consecutivo' }
                ]
            });
            
            tr.addClass('shown');
    
            // Add event listener for opening and closing details
            $(tbId).on('click', 'td.details-control1', function () {
                let tr = $(this).closest('tr');
                let row = $(tbId).DataTable().row(tr);
                let rowData = row.data();

                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    
                    tr.removeClass('shown');
                }
                else {
                    // Open this row
                    row.child(format2(rowData)).show();
                    
                    tr.addClass('shown');
                }
            });
        }
        
    });
    
    
});
.content {
    padding: 15px;
}

td.details-control1, 
td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_open.png) no-repeat center center;
    cursor: pointer;
    width: 30px;
    transition: .5s;
}

tr.shown td.details-control1, 
tr.shown td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_close.png) no-repeat center center;
    width: 30px;
    transition: .5s;
}

table.dataTable td table,
table.dataTable td table * {
    border: none !important;
}
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

<section class="content">
             
    <div class="row">
        <div class="col-xs-12">
            <div class="box">
                <div class="box-header">
                    <h3 class="box-title">Whosebug Test</h3>
                </div>
                <div id="box-body" style="padding: 0px 10px 10px 10px;">  
                    <table id="example" class="table table-bordered table-hover">
                        <thead>
                            <tr>  
                                <th></th>                
                                <th>PurchaseOrder</th>
                                <th>DatePurchaseOrder</th>
                                <th>Total</th>
                                <th>Currency</th>
                                <th>Status</th>      
                            </tr>              
                        </thead>
                    </table>        
                </div>             
            </div>
        </div>
    </div>
    
</section>


如果内部 table 与主要 table 一样宽(如第一张图片中建议的那样)对您来说很重要,则需要更多 css .

工作示例:

var purchase_data = [
    {
        PurchaseOrder: 789,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 999,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 790,
        DatePurchaseOrder: "27/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "In Wait",
        Consecutivo: 1000,
        Date: "26/04/2021"
    }, {
        PurchaseOrder: 791,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1001,
        Date: "27/04/2021"
    }, {
        PurchaseOrder: 792,
        DatePurchaseOrder: "28/04/2021",
        Total: "0",
        Currency: "USD",
        Status: "Delivered",
        Consecutivo: 1002,
        Date: "27/04/2021"
    },
];

/* Formatting function for row details - modify as you need */
function format1(d) {
    // `d` is the original data object for the row  

    let tabla = `<table id="tb-${d.PurchaseOrder}" cellpadding="5" cellspacing="0" style="width: 100%;">
                    <thead>
                        <tr>
                            <th class="details"></th>
                            <th>
                                No. Consecutivo
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>`;
                    
    return $(tabla).toArray();                        
}

function format2(d) {
    // `d` is the original data object for the row

    let tabla = `<table id="tb-${d.Consecutivo}" cellpadding="5" cellspacing="0" style="width: 100%; border-collapse: separate;">
                    <thead>
                        <tr>
                            <th class="details"></th>
                            <th>
                                Date
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td></td>
                            <td>
                                ${d.Date}
                            </td>
                        </tr>
                    </tbody>
                </table>`;
                    
    return $(tabla).toArray();                        
}

$(document).ready(function () {


    $('#example').DataTable({
        data: purchase_data,  
        columns: [          
            {
                className:      'details-control',
                orderable:      false,
                data:           null,
                defaultContent: ''
            },
            { data: "PurchaseOrder" },
            { data: "DatePurchaseOrder" },
            { data: "Total"},
            { data: "Currency" },
            { data: "Status" }               
        ],
        order: [[1, 'desc']]
    });

    
    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
    
        let tr = $(this).closest('tr');
        let row = $('#example').DataTable().row(tr);
        let rowData = row.data();
        let tbId = `#tb-${rowData.PurchaseOrder}`;

        if (row.child.isShown()) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
            
            $(tbId).off('click');
            $(tbId).DataTable().destroy();
        }
        else {
            // Open this row
            row.child(format1(rowData)).show();

            $(tbId).DataTable({                
                data: [rowData],
                searching: false,
                bPaginate: false,
                info: false,

                columns: [
                    {
                        className: 'details details-control1',
                        orderable: false,
                        data: null,
                        defaultContent: ''
                    }, 
                    { data: 'Consecutivo' }
                ],
                order: []
            });
            
            tr.addClass('shown');
    
            // Add event listener for opening and closing details
            $(tbId).on('click', 'td.details-control1', function () {
                let tr = $(this).closest('tr');
                let row = $(tbId).DataTable().row(tr);
                let rowData = row.data();

                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    
                    tr.removeClass('shown');
                }
                else {
                    // Open this row
                    row.child(format2(rowData)).show();
                    
                    tr.addClass('shown');
                }
            });
        }
        
    });
    
    
});
.content {
    padding: 15px;
}

.details {
    width: 16px;
}

table.dataTable tbody td[colspan] {
    padding: 0px;
    border: none;
}

table.dataTable.no-footer {
    border: none;
}

table.dataTable tbody th, table.dataTable tbody td {
    border-bottom-color: #dee2e6;
}

td.details-control1, 
td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_open.png) no-repeat center center;
    cursor: pointer;
    transition: .5s;
}

tr.shown td.details-control1, 
tr.shown td.details-control {
    background: url(https://www.datatables.net/examples/resources/details_close.png) no-repeat center center;
    transition: .5s;
}

table.dataTable td table {
    width: 100%;
}
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

<section class="content">
             
    <div class="row">
        <div class="col-xs-12">
            <div class="box">
                <div class="box-header">
                    <h3 class="box-title">Whosebug Test</h3>
                </div>
                <div id="box-body" style="padding: 0px 10px 10px 10px;">  
                    <table id="example" class="table table-bordered table-hover">
                        <thead>
                            <tr>  
                                <th></th>                
                                <th>PurchaseOrder</th>
                                <th>DatePurchaseOrder</th>
                                <th>Total</th>
                                <th>Currency</th>
                                <th>Status</th>      
                            </tr>              
                        </thead>
                    </table>        
                </div>             
            </div>
        </div>
    </div>
    
</section>