带有数据表的多个 bootstrap 选项卡。仅在其中一个选项卡上打开子行

Multiple bootstrap tabs with DataTables. Child row only opening on one of the tabs

我的数据表在 2 个 bootstrap 选项卡中包含子行。子行不会始终在选项卡内打开。它们有时在第一个选项卡上打开,有时在第二个选项卡上打开。

我想在每次单击该行并打开它时创建容器。它有时在第二个打开,有时在第一个打开。它不会在两个选项卡中打开。

这是我的代码:

let json1 = [{
      "data": [
      {
          "id": "1",
          "name": "Tiger Nixon",
          "position": "System Architect",
          "salary": "0,800",
          "start_date": "2011/04/25",
          "office": "Edinburgh",
          "extn": "5421"
      },
      {
          "id": "2",
          "name": "Garrett Winters",
          "position": "Accountant",
          "salary": "0,750",
          "start_date": "2011/07/25",
          "office": "Tokyo",
          "extn": "8422"
      },
      {
          "id": "3",
          "name": "Ashton Cox",
          "position": "Junior Technical Author",
          "salary": ",000",
          "start_date": "2009/01/12",
          "office": "San Francisco",
          "extn": "1562"
      },
      {
          "id": "4",
          "name": "Cedric Kelly",
          "position": "Senior Javascript Developer",
          "salary": "3,060",
          "start_date": "2012/03/29",
          "office": "Edinburgh",
          "extn": "6224"
      },
      {
          "id": "5",
          "name": "Airi Satou",
          "position": "Accountant",
          "salary": "2,700",
          "start_date": "2008/11/28",
          "office": "Tokyo",
          "extn": "5407"
      }
      ]
  }];
  let json2 = [{
      "data": [
      {
          "id": "1",
          "name": "Harry Potter",
          "position": "System Architect",
          "salary": "4,800",
          "start_date": "2013/04/25",
          "office": "Edinburgh",
          "extn": "5421"
      },
      {
          "id": "2",
          "name": "Ron Weasley",
          "position": "Accountant",
          "salary": "0,777",
          "start_date": "2011/09/25",
          "office": "Tokyo",
          "extn": "8422"
      },
      {
          "id": "3",
          "name": "Herminone Granger",
          "position": "Junior Technical Author",
          "salary": "5,000",
          "start_date": "2019/01/12",
          "office": "San Francisco",
          "extn": "1562"
      },
      {
          "id": "4",
          "name": "Neville Logbottom",
          "position": "Senior Javascript Developer",
          "salary": "5,060",
          "start_date": "2015/03/29",
          "office": "Edinburgh",
          "extn": "6224"
      },
      {
          "id": "5",
          "name": "Luna Lovegood",
          "position": "Accountant",
          "salary": "0,700",
          "start_date": "2017/11/28",
          "office": "Tokyo",
          "extn": "5407"
      }
      ]
  }];
  var table;
  const create_datatable =(js, tab) => {
    js.forEach(d => {
        table = $(`#${tab}`).DataTable( {
            "bDestroy": true,
            "responsive": true,
            "autoWidth": false,
            "data": d.data,
            columns: [{
                className: 'details-control',
                orderable: false,
                data: null,
                defaultContent: '',
            }, {
                data: 'name', className:'names'
            }, {
                data: 'position', className:'position'
            }, {
                data: 'office', className:'office'
            }, {
                data: 'salary', className:'salary'
            }]
        } );
    });
}
create_datatable(json1, 'example');
create_datatable(json2, 'example2');

const create_cont = (tab) => {
    var containers = document.createElement('div');
    containers.setAttribute("id", `${tab}_scatter`);
    $(`#${tab} tbody`).on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
          // This row is already open - close it
          row.child.hide();
          tr.removeClass('shown');
      }
      else {
        if ( table.row( '.shown' ).length ) $('.details-control', table.row( '.shown' ).node()).click();
        $(`#${tab}_scatter`).html('test');
        row.child(containers).show();
        tr.addClass('shown');
    }
});
}
create_cont('example');
create_cont('example2');
td.details-control {
    background: url('../resources/details_open.png') no-repeat center center;
    cursor: pointer;
}
tr.shown td.details-control {
    background: url('../resources/details_close.png') no-repeat center center;
}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>

<ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
    <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
</ul>

<div class="tab-content">
    <div id="home" class="tab-pane fade in active">
      <h3>Tab 1</h3>
      <table id="example" class="display" style="width:100%">
        <thead>
            <tr>
                <th>Show Child Row</th>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
</div>
<div id="menu1" class="tab-pane fade">
  <h3>Tab 2</h3>
  <table id="example2" class="display" style="width:100%">
    <thead>
        <tr>
            <th>Show Child Row</th>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Salary</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>
</div>
</div>

如何修复它,以便每当我单击最左侧的列时,该行以我的文本 ('test') 打开,总是出现子行?

我每次单击该行时都会创建一个容器,因为我想最终在子行中添加动态图表。

问题是因为您在循环中设置了 table。因此它只会包含对创建的 last DataTable 的引用。

要解决此问题,请从点击处理程序中的 table 元素获取 DataTable 引用:

let json1 = [{data:[{id:"1",name:"Tiger Nixon",position:"System Architect",salary:"0,800",start_date:"2011/04/25",office:"Edinburgh",extn:"5421"},{id:"2",name:"Garrett Winters",position:"Accountant",salary:"0,750",start_date:"2011/07/25",office:"Tokyo",extn:"8422"},{id:"3",name:"Ashton Cox",position:"Junior Technical Author",salary:",000",start_date:"2009/01/12",office:"San Francisco",extn:"1562"},{id:"4",name:"Cedric Kelly",position:"Senior Javascript Developer",salary:"3,060",start_date:"2012/03/29",office:"Edinburgh",extn:"6224"},{id:"5",name:"Airi Satou",position:"Accountant",salary:"2,700",start_date:"2008/11/28",office:"Tokyo",extn:"5407"}]}];
let json2 = [{data:[{id:"1",name:"Harry Potter",position:"System Architect",salary:"4,800",start_date:"2013/04/25",office:"Edinburgh",extn:"5421"},{id:"2",name:"Ron Weasley",position:"Accountant",salary:"0,777",start_date:"2011/09/25",office:"Tokyo",extn:"8422"},{id:"3",name:"Herminone Granger",position:"Junior Technical Author",salary:"5,000",start_date:"2019/01/12",office:"San Francisco",extn:"1562"},{id:"4",name:"Neville Logbottom",position:"Senior Javascript Developer",salary:"5,060",start_date:"2015/03/29",office:"Edinburgh",extn:"6224"},{id:"5",name:"Luna Lovegood",position:"Accountant",salary:"0,700",start_date:"2017/11/28",office:"Tokyo",extn:"5407"}]}];

const create_datatable = (js, tab) => {
  js.forEach(d => {
    $(`#${tab}`).DataTable({
      "bDestroy": true,
      "responsive": true,
      "autoWidth": false,
      "data": d.data,
      columns: [{
        className: 'details-control',
        orderable: false,
        data: null,
        defaultContent: '',
      }, {
        data: 'name',
        className: 'names'
      }, {
        data: 'position',
        className: 'position'
      }, {
        data: 'office',
        className: 'office'
      }, {
        data: 'salary',
        className: 'salary'
      }]
    });
  });
}
create_datatable(json1, 'example');
create_datatable(json2, 'example2');

const create_cont = (tab) => {
  var containers = document.createElement('div');
  containers.setAttribute("id", `${tab}_scatter`);
  
  $(`#${tab} tbody`).on('click', 'td.details-control', function() {  
    var tr = $(this).closest('tr');
    let table = tr.closest('table').DataTable(); // retrieve Datatable reference here
    var row = table.row(tr);

    if (row.child.isShown()) {
      // This row is already open - close it
      row.child.hide();
      tr.removeClass('shown');
    } else {
      if (table.row('.shown').length) $('.details-control', table.row('.shown').node()).click();
      $(`#${tab}_scatter`).html('test');
      row.child(containers).show();
      tr.addClass('shown');
    }
  });
}
create_cont('example');
create_cont('example2');
td.details-control {
  background: url('../resources/details_open.png') no-repeat center center;
  cursor: pointer;
}

tr.shown td.details-control {
  background: url('../resources/details_close.png') no-repeat center center;
}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>

<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
  <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
</ul>

<div class="tab-content">
  <div id="home" class="tab-pane fade in active">
    <h3>Tab 1</h3>
    <table id="example" class="display" style="width:100%">
      <thead>
        <tr>
          <th>Show Child Row</th>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Salary</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </div>
  <div id="menu1" class="tab-pane fade">
    <h3>Tab 2</h3>
    <table id="example2" class="display" style="width:100%">
      <thead>
        <tr>
          <th>Show Child Row</th>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Salary</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </div>
</div>