Mercurial > hg > cmmr2012-drupal-site
diff core/misc/tableresponsive.es6.js @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/misc/tableresponsive.es6.js Thu Jul 05 14:24:15 2018 +0000 @@ -0,0 +1,170 @@ +/** + * @file + * Responsive table functionality. + */ + +(function ($, Drupal, window) { + /** + * Attach the tableResponsive function to {@link Drupal.behaviors}. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches tableResponsive functionality. + */ + Drupal.behaviors.tableResponsive = { + attach(context, settings) { + const $tables = $(context).find('table.responsive-enabled').once('tableresponsive'); + if ($tables.length) { + const il = $tables.length; + for (let i = 0; i < il; i++) { + TableResponsive.tables.push(new TableResponsive($tables[i])); + } + } + }, + }; + + /** + * The TableResponsive object optimizes table presentation for screen size. + * + * A responsive table hides columns at small screen sizes, leaving the most + * important columns visible to the end user. Users should not be prevented + * from accessing all columns, however. This class adds a toggle to a table + * with hidden columns that exposes the columns. Exposing the columns will + * likely break layouts, but it provides the user with a means to access + * data, which is a guiding principle of responsive design. + * + * @constructor Drupal.TableResponsive + * + * @param {HTMLElement} table + * The table element to initialize the responsive table on. + */ + function TableResponsive(table) { + this.table = table; + this.$table = $(table); + this.showText = Drupal.t('Show all columns'); + this.hideText = Drupal.t('Hide lower priority columns'); + // Store a reference to the header elements of the table so that the DOM is + // traversed only once to find them. + this.$headers = this.$table.find('th'); + // Add a link before the table for users to show or hide weight columns. + this.$link = $('<button type="button" class="link tableresponsive-toggle"></button>') + .attr('title', Drupal.t('Show table cells that were hidden to make the table fit within a small screen.')) + .on('click', $.proxy(this, 'eventhandlerToggleColumns')); + + this.$table.before($('<div class="tableresponsive-toggle-columns"></div>').append(this.$link)); + + // Attach a resize handler to the window. + $(window) + .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility')) + .trigger('resize.tableresponsive'); + } + + /** + * Extend the TableResponsive function with a list of managed tables. + */ + $.extend(TableResponsive, /** @lends Drupal.TableResponsive */{ + + /** + * Store all created instances. + * + * @type {Array.<Drupal.TableResponsive>} + */ + tables: [], + }); + + /** + * Associates an action link with the table that will show hidden columns. + * + * Columns are assumed to be hidden if their header has the class priority-low + * or priority-medium. + */ + $.extend(TableResponsive.prototype, /** @lends Drupal.TableResponsive# */{ + + /** + * @param {jQuery.Event} e + * The event triggered. + */ + eventhandlerEvaluateColumnVisibility(e) { + const pegged = parseInt(this.$link.data('pegged'), 10); + const hiddenLength = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden').length; + // If the table has hidden columns, associate an action link with the + // table to show the columns. + if (hiddenLength > 0) { + this.$link.show().text(this.showText); + } + // When the toggle is pegged, its presence is maintained because the user + // has interacted with it. This is necessary to keep the link visible if + // the user adjusts screen size and changes the visibility of columns. + if (!pegged && hiddenLength === 0) { + this.$link.hide().text(this.hideText); + } + }, + + /** + * Toggle the visibility of columns based on their priority. + * + * Columns are classed with either 'priority-low' or 'priority-medium'. + * + * @param {jQuery.Event} e + * The event triggered. + */ + eventhandlerToggleColumns(e) { + e.preventDefault(); + const self = this; + const $hiddenHeaders = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden'); + this.$revealedCells = this.$revealedCells || $(); + // Reveal hidden columns. + if ($hiddenHeaders.length > 0) { + $hiddenHeaders.each(function (index, element) { + const $header = $(this); + const position = $header.prevAll('th').length; + self.$table.find('tbody tr').each(function () { + const $cells = $(this).find('td').eq(position); + $cells.show(); + // Keep track of the revealed cells, so they can be hidden later. + self.$revealedCells = $().add(self.$revealedCells).add($cells); + }); + $header.show(); + // Keep track of the revealed headers, so they can be hidden later. + self.$revealedCells = $().add(self.$revealedCells).add($header); + }); + this.$link.text(this.hideText).data('pegged', 1); + } + // Hide revealed columns. + else { + this.$revealedCells.hide(); + // Strip the 'display:none' declaration from the style attributes of + // the table cells that .hide() added. + this.$revealedCells.each(function (index, element) { + const $cell = $(this); + const properties = $cell.attr('style').split(';'); + const newProps = []; + // The hide method adds display none to the element. The element + // should be returned to the same state it was in before the columns + // were revealed, so it is necessary to remove the display none value + // from the style attribute. + const match = /^display\s*:\s*none$/; + for (let i = 0; i < properties.length; i++) { + const prop = properties[i]; + prop.trim(); + // Find the display:none property and remove it. + const isDisplayNone = match.exec(prop); + if (isDisplayNone) { + continue; + } + newProps.push(prop); + } + // Return the rest of the style attribute values to the element. + $cell.attr('style', newProps.join(';')); + }); + this.$link.text(this.showText).data('pegged', 0); + // Refresh the toggle link. + $(window).trigger('resize.tableresponsive'); + } + }, + }); + + // Make the TableResponsive object available in the Drupal namespace. + Drupal.TableResponsive = TableResponsive; +}(jQuery, Drupal, window));