Table: Review widget #7360
Description
Table Review
Description
Functional Specification
Table enhances the HTML <table>
in one of two ways (implemented as extensions):
- reflow
- On narrow screens, columns in a row become rows in a single column, and each row has a row header based on the column header
- columntoggle
- Columns have associated priorities, and are turned off in order of priority depending on how narrow the screen is. They can also be turned on/off manually by unchecking checkboxes in a popup menu listing the columns. Once a column has been turned on/off by the user by clicking on a checkbox, or programmatically by setting a checkbox's ```checked``` property, the column will remain hidden if the checkbox is unchecked, and shown if the checkbox is checked, irrespective of screen width
Responsive Design Considerations
Breakpoints need to be provided for the automatic showing/hiding of columns to work. Alternatively, built-in breakpoints can be used. They apply whenever the class ui-responsive
is added to the table.
Performance Considerations
It may be possible to
- refresh the table in batches using idle loop
- detach the table during creation
Accessibility Considerations
Navigation Considerations
Options
- classes
- Hash containing classes used by the table. Recognized keys:
table
- Default value:
"ui-table"
. This class is appended to the<table>
element upon widget instantiation. reflowTable
- Default value:
"ui-table-reflow"
. This class is appended to the<table>
element upon widget instantiation when it is to be turned into a reflow table. This key is provided by the widget's reflow extension. cellLabels
- Default value:
"ui-table-cell-label
. This class is added to the<b>
elements which play the role of headings when the is rendered as a single column on narrow screens. This key is provided by the widget's reflow extension. popup
- Default value:
"ui-table-columntoggle-popup"
. This class is added to the popup containing the column checklist. This key is provided by the widget's columntoggle extension. columnBtn
- Default value:
"ui-table-columntoggle-btn"
. This class is added to the button that brings up the column checklist. This key is provided by the widget's columntoggle extension. priorityPrefix
- Default value:
"ui-table-priority-"
. The table constructs a class name from this prefix by appending the value of thedata-priority
attribute it finds on the column header, if any. It then applies the resulting class to all cells under the column header. This key is provided by the widget's columntoggle extension. columnToggleTable
- Default value:
"ui-table-columntoggle"
. This class is appended to the<table>
upon widget instantiation when it is to be turned into a columntoggle table. This key is provided by the widget's columntoggle extension.
- columnButton
- Default:
true
. Boolean option indicating that the widget is to generate a button that displays the columns popup when true. - columnBtnText
- Default:
"Columns..."
. The text to be used for the columns button. - columnBtnTheme
- Default:
null
. The theme swatch to be used for the column button. The button inherits the swatch by default. - columnPopupTheme
- Default:
null
. The theme swatch to be used for the column popup. The popup inherits the swatch by default. - columnUI
- Default:
true
. Boolean option indicating that the widget is to generate a button and a popup such that the popup displays the columns available for showing/hiding, and the button launches the popup. If this option is ```false```, no button will be generated, even if the ```columnButton``` option is ```true```. - disabled
- Default:
false
. Indicates that the table is disabled. This applies the ui-state-disabled class, but does not prevent the user from reaching content inside the table via the keyboard. In the case of the columntoggle table, it disables the column chooser button and popup. - enhanced
-
Default:
false
. Boolean option indicating that the user has provided all necessary markup a priori. In the case of the columntoggle table, this means that the "Columns..." button, the popup that opens from it, and all the checkbox inputs inside the popup have been provided. - mode
- A string that can have one of two values:
- "reflow"
- Indicates that the table is to be enhanced as a reflow table
- "columntoggle"
- Indicates that the table is to be enhanced as a columntoggle table
Events
-
create notifies of the creation of a table widget on event target element
// bind to the create event $( ".selector" ).on("tablecreate", function(event, ui) {}); // create a table on .selector and hook up to tablecreate event $( ".selector" ).table({ create: function(event, ui) { } });
Methods
-
destroy removes table enhancements from the element
$( ".selector" ).table( "destroy" );
-
enable enables the table
$( ".selector" ).table( "enable" );
-
disable disabled the table
$( ".selector" ).table( "disable" );
-
refresh re-examines the DOM ensuring the table widget's state is consistent with the DOM contents
This method retains the forced-show/forced-hide status of columns$( ".selector" ).table( "refresh" );
-
toggleColumn forces visibility for a column
$( ".selector" ).table( "toggleColumn", column, isVisible )
column is either a number or a jQuery collection object containing at least one cell from the column to be forced hidden/shown
Markup & Style
Initial Markup
<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive">
<thead>
<tr>
<th data-priority="1">Rank</th>
<th data-priority="permanent">Movie Title</th>
<th data-priority="2">Year</th>
<th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th data-priority="4">Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>Citizen Kane</td>
<td>1941</td>
<td>100%</td>
<td>74</td>
</tr>
<tr>
<th>2</th>
<td>Casablanca</td>
<td>1942</td>
<td>97%</td>
<td>64</td>
</tr>
<tbody>
</table>
Enhanced Markup
<!-- reflow table -->
<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive ui-table ui-table-reflow">
<thead>
<tr>
<th data-colstart="1" data-priority="1">Rank</th>
<th data-colstart="2" data-priority="permanent">Movie Title</th>
<th data-colstart="3" data-priority="2">Year</th>
<th data-colstart="4" data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th data-colstart="5" data-priority="4">Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th><b class="ui-table-cell-label">Rank</b>1</th>
<td><b class="ui-table-cell-label">Movie Title</b>Citizen Kane</td>
<td><b class="ui-table-cell-label">Year</b>1941</td>
<td><b class="ui-table-cell-label">Rating</b>100%</td>
<td><b class="ui-table-cell-label">Reviews</b>74</td>
</tr>
<tr>
<th><b class="ui-table-cell-label">Rank</b>2</th>
<td><b class="ui-table-cell-label">Movie Title</b>Casablanca</td>
<td><b class="ui-table-cell-label">Year</b>1942</td>
<td><b class="ui-table-cell-label">Rating</b>97%</td>
<td><b class="ui-table-cell-label">Reviews</b>64</td>
</tr>
</tbody>
</table>
<!-- columntoggle table -->
<div style="display: none;" id="table-column-toggle-popup-placeholder">
<!-- placeholder for table-column-toggle-popup -->
</div>
<a href="#table-column-toggle-popup" class="ui-table-columntoggle-btn ui-btn ui-btn-a ui-corner-all ui-shadow ui-mini" data-rel="popup">Columns...</a>
<table data-role="table" id="table-column-toggle" data-mode="columntoggle" class="ui-responsive table-stroke ui-table ui-table-columntoggle">
<thead>
<tr>
<th data-priority="2" data-colstart="1" class="ui-table-priority-2">Rank</th>
<th data-colstart="2">Movie Title</th>
<th data-priority="3" data-colstart="3" class="ui-table-priority-3">Year</th>
<th data-priority="1" data-colstart="4" class="ui-table-priority-1"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th data-priority="5" data-colstart="5" class="ui-table-priority-5">Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th class="ui-table-priority-2">1</th>
<td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external" class="ui-link">Citizen Kane</a></td>
<td class="ui-table-priority-3">1941</td>
<td class="ui-table-priority-1">100%</td>
<td class="ui-table-priority-5">74</td>
</tr>
<tr>
<th class="ui-table-priority-2">2</th>
<td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external" class="ui-link">Casablanca</a></td>
<td class="ui-table-priority-3">1942</td>
<td class="ui-table-priority-1">97%</td>
<td class="ui-table-priority-5">64</td>
</tr>
<tr>
<th class="ui-table-priority-2">3</th>
<td><a href="http://en.wikipedia.org/wiki/The_Godfather" data-rel="external" class="ui-link">The Godfather</a></td>
<td class="ui-table-priority-3">1972</td>
<td class="ui-table-priority-1">97%</td>
<td class="ui-table-priority-5">87</td>
</tr>
<tr>
<th class="ui-table-priority-2">4</th>
<td><a href="http://en.wikipedia.org/wiki/Gone_with_the_Wind_(film)" data-rel="external" class="ui-link">Gone with the Wind</a></td>
<td class="ui-table-priority-3">1939</td>
<td class="ui-table-priority-1">96%</td>
<td class="ui-table-priority-5">87</td>
</tr>
<tr>
<th class="ui-table-priority-2">5</th>
<td><a href="http://en.wikipedia.org/wiki/Lawrence_of_Arabia_(film)" data-rel="external" class="ui-link">Lawrence of Arabia</a></td>
<td class="ui-table-priority-3">1962</td>
<td class="ui-table-priority-1">94%</td>
<td class="ui-table-priority-5">87</td>
</tr>
<tr>
<th class="ui-table-priority-2">6</th>
<td><a href="http://en.wikipedia.org/wiki/Dr._Strangelove" data-rel="external" class="ui-link">Dr. Strangelove Or How I Learned to Stop Worrying and Love the Bomb</a></td>
<td class="ui-table-priority-3">1964</td>
<td class="ui-table-priority-1">92%</td>
<td class="ui-table-priority-5">74</td>
</tr>
<tr>
<th class="ui-table-priority-2">7</th>
<td><a href="http://en.wikipedia.org/wiki/The_Graduate" data-rel="external" class="ui-link">The Graduate</a></td>
<td class="ui-table-priority-3">1967</td>
<td class="ui-table-priority-1">91%</td>
<td class="ui-table-priority-5">122</td>
</tr>
<tr>
<th class="ui-table-priority-2">8</th>
<td><a href="http://en.wikipedia.org/wiki/The_Wizard_of_Oz_(1939_film)" data-rel="external" class="ui-link">The Wizard of Oz</a></td>
<td class="ui-table-priority-3">1939</td>
<td class="ui-table-priority-1">90%</td>
<td class="ui-table-priority-5">72</td>
</tr>
<tr>
<th class="ui-table-priority-2">9</th>
<td><a href="http://en.wikipedia.org/wiki/Singin%27_in_the_Rain" data-rel="external" class="ui-link">Singin' in the Rain</a></td>
<td class="ui-table-priority-3">1952</td>
<td class="ui-table-priority-1">89%</td>
<td class="ui-table-priority-5">85</td>
</tr>
<tr>
<th class="ui-table-priority-2">10</th>
<td class="title"><a href="http://en.wikipedia.org/wiki/Inception" data-rel="external" class="ui-link">Inception</a></td>
<td class="ui-table-priority-3">2010</td>
<td class="ui-table-priority-1">84%</td>
<td class="ui-table-priority-5">78</td>
</tr>
</tbody>
</table>
<div class="ui-screen-hidden ui-popup-screen ui-overlay-inherit" id="table-column-toggle-popup-screen"></div>
<div class="ui-popup-container ui-popup-hidden ui-popup-truncate" id="table-column-toggle-popup-popup">
<div class="ui-table-columntoggle-popup ui-popup ui-body-inherit ui-overlay-shadow ui-corner-all" id="table-column-toggle-popup">
<fieldset class="ui-controlgroup ui-controlgroup-vertical ui-corner-all">
<div class="ui-controlgroup-controls ">
<div class="ui-checkbox">
<label class="ui-btn ui-corner-all ui-btn-null ui-btn-icon-left ui-checkbox-on ui-first-child">Rank</label>
<input type="checkbox" checked="">
</div>
<div class="ui-checkbox">
<label class="ui-btn ui-corner-all ui-btn-null ui-btn-icon-left ui-checkbox-on">Year</label>
<input type="checkbox" checked="">
</div>
<div class="ui-checkbox">
<label class="ui-btn ui-corner-all ui-btn-null ui-btn-icon-left ui-checkbox-on">Rotten Tomato Rating</label>
<input type="checkbox" checked="">
</div>
<div class="ui-checkbox">
<label class="ui-btn ui-corner-all ui-btn-null ui-btn-icon-left ui-checkbox-on ui-last-child">Reviews</label>
<input type="checkbox" checked="">
</div>
</div>
</fieldset>
</div>
</div>
CSS
/*****************************************
* base class
****************************************/
.ui-table {
border: 0;
border-collapse: collapse;
padding: 0;
width: 100%;
}
.ui-table th,
.ui-table td {
line-height: 1.5em;
text-align: left;
padding: .4em .5em;
vertical-align:top;
}
.ui-table th .ui-btn,
.ui-table td .ui-btn {
line-height: normal;
}
.ui-table th {
font-weight: bold;
}
.ui-table caption {
text-align: left;
margin-bottom: 1.4em;
opacity: .5;
}
/*****************************************
* columntoggle
****************************************/
.ui-table-columntoggle-btn {
float: right;
margin-bottom: .8em;
}
/* Remove top/bottom margins around the fieldcontain on check list */
.ui-table-columntoggle-popup fieldset {
margin:0;
}
.ui-table-columntoggle {
clear: both;
}
/* Hide all prioritized columns by default */
@media only all {
th.ui-table-priority-6,
td.ui-table-priority-6,
th.ui-table-priority-5,
td.ui-table-priority-5,
th.ui-table-priority-4,
td.ui-table-priority-4,
th.ui-table-priority-3,
td.ui-table-priority-3,
th.ui-table-priority-2,
td.ui-table-priority-2,
th.ui-table-priority-1,
td.ui-table-priority-1 {
display: none;
}
}
/* Preset breakpoints if ".ui-responsive" class added to table */
/* Show priority 1 at 320px (20em x 16px) */
@media screen and (min-width: 20em) {
.ui-table-columntoggle.ui-responsive th.ui-table-priority-1,
.ui-table-columntoggle.ui-responsive td.ui-table-priority-1 {
display: table-cell;
}
}
/* Show priority 2 at 480px (30em x 16px) */
@media screen and (min-width: 30em) {
.ui-table-columntoggle.ui-responsive th.ui-table-priority-2,
.ui-table-columntoggle.ui-responsive td.ui-table-priority-2 {
display: table-cell;
}
}
/* Show priority 3 at 640px (40em x 16px) */
@media screen and (min-width: 40em) {
.ui-table-columntoggle.ui-responsive th.ui-table-priority-3,
.ui-table-columntoggle.ui-responsive td.ui-table-priority-3 {
display: table-cell;
}
}
/* Show priority 4 at 800px (50em x 16px) */
@media screen and (min-width: 50em) {
.ui-table-columntoggle.ui-responsive th.ui-table-priority-4,
.ui-table-columntoggle.ui-responsive td.ui-table-priority-4 {
display: table-cell;
}
}
/* Show priority 5 at 960px (60em x 16px) */
@media screen and (min-width: 60em) {
.ui-table-columntoggle.ui-responsive th.ui-table-priority-5,
.ui-table-columntoggle.ui-responsive td.ui-table-priority-5 {
display: table-cell;
}
}
/* Show priority 6 at 1,120px (70em x 16px) */
@media screen and (min-width: 70em) {
.ui-table-columntoggle.ui-responsive th.ui-table-priority-6,
.ui-table-columntoggle.ui-responsive td.ui-table-priority-6 {
display: table-cell;
}
}
/* Unchecked manually: Always hide */
.ui-table-columntoggle th.ui-table-cell-hidden,
.ui-table-columntoggle td.ui-table-cell-hidden,
.ui-table-columntoggle.ui-responsive th.ui-table-cell-hidden,
.ui-table-columntoggle.ui-responsive td.ui-table-cell-hidden {
display: none;
}
/* Checked manually: Always show */
.ui-table-columntoggle th.ui-table-cell-visible,
.ui-table-columntoggle td.ui-table-cell-visible,
.ui-table-columntoggle.ui-responsive th.ui-table-cell-visible,
.ui-table-columntoggle.ui-responsive td.ui-table-cell-visible {
display: table-cell;
}
/*****************************************
* columntoggle
****************************************/
/*
Styles for the table columntoggle mode
*/
.ui-table-reflow td .ui-table-cell-label,
.ui-table-reflow th .ui-table-cell-label {
display: none;
}
/* Mobile first styles: Begin with the stacked presentation at narrow widths */
@media only all {
/* Hide the table headers */
.ui-table-reflow thead td,
.ui-table-reflow thead th {
display: none;
}
/* Show the table cells as a block level element */
.ui-table-reflow td,
.ui-table-reflow th {
text-align: left;
display: block;
}
/* Add a fair amount of top margin to visually separate each row when stacked */
.ui-table-reflow tbody th {
margin-top: 3em;
}
/* Make the label elements a percentage width */
.ui-table-reflow td .ui-table-cell-label,
.ui-table-reflow th .ui-table-cell-label {
padding: .4em;
min-width: 30%;
display: inline-block;
margin: -.4em 1em -.4em -.4em;
}
/* For grouped headers, have a different style to visually separate the levels by classing the first label in each col group */
.ui-table-reflow th .ui-table-cell-label-top,
.ui-table-reflow td .ui-table-cell-label-top {
display: block;
padding: .4em 0;
margin: .4em 0;
text-transform: uppercase;
font-size: .9em;
font-weight: normal;
}
}
/* Breakpoint to show as a standard table at 560px (35em x 16px) or wider */
@media ( min-width: 35em ) {
/* Fixes table rendering when switching between breakpoints in Safari <= 5. See https://github.com/jquery/jquery-mobile/issues/5380 */
.ui-table-reflow.ui-responsive {
display: table-row-group;
}
/* Show the table header rows */
.ui-table-reflow.ui-responsive td,
.ui-table-reflow.ui-responsive th,
.ui-table-reflow.ui-responsive tbody th,
.ui-table-reflow.ui-responsive tbody td,
.ui-table-reflow.ui-responsive thead td,
.ui-table-reflow.ui-responsive thead th {
display: table-cell;
margin: 0;
}
/* Hide the labels in each cell */
.ui-table-reflow.ui-responsive td .ui-table-cell-label,
.ui-table-reflow.ui-responsive th .ui-table-cell-label {
display: none;
}
}
/* Hack to make IE9 and WP7.5 treat cells like block level elements, scoped to ui-responsive class */
/* Applied in a max-width media query up to the table layout breakpoint so we don't need to negate this*/
@media ( max-width: 35em ) {
.ui-table-reflow.ui-responsive td,
.ui-table-reflow.ui-responsive th {
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
float: left;
clear: left;
}
}
Checklist
- Widget
_setOptions()
with all options dynamically settable- disabled
- mode (not settable)
- classes (not settable)
- columnBtnTheme
- columnPopupTheme
- columnBtnText
-
_destroy()
-
widget()
- avoid using
document
andwindow
directly - usesthis.document
andthis.window
- Demos page
- Demos page added to menu
- Api PR Table review jquery/api.jquerymobile.com#307
- update /js/index.php
- update /js/jquery.mobile.js
- check with download builder
- Full test coverage
- Device Testing
- Screen reader testing
- Full accessibility review by expert
- Add instructions to the upgrade guide