admin管理员组

文章数量:1414852

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",
            // 
            // 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 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/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
Add a ment  | 

2 Answers 2

Reset to default 4

I 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>

本文标签: javascriptHiding DataTables columns at specific breakpointsStack Overflow