jquery DataTables 父行和子行作为一条记录而不是两条记录发布到服务器
Posted
技术标签:
【中文标题】jquery DataTables 父行和子行作为一条记录而不是两条记录发布到服务器【英文标题】:jquery DataTables parent and child rows posted to server as one record instead of two 【发布时间】:2019-02-18 04:44:33 【问题描述】:我有一个问题,jquery DataTables
在调整大小时创建父子行(响应式 DataTable),我需要保存子行以及父行的输入值并通过 ajax 发布到控制器操作。
响应式(调整大小)数据表:
普通(未调整大小)数据表:
目前我正在使用这个 jquery 函数将数据发布到服务器:
$('#SaveItemButton').click(function (e)
var arr = [];
var rows = $('#ItemTable').find('tbody').find('tr');
console.log(rows.length);
$.each(rows, function (index, item)
var controls = $(this).find('input, select');
console.log(controls.length);
item =
ItemType: controls.eq(0).val(),
Unit: controls.eq(1).val(),
Quantity: controls.eq(2).val(),
Price: controls.eq(3).val(),
InvoiceDate: $('#InvoiceDate').val(),
TransferDate: $('#TransferDate').val(),
TransferPlace: $('#TransferPlace').val(),
InvoiceDescription: $('#InvoiceDescription').val()
;
arr.push(item);
);
$.ajax(
url: '/Item/Add',
data: JSON.stringify(arr),
contentType: 'application/json',
type: "POST",
dataType: "json",
success: function (result)
//alert(result);
,
error: function (errormessage)
);
return false;
);
但是当调整数据表的大小时,它会返回两行,然后将其发布到服务器。
我正在通过以下方式从表中检索行:
var rows = $('#ItemTable').find('tbody').find('tr');
如何将所有相关的父行和子行作为一行,以便我可以将该行发布到服务器?
父行示例:
<tr role="row" class="odd parent">
<td tabindex="0" style=""></td>
<td class="sorting_1"><input name="ItemType" class="form-control" type="text"></td>
<td style="display: none;"><select name="Unit" class="form-control defaultpicker"><option>dan</option><option>Komad</option><option>Sat</option>m<option>m2</option><option>m3</option><option>kg</option><option>lit</option><option>pak</option><option>reč</option></select></td>
<td style="display: none;"><input name="Quantity" class="form-control" type="number"></td>
<td style="display: none;"><input name="Price" class="form-control" type="text"></td>
<td style="display: none;"><input name="Total" class="form-control" type="text" readonly=""></td>
<td style="display: none;"><button type="submit" id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>
</td>
</tr>
子行示例:
<tr class="child">
<td class="child" colspan="2">
<ul data-dtr-index="0" class="dtr-details">
<li data-dtr-index="2" data-dt-row="0" data-dt-column="2">
<span class="dtr-title">Unit</span>
<span class="dtr-data">
<select name="Unit" class="form-control defaultpicker"><option>dan</option><option>Komad</option><option>Sat</option>m<option>m2</option><option>m3</option><option>kg</option><option>lit</option><option>pak</option><option>reč</option></select>
</span>
</li>
<li data-dtr-index="3" data-dt-row="0" data-dt-column="3">
<span class="dtr-title">Quantity</span>
<span class="dtr-data">
<input name="Quantity" class="form-control" type="number" value="3">
</span>
</li>
<li data-dtr-index="4" data-dt-row="0" data-dt-column="4">
<span class="dtr-title">Price</span>
<span class="dtr-data">
<input name="Price" class="form-control" type="text" value="1000">
</span>
</li>
<li data-dtr-index="5" data-dt-row="0" data-dt-column="5">
<span class="dtr-title">Total</span>
<span class="dtr-data">
<input name="Total" class="form-control" type="text" readonly="" value="">
</span>
</li>
<li data-dtr-index="6" data-dt-row="0" data-dt-column="6">
<span class="dtr-title"></span>
<span class="dtr-data">
<button type="submit" id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>
</span>
</li>
</ul>
</td>
</tr>
控制器发布数据,index 0
包含有效数据:
代码片段:
var table = $('#ItemTable').DataTable(
"dom": '<"toolbar">frtip',
"paging": true,
"pagingType": "full_numbers",
"searching": false,
// Solution to responsive table losing data
'columnDefs': [
'targets': [1, 2, 3, 4, 5, 6],
'render': function(data, type, row, meta)
if (type === 'display')
var api = new $.fn.dataTable.Api(meta.settings);
var $el = $('input, select, textarea', api.cell(
row: meta.row,
column: meta.col
).node());
var $html = $(data).wrap('<div/>').parent();
if ($el.prop('tagName') === 'INPUT')
$('input', $html).attr('value', $el.val());
if ($el.prop('checked'))
$('input', $html).attr('checked', 'checked');
else if ($el.prop('tagName') === 'TEXTAREA')
$('textarea', $html).html($el.val());
else if ($el.prop('tagName') === 'SELECT')
$('option:selected', $html).removeAttr('selected');
$('option', $html).filter(function()
return ($(this).attr('value') === $el.val());
).attr('selected', 'selected');
data = $html.html();
return data;
],
'responsive': true,
order: [1, 'asc']
);
// Solution to responsive table losing data
$('#ItemTable tbody').on('keyup change', '.child input, .child select, .child textarea', function(e)
var $el = $(this);
var rowIdx = $el.closest('ul').data('dtr-index');
var colIdx = $el.closest('li').data('dtr-index');
var cell = table.cell(
row: rowIdx,
column: colIdx
).node();
$('input, select, textarea', cell).val($el.val());
if ($el.is(':checked'))
$('input', cell).prop('checked', true);
else
$('input', cell).removeProp('checked');
);
$('#SaveItemButton').click(function()
var arr = [];
var rows = $('#ItemTable').find('tbody').find('tr');
console.log(rows.length);
$.each(rows, function(index, item)
var controls = $(this).find('input, select');
console.log(controls.length);
item =
ItemType: controls.eq(0).val(),
Unit: controls.eq(1).val(),
Quantity: controls.eq(2).val(),
Price: controls.eq(3).val(),
InvoiceDate: $('#InvoiceDate').val(),
TransferDate: $('#TransferDate').val(),
TransferPlace: $('#TransferPlace').val(),
InvoiceDescription: $('#InvoiceDescription').val()
;
arr.push(item);
);
$.ajax(
url: '/Item/Add',
data: JSON.stringify(arr),
contentType: 'application/json',
type: "POST",
dataType: "json",
success: function(result)
//alert(result);
,
error: function(errormessage)
);
return false;
);
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/responsive/2.2.3/css/responsive.dataTables.min.css" rel="stylesheet" />
<table id="ItemTable" class="table table-hover table-secondary dataTable no-footer dtr-inline" style="width: 100%;" role="grid" aria-describedby="ItemTable_info">
<thead>
<tr role="row">
<th></th>
<th>ItemType</th>
<th>Unit</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
<th></th>
</tr>
</thead>
<tbody>
<tr role="row" class="odd parent">
<td tabindex="0" style=""></td>
<td class="sorting_1"><input name="ItemType" class="form-control" type="text"></td>
<td style="">
<select name="Unit" class="form-control defaultpicker">
<option>value1</option>
<option>value2</option>
<option>value3</option>
<option>value4</option>
<option>value5</option>
<option>value6</option>
<option>value7</option>
<option>value8</option>
<option>value9</option>
</select>
</td>
<td style=""><input name="Quantity" class="form-control" type="number"></td>
<td style=""><input name="Price" class="form-control" type="text"></td>
<td style=""><input name="Total" class="form-control" type="text" readonly=""></td>
<td style=""><button type="submit" id="DeleteButton" data-id=""></button></td>
</tr>
</tbody>
</table>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/select/1.2.6/js/dataTables.select.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.2.3/js/dataTables.responsive.min.js"></script>
【问题讨论】:
您能否在您的帖子中添加一个示例,说明父行和子行中的数据是什么? 您不能使用相对选择器来获取带有class="child"
的行,它是带有class="parent"
的行的下一个兄弟吗?
@RyanWilson 看到上面的编辑。
@Dusan 那么看起来你根本不需要担心子行,所以只需检查一下是否有类为child
的行,如果有的话使用parent
类获取行并使用它们发布,否则使用tr
获取行。
您的子行似乎只是在重复父行中的一些表单控件(例如,您有 2 个 Quantity
输入 - 但在父行中,它位于隐藏列中并且它具有没有价值)
【参考方案1】:
嗯,你真的不能。起初 DT 向 DOM 注入和删除子行及其内容,使它们对简单的 jQuery 选择器不可见。您可以定位打开的子行,但仅此而已。
其次,您不能成对选择多个元素。例如,您可以拥有 $('tr.parent, tr.parent ~ tr.child')
或类似名称,但这将等于 $('tr')
。我会通过 API:
table.rows().every(function()
var $node = this.nodes().to$();
var item =
ItemType: $node.find('input[name=ItemType]').val(),
Unit: $node.find('select[name=Unit]').val(),
Quantity: $node.find('input[name=Quantity]').val(),
Price: $node.find('input[name=Price]').val(),
Total: $node.find('input[name=Total]').val(),
InvoiceDate: $('#InvoiceDate').val(),
TransferDate: $('#TransferDate').val(),
TransferPlace: $('#TransferPlace').val(),
InvoiceDescription: $('#InvoiceDescription').val()
;
arr.push(item)
)
完全未经测试。请参阅JQuery Datatables search within input and select,了解如何在表单控件更改时更新 DT 内部。否则你只会得到返回默认值/原始值。
【讨论】:
以上是关于jquery DataTables 父行和子行作为一条记录而不是两条记录发布到服务器的主要内容,如果未能解决你的问题,请参考以下文章
HTML:如何使用 AngularJs 填充第一行是父行和后续行是子行的行
PowerQuery - 主行和子行 - 基于公式或逻辑的另一行的参考值