DataTables detail row without nesting

2019-05-23 06:38发布

I'm trying to make a table with nested data inside. I want to have one set of column headers at the top of the table and have them carry through the entire table. To this end, I've started adapting the Row Details example for my needs. The code:

var table = this.$el.attr({
  'width': '100%',
  'class': 'table table-striped table-hover'
}).DataTable({
  data: data,
  autoWidth: true,
  paging: false,
  order: [[0,'asc']],
  columns: [
    {
      'width':15,
      'class':'details-control',
      'orderable':false,
      'data':null,
      defaultContent: '+'
    },
    {data:'term',title:'Item ID'},
    {data:'count',title:'Count'}
  ]
});

this.$el.find('tr.group').each(function(i){
  var $tr = $(this);
  var row = table.row($tr);
  console.log(row.data());
  row.child($.map(row.data().samples, function(sample){
    return $('<tr><td></td><td>Sample: '+sample.name+'</td></tr>');
   })).show();
});

However, this nests my generated rows within a single <tr colspan="4"> element, as follows:

<tbody>
  <tr>
    <td class="details-control">+</td>
    <td>659A</td>
    <td>12</td>
  </tr>
  <tr>
    <td colspan="4">
      <tr>
        <td></td>
        <td>659A-27</td>
      </tr>
    </td>
  </tr>
</tbody>

Because of the colspan element, my child rows aren't lining up with the parent rows. For instance, I want the blank <td> to line up with the details-control column in the large table, and the 659A-27 to line up with the Item ID column.

What would be the least-clumsy way to shed the extra <td colspan="4"><tr></tr></td> and have my child rows simply line up with the parent table?

Edit: from the documentation (emphasis mine):

The contents of the child rows are entirely independent of the main table (other than their position in the document). Ordering, searching etc applied to the table has no effect on the order of the child rows. Each child row is typically contains a single cell, which has a colspan attribute set to span the full table width, so the content of the cell covers the full table width. However, it is also possible to pass in a tr element which has multiple cells (one for each column in the table) to show the child row data in the same column structure as the main table.

It mentions that placing the child row into the parent's structure "is also possible" but does not describe how to achieve this, and as described above the intuitive attempt fails. It does actually describe how to do this:

jQuery - A jQuery object with nodes to be added. If there are multiple elements in the jQuery result set, they are added as multiple rows. If the node is tr element it is treated a the child row, otherwise a row and cell are automatically created and the node from the jQuery result set inserted into it.

However it does not say anything about arrays of JQuery elements. I'll close this question, as this appears to simply be an unsupported feature.

3条回答
倾城 Initia
2楼-- · 2019-05-23 06:49

I have got a stupid solution here but it works

row.child('').show();
tr.addClass('shown');
var c = tr.next();
c.children().remove();
c.html (format(row.data()));
查看更多
来,给爷笑一个
3楼-- · 2019-05-23 07:09

I found the create detail source code in datatable. you should return a array or jQuery object.

function formatDetail(data) {
            var html = "";
            $.each(data, function () {
                html += "<tr><td>1</td><td>2</td></tr>";
            });

            return $(html);
        }
查看更多
Melony?
4楼-- · 2019-05-23 07:12

i have tried the same and after a bit of trail and error this solution works fine for me.

DataTables version 1.10.16

table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
  var data = this.data();
  //i use the data rendered on server side, which in my case are multiple tr. you can remove the data check if not needed ;) 
  if(data.childRow){
    this
      .child(
        //$(data.childRow)
        $('<tr><td>test</td></tr>')
      )
      .show();
  }
} );
查看更多
登录 后发表回答