Problem
I have two DataTables — one is five columns and the other is four columns — and I'm looking for a way to hide columns at specific screen widths.
What I've tried
When I resize the browser, both tables automatically appear to drop down to a two-column chart at 480 pixels in width, but I need additional breakpoints in-between where I'm dropping additional columns since they don't fit inside viewport.
- Adding a class of
responsive
to the table as seen in this example - I've tried using column control helper classes to remove columns at certain breakpoints, but even adding the class
none
did not hide a column - Adding classes to the
<th>
in thethead
to take advantage of their responsive breakpoints - I've include
responsive: true
in my DataTables options
scripts.js
$('#test-scores').dataTable({
initComplete: function () {
this.api().columns([0,1,2]).every( function () {
var column = this;
var colIdx = column.index();
// adjust label for dropdown according to index
// TODO - colIdx is producing 0
if (colIdx === 0) {
var label = 'districts';
}
else if (colIdx === 1) {
var label = 'schools';
}
else {
var label = 'subjects';
}
var select = $('.select--map-' + label)
.on( 'change', function () {
var val = $(this).val();
if ( val == '*' ) {
column
.search( '' )
.draw();
}
else {
val = $.fn.dataTable.util.escapeRegex( val );
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
}
});
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
});
});
},
"pageLength": 25, // The number of entries per page
"order": [0, 'asc'], // First column in ascending order, previous "3, desc"
"responsive": true,
"searching": true,
"columns": [
{ "data": "district",
"render": function (data, type, row, meta) {
return '<a href="/schools/' + makeSlug(data) + '">' + data + '</a>';
}
},
{ "data": "school",
"render": function (data, type, row, meta) {
return '<a href="/schools/' + makeSlug(row['district']) + '/' + makeSlug(data) + '">' + data + '</a>';
}
},
{ "data": "subject" },
{
"data": "rate",
//
// Render.number() parameters: thousands separator, decimal separator, decimal places, prefix, suffix
"render": $.fn.dataTable.render.number( ',', '.', 1, '', '%' )
},
{
"data": "test_takers",
// Render.number() parameters: thousands separator, decimal separator, decimal places, prefix, suffix
"render": $.fn.dataTable.render.number( ',', '.', 0, '', '' )
}
],
"ajax": {
"url": "{% static 'schools/json/school_map_scores.json' %}"
}
});
index.html
<table id="test-scores" class="table table-striped responsive" cellspacing="0" width="100%">
<thead>
<tr>
<th class="table-district none">District</th>
<th class="table-school none">School</th>
<th class="table-subject none">Subject</th>
<th class="table-proficiency none">Pct. proficient</th>
<th class="table-testtakers none">No. of test takers</th>
</tr>
</thead>
<tbody></tbody>
</table>
Problem
I have two DataTables — one is five columns and the other is four columns — and I'm looking for a way to hide columns at specific screen widths.
What I've tried
When I resize the browser, both tables automatically appear to drop down to a two-column chart at 480 pixels in width, but I need additional breakpoints in-between where I'm dropping additional columns since they don't fit inside viewport.
- Adding a class of
responsive
to the table as seen in this example - I've tried using column control helper classes to remove columns at certain breakpoints, but even adding the class
none
did not hide a column - Adding classes to the
<th>
in thethead
to take advantage of their responsive breakpoints - I've include
responsive: true
in my DataTables options
scripts.js
$('#test-scores').dataTable({
initComplete: function () {
this.api().columns([0,1,2]).every( function () {
var column = this;
var colIdx = column.index();
// adjust label for dropdown according to index
// TODO - colIdx is producing 0
if (colIdx === 0) {
var label = 'districts';
}
else if (colIdx === 1) {
var label = 'schools';
}
else {
var label = 'subjects';
}
var select = $('.select--map-' + label)
.on( 'change', function () {
var val = $(this).val();
if ( val == '*' ) {
column
.search( '' )
.draw();
}
else {
val = $.fn.dataTable.util.escapeRegex( val );
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
}
});
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
});
});
},
"pageLength": 25, // The number of entries per page
"order": [0, 'asc'], // First column in ascending order, previous "3, desc"
"responsive": true,
"searching": true,
"columns": [
{ "data": "district",
"render": function (data, type, row, meta) {
return '<a href="/schools/' + makeSlug(data) + '">' + data + '</a>';
}
},
{ "data": "school",
"render": function (data, type, row, meta) {
return '<a href="/schools/' + makeSlug(row['district']) + '/' + makeSlug(data) + '">' + data + '</a>';
}
},
{ "data": "subject" },
{
"data": "rate",
// https://datatables/manual/data/renderers#Built-in-helpers
// Render.number() parameters: thousands separator, decimal separator, decimal places, prefix, suffix
"render": $.fn.dataTable.render.number( ',', '.', 1, '', '%' )
},
{
"data": "test_takers",
// Render.number() parameters: thousands separator, decimal separator, decimal places, prefix, suffix
"render": $.fn.dataTable.render.number( ',', '.', 0, '', '' )
}
],
"ajax": {
"url": "{% static 'schools/json/school_map_scores.json' %}"
}
});
index.html
<table id="test-scores" class="table table-striped responsive" cellspacing="0" width="100%">
<thead>
<tr>
<th class="table-district none">District</th>
<th class="table-school none">School</th>
<th class="table-subject none">Subject</th>
<th class="table-proficiency none">Pct. proficient</th>
<th class="table-testtakers none">No. of test takers</th>
</tr>
</thead>
<tbody></tbody>
</table>
Share
Improve this question
asked Jun 2, 2017 at 16:45
Andrew NguyenAndrew Nguyen
1,4364 gold badges21 silver badges45 bronze badges
1
-
If your table is overflowing within a flexbox but not elsewhere you may have encountered a display issue because of it If that's the case, adding
overflow: hidden;flex-shrink:1;
to the closest flex element will solve the issue – Tofandel Commented Feb 18, 2020 at 11:28
2 Answers
Reset to default 4I am not sure I understand the logic above, but perhaps you overplicate the problem? I would look at column.visible()
and respond to the onresize
event. Here is a dead simple example :
var table = $('#example').DataTable({
autoWidth: false //set to false, so dataTables not ruin the idea
})
create a onresize
handler, trigger immediately so columns is automatically hidden on small devices :
window.onresize = function() {
var w = this.innerWidth;
table.column(5).visible( w > 700);
table.column(4).visible( w > 600);
table.column(3).visible( w > 500);
table.column(2).visible( w > 400);
table.column(1).visible( w > 300);
}
//trigger upon pageload
$(window).trigger('resize');
demo -> http://jsfiddle/4xL6d5xa/
Try resize the right bottom pane.
var table;
window.onresize = function() {
if (!table) return;
var w = this.innerWidth;
table.api().column(5).visible( w > 700);
...
}
table = $('#test-scores').dataTable({
...
initComplete: function() {
setTimeout(function() {
$(window).trigger('resize');
})
}
});
Since you are already using the Responsive extension of DataTable, you can use the responsivePriority option to obtain the desired behavior, it will automatically calculate what columns should be hidden based on the space available for the table and the defined priority
Note: the priority is reversed, meaning a higher priority column will be hidden before a lower priority
$('#test-scores').dataTable({
//...
responsive: true,
columns: [
{ data: "district", responsivePriority: 1 },
{ data: "school", responsivePriority: 2 },
{ data: "subject", responsivePriority: 3 },
{ data: "rate", responsivePriority: 4 },
{ data: "test_takers", responsivePriority: 5 },
],
//...
});
Example
var table = $('#example').DataTable({
responsive: true
});
<link href="https://cdn.datatables/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://cdn.datatables/responsive/2.2.3/css/responsive.dataTables.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables/responsive/2.2.3/js/dataTables.responsive.min.js"></script>
<table id="example" class="nowrap" width="100%">
<thead>
<tr>
<th data-priority="0">Seq.</th> <!-- The first column should always be visible or the collapsed data will not be visible -->
<th data-priority="1">Name</th>
<th data-priority="3">Position</th>
<th data-priority="4">Office</th>
<th data-priority="5">Start date</th>
<th data-priority="1">Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Seq.</th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>2</td>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>22</td>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
<tr>
<td>6</td>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
<tr>
<td>41</td>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>2012/03/29</td>
<td>$433,060</td>
</tr>
<tr>
<td>55</td>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>2008/11/28</td>
<td>$162,700</td>
</tr>
<tr>
<td>21</td>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>2012/12/02</td>
<td>$372,000</td>
</tr>
<tr>
<td>46</td>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
<td>San Francisco</td>
<td>2012/08/06</td>
<td>$137,500</td>
</tr>
<tr>
<td>13</td>
<td>Jena Gaines</td>
<td>Office Manager</td>
<td>London</td>
<td>2008/12/19</td>
<td>$90,560</td>
</tr>
<tr>
<td>23</td>
<td>Quinn Flynn</td>
<td>Support Lead</td>
<td>Edinburgh</td>
<td>2013/03/03</td>
<td>$342,000</td>
</tr>
<tr>
<td>14</td>
<td>Charde Marshall</td>
<td>Regional Director</td>
<td>San Francisco</td>
<td>2008/10/16</td>
<td>$470,600</td>
</tr>
<tr>
<td>12</td>
<td>Haley Kennedy</td>
<td>Senior Marketing Designer</td>
<td>London</td>
<td>2012/12/18</td>
<td>$313,500</td>
</tr>
<tr>
<td>54</td>
<td>Tatyana Fitzpatrick</td>
<td>Regional Director</td>
<td>London</td>
<td>2010/03/17</td>
<td>$385,750</td>
</tr>
<tr>
<td>37</td>
<td>Michael Silva</td>
<td>Marketing Designer</td>
<td>London</td>
<td>2012/11/27</td>
<td>$198,500</td>
</tr>
<tr>
<td>32</td>
<td>Paul Byrd</td>
<td>Chief Financial Officer (CFO)</td>
<td>New York</td>
<td>2010/06/09</td>
<td>$725,000</td>
</tr>
<tr>
<td>35</td>
<td>Gloria Little</td>
<td>Systems Administrator</td>
<td>New York</td>
<td>2009/04/10</td>
<td>$237,500</td>
</tr>
<tr>
<td>48</td>
<td>Bradley Greer</td>
<td>Software Engineer</td>
<td>London</td>
<td>2012/10/13</td>
<td>$132,000</td>
</tr>
<tr>
<td>29</td>
<td>Caesar Vance</td>
<td>Pre-Sales Support</td>
<td>New York</td>
<td>2011/12/12</td>
<td>$106,450</td>
</tr>
<tr>
<td>56</td>
<td>Doris Wilder</td>
<td>Sales Assistant</td>
<td>Sidney</td>
<td>2010/09/20</td>
<td>$85,600</td>
</tr>
</tbody>
</table>