Responsive Data Grids with JavaScript
All references to responsive tables on the 'net refer to typical tabular data, 'database-style' if you will. We use tables a lot to represent a single row of that data, in what I'll call a data grid. Like this, for instance:
Gender | Male | DOB (Age) | 07/02/1990 (23) |
---|---|---|---|
Interests | Coding, snooker, sports betting, cooking | ||
Summary | Some thing that looks better full width.. | ||
Ethnicity | White - British | Religion | None |
First Language | English | English As Additional Language | No |
Email Address | foo@bar.com | Telephone Number | 01234567 |
I think this is appropriate data to be represented in a table, and it'd look awful just in one long row. The good thing is that it's ought to be easy to make responsive, you just put every 'key-value' (th and adjacent td) data item in its each row.
I wrote the following simple jQuery plugin to do just this. The default size at which it collapses is below 768px (twitter bootstrap's "extra-small").
(function($) { "use strict"; $.fn.responsiveDataGrid = function(options) { return this.each(function() { var $this = $(this); var $new_table, $old_table; var currentSize = 99999; // default size below which to pack is 768 if (!options.packAt) options.packAt = '768' if (!$this.is("table")) { return $this.find("table").each(function(index, item) { $(item).responsiveDataGrid(options); }) } // check after the initial load checkForResize(); // check subscriptions when window width changes $(window).resize(function () { checkForResize(); }); // see if subscriptions need to be fired function checkForResize() { // get the screen width var width = $(window).width(); if (width <= options.packAt && currentSize > options.packAt) { currentSize = width; packDataGrid(); } else if (width > options.packAt && currentSize <= options.packAt) { currentSize = width; unpackDataGrid(); } } function packDataGrid() { if (!$new_table) { $new_table = $this.clone().empty(); $this.clone().find('tr').each(function(i,tr) { var $row = $(tr); $row.children('th').each(function(i,th) { var $th = $(th); var $td = $th.next(); if ($td.is('td')) { var $updated = $('<tr>', {'class':'rdg-wrapped'}).append($th, $td); $new_table.append($updated); } }); }); } $old_table = $this.replaceWith($new_table); } function unpackDataGrid() { $new_table.replaceWith($old_table); } }); } })(jQuery);
To use, just call .responsiveDataGrid({}) on the table. You can optionally pass "packAt" as an option to change the size at which the table adjusts.
See it in action.