简体   繁体   中英

Nested DataTables with non-AJAX data source

I got the following code with bootstrap collapse, but I need a sorting option. Because of this issue I would like to solve my problem with a DataTables. Is there an option to solve my problem without using ajax? I want to fill the parent table and the child by a sql query. Like this example

<?php

$switches = $pdo->prepare("Select d.name AS 'Hostname', GROUP_CONCAT(DISTINCT v.id ORDER BY v.id ASC SEPARATOR ' / ') AS 'VLAN', GROUP_CONCAT(DISTINCT v.name ORDER BY v.name ASC SEPARATOR ' / ') AS 'Location'
    FROM device d
    INNER JOIN vlan v ON d.deviceId = v.deviceId
    GROUP BY d.name");
$result = $switches->execute();
$count = 0;
while ($row = $switches->fetch()) {
    echo '<tr class="accordion-toggle">';
    echo '<td><button class="btn btn-default btn-xs collapsed" data-toggle="collapse" data-target="#' . ++$count . '"></button></td>';
    echo "<td>" . $row['Hostname'] . "</td>";
    echo "<td><a>" . $row['VLAN'] . "</a></td>";
    echo "<td>" . $row['Location'] . "</td>";
    echo '<td>
     <select class="form-control">
      <option>1</option>
      <option>2</option>
      <option>3</option>
    </select>
    </td>';
    echo "</tr>";
    echo "<tr>";
    echo '<td colspan="12" class="hiddenRow"><div class="accordian-body collapse" id=' . $count . '>';
    echo '<table class="table table-striped">';
    echo "<thead>";
    echo '<tr><p><a href="InterfaceIPHere">Interface IP</a></p>';
    echo "</tr>";
    echo "<tr>";
    echo "<th>Hostname</th>";
    echo "<th>phys. Port</th>";
    echo "<th>Port Type</th>";
    echo "<th>VLAN</th>";
    echo "<th>Destination Hostname</th>";
    echo "<th>Destination Port</th>";
    echo "<th>Tagged</th>
                </tr>";
    echo "</thead>";
    echo "<tbody>";
    $statement = $pdo->prepare("SELECT a.physikalischerPort as 'phys. Port', a.logischerPort as 'log. Port', pt.type as 'Port Type', GROUP_CONCAT(v.id ORDER BY v.id ASC SEPARATOR ' / ') as VLAN, d2.name as 'Destination Hostname', b.physikalischerPort as 'Destination Port', pt.tagged as 'Tagged' 
    FROM port a
    inner JOIN port b ON a.portId = b.destinationPortId
    INNER JOIN device d ON d.deviceId = a.deviceId
    INNER JOIN device d2 ON d2.deviceId = b.deviceId
    INNER JOIN porttype pt ON pt.porttypeId = a.porttypeId
    INNER JOIN  vlan v ON v.portId = a.portId
    WHERE  a.portId = b.destinationPortId AND b.portId = a.destinationPortId AND a.deviceId = '" . $count . "'
    GROUP BY a.logischerPort, a.physikalischerPort,d2.name, b.physikalischerPort, pt.type, pt.tagged
    ORDER BY (a.physikalischerPort +0) ASC");
    $result = $statement->execute();
    while ($row = $statement->fetch()) {
        echo "<tr>";
        echo "<td>" . $row['phys. Port'] . "</td>";
        echo "<td>" . $row['log. Port'] . "</td>";
        echo "<td>" . $row['Port Type'] . "</td>";
        echo "<td>" . $row['VLAN'] . "</td>";
        echo "<td>" . $row['Destination Hostname'] . "</td>";
        echo "<td>" . $row['Destination Port'] . "</td>";
        echo ($row['Tagged'] == '0') ? '<td><i class="glyphicon glyphicon-remove"></i></td>' : '<td><i class="glyphicon glyphicon-ok"></i></td>';
        echo "</tr>";
    }
    echo "</tbody>";
    echo "</table>";
    echo "</div>";
    echo "</td>";
    echo "</tr>";
}

?>  

With result: Result

Ajax is not a mandatory source to populate your DataTable, it is only (widely preferred) option that allows you to keep your data up to date without reloading page (eg upon editing certain entries or deleting them).

What you need to do is a PHP-script that will echo simple HTML page that has all the necessary prerequisites (including jQuery and DataTables javascripts and stylesheets) referred within <head> section and empty <table id="mytable"></table> within page <body> .

In addition to above prerequisites, you need to refer in your page HTML to dynamically created javascript that uses arrays of objects (obtained from SQL queries) as DataTables source for both parent and child rows:

<?php
/* query your database over here and put the result into associative arrays,
turn them into JSON-compliant arrays/objects */
$parentSource = ... //PHP variable that contains JSON for parent rows
$childSource = ...  //PHP variable that contains JSON for child rows
$js = <<<JS
$(document).ready(function () {
    const parentData = ${$parentSource};
    const childData = ${$childSource};
    const dataTable = $('#mytable').DataTable({
  sDom: 't',
  data: parentData,
  columns: [
    {title: 'Hostname', data: 'hostname'},
    {title: 'VLAN', data: 'vlan'},
    {title: 'Location', data: 'location'},
  ],
});
//prepare child DataTable upon clicking parent row
$('#mytable').on('click', 'tr', function(){
  const parentRow = dataTable.row($(this));
  parentRow.child.isShown() ?
  parentRow.child.remove() :
  parentRow.child('<table id="details"></table>').show();
  $(this).toggleClass('shown');
  if(!parentRow.child.isShown()) return;
  const detailsData = childData[parentRow.data().hostname];
  $('#details').DataTable({
    sDom: 't',
    data: detailsData,
    columns: [
      {title: 'Hostname', data: 'hostname'},
      {title: 'Port', data: 'port'},
      {title: 'Port type', data: 'porttype'},
      {title: 'VLAN', data: 'vlan'},
      {title: 'Destination host', data: 'dsthost'},
      {title: 'Destination port', data: 'dstport'},
    ]
  });
});
});
JS;
/* here should go the code to insert above JS code as a <script> 
into your page */
?>

Hopefully, I've made my point clear despite of possible PHP blunders (since I haven't been using PHP for a while).

You may find working demo over here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM