Mercurial > hg > cmmr2012-drupal-site
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 /** | |
2 * @file | |
3 * Responsive table functionality. | |
4 */ | |
5 | |
6 (function ($, Drupal, window) { | |
7 /** | |
8 * Attach the tableResponsive function to {@link Drupal.behaviors}. | |
9 * | |
10 * @type {Drupal~behavior} | |
11 * | |
12 * @prop {Drupal~behaviorAttach} attach | |
13 * Attaches tableResponsive functionality. | |
14 */ | |
15 Drupal.behaviors.tableResponsive = { | |
16 attach(context, settings) { | |
17 const $tables = $(context).find('table.responsive-enabled').once('tableresponsive'); | |
18 if ($tables.length) { | |
19 const il = $tables.length; | |
20 for (let i = 0; i < il; i++) { | |
21 TableResponsive.tables.push(new TableResponsive($tables[i])); | |
22 } | |
23 } | |
24 }, | |
25 }; | |
26 | |
27 /** | |
28 * The TableResponsive object optimizes table presentation for screen size. | |
29 * | |
30 * A responsive table hides columns at small screen sizes, leaving the most | |
31 * important columns visible to the end user. Users should not be prevented | |
32 * from accessing all columns, however. This class adds a toggle to a table | |
33 * with hidden columns that exposes the columns. Exposing the columns will | |
34 * likely break layouts, but it provides the user with a means to access | |
35 * data, which is a guiding principle of responsive design. | |
36 * | |
37 * @constructor Drupal.TableResponsive | |
38 * | |
39 * @param {HTMLElement} table | |
40 * The table element to initialize the responsive table on. | |
41 */ | |
42 function TableResponsive(table) { | |
43 this.table = table; | |
44 this.$table = $(table); | |
45 this.showText = Drupal.t('Show all columns'); | |
46 this.hideText = Drupal.t('Hide lower priority columns'); | |
47 // Store a reference to the header elements of the table so that the DOM is | |
48 // traversed only once to find them. | |
49 this.$headers = this.$table.find('th'); | |
50 // Add a link before the table for users to show or hide weight columns. | |
51 this.$link = $('<button type="button" class="link tableresponsive-toggle"></button>') | |
52 .attr('title', Drupal.t('Show table cells that were hidden to make the table fit within a small screen.')) | |
53 .on('click', $.proxy(this, 'eventhandlerToggleColumns')); | |
54 | |
55 this.$table.before($('<div class="tableresponsive-toggle-columns"></div>').append(this.$link)); | |
56 | |
57 // Attach a resize handler to the window. | |
58 $(window) | |
59 .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility')) | |
60 .trigger('resize.tableresponsive'); | |
61 } | |
62 | |
63 /** | |
64 * Extend the TableResponsive function with a list of managed tables. | |
65 */ | |
66 $.extend(TableResponsive, /** @lends Drupal.TableResponsive */{ | |
67 | |
68 /** | |
69 * Store all created instances. | |
70 * | |
71 * @type {Array.<Drupal.TableResponsive>} | |
72 */ | |
73 tables: [], | |
74 }); | |
75 | |
76 /** | |
77 * Associates an action link with the table that will show hidden columns. | |
78 * | |
79 * Columns are assumed to be hidden if their header has the class priority-low | |
80 * or priority-medium. | |
81 */ | |
82 $.extend(TableResponsive.prototype, /** @lends Drupal.TableResponsive# */{ | |
83 | |
84 /** | |
85 * @param {jQuery.Event} e | |
86 * The event triggered. | |
87 */ | |
88 eventhandlerEvaluateColumnVisibility(e) { | |
89 const pegged = parseInt(this.$link.data('pegged'), 10); | |
90 const hiddenLength = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden').length; | |
91 // If the table has hidden columns, associate an action link with the | |
92 // table to show the columns. | |
93 if (hiddenLength > 0) { | |
94 this.$link.show().text(this.showText); | |
95 } | |
96 // When the toggle is pegged, its presence is maintained because the user | |
97 // has interacted with it. This is necessary to keep the link visible if | |
98 // the user adjusts screen size and changes the visibility of columns. | |
99 if (!pegged && hiddenLength === 0) { | |
100 this.$link.hide().text(this.hideText); | |
101 } | |
102 }, | |
103 | |
104 /** | |
105 * Toggle the visibility of columns based on their priority. | |
106 * | |
107 * Columns are classed with either 'priority-low' or 'priority-medium'. | |
108 * | |
109 * @param {jQuery.Event} e | |
110 * The event triggered. | |
111 */ | |
112 eventhandlerToggleColumns(e) { | |
113 e.preventDefault(); | |
114 const self = this; | |
115 const $hiddenHeaders = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden'); | |
116 this.$revealedCells = this.$revealedCells || $(); | |
117 // Reveal hidden columns. | |
118 if ($hiddenHeaders.length > 0) { | |
119 $hiddenHeaders.each(function (index, element) { | |
120 const $header = $(this); | |
121 const position = $header.prevAll('th').length; | |
122 self.$table.find('tbody tr').each(function () { | |
123 const $cells = $(this).find('td').eq(position); | |
124 $cells.show(); | |
125 // Keep track of the revealed cells, so they can be hidden later. | |
126 self.$revealedCells = $().add(self.$revealedCells).add($cells); | |
127 }); | |
128 $header.show(); | |
129 // Keep track of the revealed headers, so they can be hidden later. | |
130 self.$revealedCells = $().add(self.$revealedCells).add($header); | |
131 }); | |
132 this.$link.text(this.hideText).data('pegged', 1); | |
133 } | |
134 // Hide revealed columns. | |
135 else { | |
136 this.$revealedCells.hide(); | |
137 // Strip the 'display:none' declaration from the style attributes of | |
138 // the table cells that .hide() added. | |
139 this.$revealedCells.each(function (index, element) { | |
140 const $cell = $(this); | |
141 const properties = $cell.attr('style').split(';'); | |
142 const newProps = []; | |
143 // The hide method adds display none to the element. The element | |
144 // should be returned to the same state it was in before the columns | |
145 // were revealed, so it is necessary to remove the display none value | |
146 // from the style attribute. | |
147 const match = /^display\s*:\s*none$/; | |
148 for (let i = 0; i < properties.length; i++) { | |
149 const prop = properties[i]; | |
150 prop.trim(); | |
151 // Find the display:none property and remove it. | |
152 const isDisplayNone = match.exec(prop); | |
153 if (isDisplayNone) { | |
154 continue; | |
155 } | |
156 newProps.push(prop); | |
157 } | |
158 // Return the rest of the style attribute values to the element. | |
159 $cell.attr('style', newProps.join(';')); | |
160 }); | |
161 this.$link.text(this.showText).data('pegged', 0); | |
162 // Refresh the toggle link. | |
163 $(window).trigger('resize.tableresponsive'); | |
164 } | |
165 }, | |
166 }); | |
167 | |
168 // Make the TableResponsive object available in the Drupal namespace. | |
169 Drupal.TableResponsive = TableResponsive; | |
170 }(jQuery, Drupal, window)); |