<table id="data-table" class="table table-bordered table-hover" width="100%" cellspacing="0"> <thead> <tr> <th>IP</th> <th>DNS</th> <th>Device</th> <th>Port</th> <th>Name</th> <th>Description</th> <th class="nd_center-cell">Channel</th> <th class="nd_center-cell">Tx Power (mW/dBm)</th> </tr> </thead> </table> <style> tr.group, tr.group:hover { background-color: #ddd !important; } </style> <script> function groupString(d) { "use strict"; var s = ''; s = s + 'Device: '; s = s + '<a href="[% uri_for('/device') | none %]?tab=details&q=' + encodeURIComponent(d.ip) + '">'; s = s + he.encode(d.dns || d.device_name || d.ip); if (d.dns || d.device_name) { s = s + ' (' + he.encode(d.ip) + ') '; } s = s + '</a> Model: ' + he.encode(d.model || ''); s = s + he.encode(d.location ? ' Location: ' + d.location : ''); return s; } $(document).ready(function() { var table = $('#data-table').DataTable({ "serverSide": true, "ajax": "[% uri_for('/ajax/content/report/apradiochannelpower/data') | none %]", "order": [[ 0, 'asc' ]], "columns": [ { // Grouping column "data": 'ip', "visible": false }, { // Included for filtering "data": 'dns', "visible": false }, { // Included for filtering "data": 'device_name', "visible": false }, { "data": 'port', "type": 'portsort', "render": function(data, type, row, meta) { return type === 'display' ? '<a href="[% device_ports | none %]&q=' + encodeURIComponent(row.ip) + '&f=' + encodeURIComponent(data) + '">' + he.encode(data || '') + '</a>' : he.encode(data || ''); } }, { "data": 'port_name', "render": function(data, type, row, meta) { return he.encode(data || ''); } }, { "data": 'descr', "render": function(data, type, row, meta) { return he.encode(data || ''); } }, { "data": 'channel', "className": "nd_center-cell" }, { "data": 'power', "className": "nd_center-cell", "render": function(data, type, row, meta) { return (row.power2 ? data + ' / ' + row.power2 : ''); } } ], "drawCallback": function ( settings ) { var api = this.api(); var rows = api.rows( {page:'current'} ).nodes(); var last=null; api.column(0, {page:'current'} ).data().each( function ( group, i ) { if ( last !== group ) { var row_data = api.row( i ).data(); $(rows).eq( i ).before( '<tr class="group"><td colspan="5">' + groupString(row_data) + '</td></tr>' ); last = group; } } ); }, [% INCLUDE 'ajax/datatabledefaults.tt' -%] } ); // Order by the grouping $('#data-table tbody').on( 'click', 'tr.group', function () { var currentOrder = table.order()[0]; if ( currentOrder[0] === 0 && currentOrder[1] === 'asc' ) { table.order( [ 0, 'desc' ] ).draw(); } else { table.order( [ 0, 'asc' ] ).draw(); } } ); } ); </script>