javascript - jquery DataTables 父行和子行作为一条记录而不是两条记录发布到服务器

标签 javascript jquery asp.net-mvc datatables tablerow

我有一个问题,jquery DataTables 在调整大小(响应数据表)时创建父行和子行,我需要保存子行和父行的输入值并通过 ajax 发布到 Controller Action 。

响应式(调整大小)数据表:

Responsive DataTable

普通(未调整大小)数据表:

Normal DataTable

目前我正在使用这个 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>

Controller 发布的数据,索引 0 包含有效数据:

Controller posted data

代码片段:

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>

最佳答案

嗯,你真的不能。首先,DT 在 DOM 中注入(inject)和删除子行及其内容,使它们对简单的 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 内部结构。否则你只会得到返回默认值/原始值。

关于javascript - jquery DataTables 父行和子行作为一条记录而不是两条记录发布到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52313856/

相关文章:

javascript - 明确定义后图像不会改变

javascript - 在全屏视频上放置文本 (HTML5)

javascript - 如何在 Angular js 的选项卡集中的选项卡上启用延迟加载?

javascript - 如何使用 Javascript/JQuery 判断单选按钮是否处于未选中状态

javascript - 使用 jquery hide() 时,Firefox 不会隐藏 div

javascript - CheckBox 选中所有子复选框

javascript - jquery/javascript 没有在点击时获得值(value)

javascript - asp.net mvc 将 Json 对象从 View 传递到 Controller

c# - mvc中的用户角色和权限

asp.net-mvc - 如何在带有 razor 的 MVC 3 中使用正则表达式