【发布时间】:2021-07-14 00:54:09
【问题描述】:
我有一个使用子行的表,其中每一行都是可展开/可折叠的,但我的父行会有重复的数据。
我想对我的子行或子行进行分组,因为它们在官方 Datatables 文档中被称为,我有下表,其中父行中有采购订单、采购订单日期、货币和状态列。
如果你看,我有 3 个采购订单对应于这个例子中相同的标识符是 258,但是每个采购订单都包含一个带有不同信息的辅助行,该信息是 Receipt Date,No . 发票、项目代码和描述。
+-----------------------------------------------------------------------+
| | Purchase Order | Purchase Order Date |Currency| Status |
+----+------------------+--------------------------+--------+-----------+
| + | 258 | 06/01/2020 | USD | Delivered |
+------+---------+------------+--------------------+-------------+------+
| Receipt Date | No. Invoice | Code Item | Description |
+------+---------+-----------+---------------------+-------------+------+
| 07/01/2020 | 617 | CA0033 | CT |
+-----------------------------------------------------------------------+
| + | 258 | 06/01/2020 | USD | Delivered |
+-----------------------+--------------------------+--------+-----------+
| Receipt Date | No. Invoice | Code Item | Description |
+-----------------------+-------------+-----------------+---------------+
| 14/01/2020 | 620 | CA0036 | CTR |
+-----------------------+-------------+-----------------+---------------+
| + | 258 | 06/01/2020 | USD | Delivered |
+-----------------------+--------------------------+--------+-----------+
| Receipt Date | No. Invoice | Code Item | Description |
+-----------------------+-------------+-----------------+---------------+
| 16/01/2020 | 626 | CC0048 | CTY |
+-----------------------+-------------+-----------------+---------------+
在不重复采购订单的情况下,我想要实现的是按如下方式对辅助行进行分组。
+-----------------------------------------------------------------------+
| | Purchase Order | Purchase Order Date |Currency| Status |
+----+------------------+--------------------------+--------+-----------+
| + | 258 | 06/01/2020 | USD | Delivered |
+------+---------+------------+-------------------+-------------+-------+
| Receipt Date | No. Invoice | Code Item | Description |
+------+---------+-----------+--------------------+-------------+-------+
| 07/01/2020 | 617 | CA0033 | CT |
+-----------------------+-------------+-----------------+---------------+
| 14/01/2020 | 620 | CA0036 | CTR |
+-----------------------+-------------+-----------------+---------------+
| 16/01/2020 | 626 | CC0048 | CTY |
+-----------------------+-------------+-----------------+---------------+
如果您现在查看采购订单,它包含组合在一起的相同 3 个订单的信息,这就是我想要的。
以下是我用来构建表格的 AJAX 调用代码。
/* Formatting function for row details - modify as you need */
function format(d) {
// `d` is the original data object for the row
console.log(d);
return '<table cellpadding="5" cellspacing="0" style="border-collapse: separate; border-spacing: 40px 5px;">' +
'<tr>' +
'<td><strong>Receipt Date: </strong></td>' + '<td><strong>No. Invoice:<strong></td>' + '<td><strong>Code Item:<strong></td>' + '<td><strong>Description:</strong></td>' +
'</tr>' +
'<tr>' +
'<td>' + d.ReceiptDate + '</td>' + '<td>' + d.Invoice+ '</td>' + '<td>' + d.CodeItem+ '</td>' + '<td>' + d.Description + '</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
$('#example').dataTable( {
responsive : true,
ajax : {
"type": 'POST',
"url" : './test.php',
"dataType": 'JSON',
"cache": false,
"data": {
'param' : 1,
},
},
language : {
"lengthMenu": "Mostrar _MENU_ registros",
"zeroRecords": "No se encontró nada",
"info": "Mostrando del _START_ al _END_ de un total de _TOTAL_",
"infoEmpty": "No hay registros",
"emptyTable": "No hay datos para mostrar",
"loadingRecords": "Cargando...",
"processing": "Procesando...",
"search": "Buscar:",
"infoFiltered": "(filtrado de un total de _MAX_ registros)",
"paginate": {
"first": "Primera",
"last": "Última",
"next": "Siguiente",
"previous": "Anterior"
}
},
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data" : "PurchaseOrder" },
{ "data" : "PurcharOrderDate" },
{ "data" : "Currency" },
{ "data" : "Status" }
],
order : [[1, 'desc']]
} );
// Add event listener for opening and closing details
$('#example').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(format(row.data())).show();
tr.addClass('shown');
}
});
});
查阅Datatables 文档,它有一个RowGroup 扩展名,但我不知道它们是否可以分组为子行或子行。如果您能帮助我找到解决此问题的方法,我将不胜感激。
更新:
下面我按照评论中的要求对 test.php 提供的 JSON 响应进行非规范化,这样做的目的是为了访问每个子行所需的所有数据。
[
{
"Purchase Order": 949,
"Purchase Order Date": "20/11/2019",
"Receipt Date": "12/12/2019",
"No. Invoice": 448,
"Code Item": "CC0048",
"Description": "CTR",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 949,
"Purchase Order Date": "20/11/2019",
"Receipt Date": "13/12/2019",
"No. Invoice": 448,
"Code Item": "CC0048",
"Description": "CTR",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 949,
"Purchase Order Date": "20/11/2019",
"Receipt Date": "14/12/2019",
"No. Invoice": 448,
"Code Item": "CC0048",
"Description": "UBC",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 949,
"Purchase Order Date": "20/11/2019",
"Receipt Date": "15/12/2019",
"No. Invoice": 448,
"Code Item": "CC0048",
"Description": "UBC",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 258,
"Purchase Order Date": "05/12/2019",
"Receipt Date": "17/12/2019",
"No. Invoice": 451,
"Code Item": "CA0033",
"Description": "CTY",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 258,
"Purchase Order Date": "05/12/2019",
"Receipt Date": "18/12/2019",
"No. Invoice": 451,
"Code Item": "CA0033",
"Description": "CTY",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 258,
"Purchase Order Date": "05/12/2019",
"Receipt Date": "19/12/2019",
"No. Invoice": 452,
"Code Item": "CA0033",
"Description": "CTY",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 258,
"Purchase Order Date": "05/12/2019",
"Receipt Date": "20/12/2019",
"No. Invoice": 452,
"Code Item": "CA0033",
"Description": "CTY",
"Status": "Delivered",
"Currency": "USD"
},
{
"Purchase Order": 258,
"Purchase Order Date": "05/12/2019",
"Receipt Date": "21/12/2019",
"No. Invoice": 452,
"Code Item": "CA0033",
"Description": "CTY",
"Status": "Delivered",
"Currency": "USD"
}
]
重要的是要记住,作为父行,我需要采购订单、采购订单日期、货币和状态,而作为子行,我需要找到收货日期、发票编号、代码项目和描述。
更新 2:
我添加了 php 代码来为我的问题提供更多指导。
Test.php
<?php
header('Content-Type: text/html; charset=utf-8');
$param = $_POST['param'];
switch($param) {
case '1':
$query = array();
include './db/conecct.php';
$sql = "select PURCHID as 'PurchaseOrder',
CREATEDDATETIME as 'PurchaseOrderDate',
MONEDA as 'Currency',
INVOICEDATE as 'ReceiptDate',
ITEMID as 'CodeItem',
FACTURA as 'No. Invoice',
NAMEALIAS as 'Description',
PURCHSTATUS as 'Status'
FROM PP_FACTURAS
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
while( $row = sqlsrv_fetch_array($stmt) ) {
//print_r($row);
$record = array(
"PurchaseOrder" => $row['PurchaseOrder'],
"PurchaseOrderDate" => $row['PurchaseOrderDate']->format('d/m/Y'),
"Currency" => $row['Currency'],
"Status" => $row['Status'],
"PurchaseOrderDate" => $row['PurchaseOrderDate'] != null ? $row['PurchaseOrderDate']->format('d/m/Y'):"",
"No. Invoice" => utf8_encode ($row['No. Invoice']),
"CodeItem" => utf8_encode ($row['CodeItem']),
"Description" => utf8_encode ($row['Description']),
);
array_push($query, $record);
}
sqlsrv_free_stmt( $stmt);
sqlsrv_close($conn);
$json = array(
"success"=> count($query) > 0 ? true : false,
"data"=>$query
);
echo json_encode($json);
break;
更新 3:
尝试回答,现在我在控制台中收到以下错误:
Uncaught TypeError: originalJson is not iterable
我根据答案附上我支持自己的代码:
/* Formatting function for row details - modify as you need */
function format(d) {
// `d` is the original data object for the row
console.log(d);
var tableHtml = '<table><thead><tr><th>Receipt Date</th><th>Invoice No.</th><th>Item Code</th><th>Description</th></tr></thead>';
tableHtml = tableHtml + '<tbody>';
var rowHtml = '';
for (const rowData of d.details){
rowHtml = rowHtml + '<tr><td>' + rowData.ReceiptDate + '</td><td>' + rowData.Invoice + '</td><td>' + rowData.CodeItem + '</td><td>' + rowData.Description + '</td></tr>';
}
tableHtml = tableHtml + rowHtml + '</tbody></table>';
return tableHtml;
}
function denormalize(originalJson) {
let denormalizedMap = new Map();
for (const element of originalJson) {
let headerInfo = (({
PurchaseOrder,
PurcharOrderDate,
Currency,
Status
}) => ({
PurchaseOrder,
PurcharOrderDate,
Currency,
Status
}))(element);
headerInfo.details = [];
let detailLine = (({
ReceiptDate,
Invoice,
CodeItem,
Description
}) => ({
ReceiptDate,
Invoice,
CodeItem,
Description
}))(element);
if (! denormalizedMap.has(element.PurchaseOrder)) {
denormalizedMap.set(element.PurchaseOrder, headerInfo);
}
denormalizedMap.get(element.PurchaseOrder).details.push(detailLine);
}
let denormalizeSource = Array.from(denormalizedMap.values());
return denormalizeSource;
}
$(document).ready(function () {
$('#example').dataTable( {
responsive : true,
ajax : {
"type": 'POST',
"url" : './test.php',
"dataType": 'JSON',
"cache": false,
"dataSrc" : function (json){
console.log(json);
return denormalize(json);
},
},
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data" : "PurchaseOrder" },
{ "data" : "PurcharOrderDate" },
{ "data" : "Currency" },
{ "data" : "Status" }
],
order : [[1, 'desc']],
} );
// Add event listener for opening and closing details
$('#example').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(format(row.data())).show();
tr.addClass('shown');
}
});
});
【问题讨论】:
-
您可以将 DataTables 的“子”行视为已经是父行的源数据对象一部分的额外数据。在构建子对象时,您只能访问该一个源对象(因此代码中的注释:“
d是原始数据对象for the row”)。您可以首先对test.php提供的 JSON 响应进行非规范化(或使用 JavaScript 对其进行后处理),以访问每个子行所需的所有数据。然后,d将包含您需要的所有数据。这也同时解决了“重复父行”问题(没有重复的 PO 行)。 -
@andrewjames 您可以查看我的上次更新添加我处理的 JSON 文件,以便您可以访问每行中的数据
-
我认为这里对“非规范化”的含义存在误解。您问题中的示例数据每个唯一的采购订单号没有一个对象。每个唯一的 PO 仍然有许多对象。所以,这对你没有帮助。我不使用 PHP,但如果有帮助,我可以向您展示使用 JS 的意思。
-
@andrewjames 我明白了,告诉我你说的 JS 是什么意思,这对我有很大帮助
标签: javascript jquery ajax datatables