Hiding DataTables columns at specific breakpoints

Viewed 3611

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 the thead 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.net/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>
2 Answers

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.net/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/responsive/2.2.3/css/responsive.dataTables.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/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>

Related