Column-Toggle Table Widget


Column-Toggle Table Widgetversion added: 1.3

Description: Creates a responsive table in column toggle mode

QuickNavExamples

Methods

Events

This table mode automatically hides less important columns at narrower widths and surfaces a button to open a menu that allows the user to choose what columns they want to see. In this mode, the author attempts to define which columns are most important to show across various widths by assigning a priority to each column.

A user may choose to check as many columns as they want by tapping the "Columns..." button to open the column chooser popup. The popup contains a dynamically generated list of columns based on the table markup that can be checked and unchecked to adjust the visible columns.

Applying column chooser mode to a table

The column chooser mode requires a table element with two attributes: data-role="table" and data-mode="columntoggle". An ID attribute is also required on the table to associate it with the column chooser popup menu.

1
<table data-role="table" data-mode="columntoggle" id="my-table">

How column toggle mode works

The plugin automates a few key things: it injects the column chooser button, and generates the popup with check list of columns that can be hidden or shown by the user. The list of columns in the chooser menu is populated by parsing the values (or abbr title) of the first row of header (TH) elements. Only headers that have a data-priority attribute are included in the column chooser; headers without this attribute won't made available in the chooser to allow developers to identify critical columns that shouldn't be hidden. If columns are hidden via responsive media queries, these will be unchecked in the chooser to reflect the current column visibility.

The automatic column hiding behavior is accomplished by CSS media queries that hide or show columns based on priority levels at various screen widths. Since each site will have different content and column configurations, we provide a simple media query block that you can copy, paste and customize for each project. This is explained in detail below.

The priorities assigned to headers and media queries used to hide columns act as a sensible default for showing the most important columns that will fit on a device. The column chooser menu gives users the ability to override these defaults and choose which columns they want to see. These user preferences take precedence over the priority mappings so if a column is manually checked, it will remain visible across all screen widths until the page is refreshed.

Because of the flexibility this plugin provides, it's possible for users to introduce horizontal scrolling if the data in each column is long or if many columns are selected to be shown on a smaller screen.

Setting column priority

The table works by hiding and showing columns based on two inputs: available screen width or by the user checking and unchecking which columns to display in a column picker popup. Add data-priority attributes to each of the table headers of columns you want to responsively display and assign a priority (1 = highest, 6 = lowest). Any table header given a priority will be available in the column picker menu.

To make a column persistent so it's not available for hiding, omit the data-priority attribute. This will make the column visible at all widths and won't be available in the column chooser menu.

1
2
3
4
<th>I'm critical and can't be removed</th>
<th data-priority="1">I'm very important</th>
<th data-priority="3">I'm somewhat</th>
<th data-priority="5">I'm less important</th>

Behind the scenes, the plugin will apply classes to each cell that map to the priority set in the data attribute on the header. For example, if a table heading has a data-priority="3" attribute, every cell in that column will assigned a ui-table-priority-3 class once enhanced. These classes are then used in media queries to hide and show columns based on screen width (see below).

1
<td class="ui-table-priority-3">97%</td>

You may use any priority naming convention and assign as many (or few) levels of priority for the columns. The plugin simply generates class names based on the values in the data-priority attribute so even though we default to using a numeric system of 1-6, any naming convention is possible.

For example, if a priority of data-priority="critical" is added to the heading, a class of ui-table-priority-critial will be applied to each cell in that column. If a priority is assigned, the column will be made available for the toggling in the column menu and adds the classes to each cell, the rest of the styling and media query creation is up to you write in your custom stylesheet.

It is important to note that you are required to wrap your table headers in a <thead> ... </thead> block, and the table body in a <tbody> ... </tbody> block, as shown in the full demo Example.

Making the table responsive

The styles for the all priority columns (1-6) start as display:none in the structure stylesheet since we're taking a mobile-first approach to our styles. This means that only columns that should be persistent are visible in the styles to start.

The framework does not automatically include the the media queries to progressively display columns at wider widths. We do this to make it easier for developers to customize the media query widths for each priority level.

Media queries add the responsive behavior to show and hide columns by priority. Each media query is written using min-width widths so they build on top of each other. The widths are set in ems so they respond to font size changes. To calculate a pixel withs in em's, divide the target width by 16 (pixels) - it's that easy.

Inside each media query, we override the display:none style properties set on all the priority columns in the basic styles to display:table-cell so they become visible again and act as a table.

To customize the breakpoints, copy the following style block into your custom style overrides and adjust the min-width media query values for each priority level to specify where various priority columns should appear.

In the example styles below for a my-custom-class class on the table, the priority 1 columns are shown first, at widths above 20em (320px), then priority 2 kicks in above 30em (480px) and so on up to wide desktop widths with priority 6. Feel free to change these breakpoints in your stylesheet and choose how many priority levels you'd like to use.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Show priority 1 at 320px (20em x 16px) */
@media screen and (min-width: 20em) {
.my-custom-class th.ui-table-priority-1,
.my-custom-class td.ui-table-priority-1 {
display: table-cell;
}
}
/* Show priority 2 at 480px (30em x 16px) */
@media screen and (min-width: 30em) {
.my-custom-class th.ui-table-priority-2,
.my-custom-class td.ui-table-priority-2 {
display: table-cell;
}
}
...more breakpoints...

Due to CSS specificity, you will also need to include the class definitions for the hidden and visible states after the custom breakpoints in your custom stylesheet so be sure to include these as well:

1
2
3
4
5
6
7
8
9
10
11
/* Manually hidden */
.my-custom-class th.ui-table-cell-hidden,
.my-custom-class td.ui-table-cell-hidden {
display: none;
}
/* Manually shown */
.my-custom-class th.ui-table-cell-visible,
.my-custom-class td.ui-table-cell-visible {
display: table-cell;
}

Applying a preset breakpoint

Even though we strongly encourage you to write custom breakpoints yourself, the framework includes a set of pre-configured breakpoints for each of the six priority levels that you can use if they happen work well for your content.

These breakpoints can applied by adding a class="ui-responsive" to the table element. Here is an example of a table with this class added:

1
<table data-role="table" class="ui-responsive" data-mode="columntoggle" id="my-table">

The six preset breakpoints classes included in the column toggle stylesheet use regular increments of 10em (160 pixels). Here is a summary of the breakpoints assigned to each priority in the preset styles:

data-priority="1"
Displays the column at 320px (20em)
data-priority="2"
Displays the column at 480px (30em)
data-priority="3"
Displays the column at 640px (40em)
data-priority="4"
Displays the column at 800px (50em)
data-priority="5"
Displays the column at 960px (60em)
data-priority="6"
Displays the column at 1,120px (70em)

If these preset breakpoints don't work for your content and layout needs, we recommend that you create custom breakpoints to fine tune the styles.

Working with the column menu classes

When the column chooser menu opens, the column checkboxes will be checked or unchecked based on the visibility of each column based on the media queries so it accurately reflects what is being seen. These media queries to hide or show columns act as sensible defaults for what columns should be shown based on the developer's understanding of the column importance and data values. The chooser menu allows the user to have control of the table presentation so this takes precedence over the default display.

If an unchecked column checkbox is checked by the user, they now take control of the column. Until the page is refreshed, the visibility of that column will now always be visible, even if the screen is re-sized. Behind the scenes, a class of ui-table-cell-visible is added to all the cells in that column to ensure they override any visibility set via media queries.

The same idea applies when a column is unchecked: from then on, the column won't be seen at any width because the class of ui-table-cell-hidden is added to each of the cells in that column.

Styling the button and column chooser popup

The column chooser popup is opened via a button that is generated by the framework. The button's text is "Columns..." by default but can be set by adding the data-column-btn-text attribute to the table to the text string you want in the button. The button will inherit the theme from the content area, just like all buttons, but the theme can be set manually by adding the data-column-btn-theme attribute to any swatch letter in your theme.

This button is injected directly before the table element and has basic styles to align it to the right but you may want to further customize the appearance of this button. To style all these buttons across your site, key off the ui-table-columntoggle-btn structural class on this link.

To target styles against only a specific button, use the unique href value that is generated to target a specific column chooser button. For example, a table with an ID of movie-table will generate a popup with an ID of movie-table-popup so a CSS selector of a[href="#movie-table-popup"] will target only the column popup button for this specific table.

The theme for the column chooser popup can be set by adding the data-column-popup-theme attribute to the table and specifying any swatch letter in your theme. For custom styles or scripting, all the column chooser popups can be targeted by using the ui-table-columntoggle-popup structural class added to these popups. To customize a single popup, use the generated ID based on the table ID that added to each specific popup (such as #movie-table-popup) to target a specific popup.

Working with grouped column headers

It's fairly common to need to logically group multiple columns together under a heading group for financial or scientific data. The framework can support the most simple version of this by allowing for two rows of table headers (TH), with the first row containing simple colspan attributes to group the columns below. In this configuration, the framework will parse the first row only for the priority and expose these heading groups as the options in the column chooser popup. In this configuration, the second heading will not be exposed as columns that can be hidden or shown independently of the groupings in the chooser.

Providing pre-rendered markup

You can improve the load time of your page by providing the markup that the table-columntoggle widget would normally create during its initialization.

By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the table-columntoggle widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.

When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.

The columntoggle table places an anchor before the table that invokes a popup listing the columns available for showing/hiding. The ID of the popup and thus the href of the anchor should be the ID of the table suffixed by the string -popup. You may separately pre-enhance the popup widget, or you may allow autoinitialization to enhance it.

The popup widget must contain a single controlgroup widget which in turn contains all the checkboxes representing the columns of the table.

In the example below the parameter data-column-btn-theme="b" is added to the table explicitly to indicate that the theme applied to the "Columns..." button is not the default (null).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<div data-role="popup" id="table-column-toggle-popup" class="ui-table-columntoggle-popup">
<fieldset data-role="controlgroup">
<label>Rank<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
<label>Year<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
<label>Rotten Tomato Rating<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
<label>Reviews<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
</fieldset>
</div>
<a href="#table-column-toggle-popup" class="ui-table-columntoggle-btn ui-btn ui-btn-b ui-corner-all ui-shadow ui-mini" data-rel="popup">Columns...</a>
<table data-role="table" id="table-column-toggle" data-mode="columntoggle" data-enhanced="true" class="ui-table ui-table-columntoggle" data-column-btn-theme="b">
<thead>
<tr>
<th data-priority="2" data-colstart="1" class="ui-table-priority-2 ui-table-cell-visible">Rank</th>
<th data-colstart="2">Movie Title</th>
<th data-priority="3" data-colstart="3" class="ui-table-priority-3 ui-table-cell-visible">Year</th>
<th data-priority="1" data-colstart="4" class="ui-table-priority-1 ui-table-cell-visible"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th data-priority="5" data-colstart="5" class="ui-table-priority-5 ui-table-cell-visible">Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th class="ui-table-priority-2 ui-table-cell-visible">1</th>
<td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td>
<td class="ui-table-priority-3 ui-table-cell-visible">1941</td>
<td class="ui-table-priority-1 ui-table-cell-visible">100%</td>
<td class="ui-table-priority-5 ui-table-cell-visible">74</td>
</tr>
<tr>
<th class="ui-table-priority-2 ui-table-cell-visible">2</th>
<td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td>
<td class="ui-table-priority-3 ui-table-cell-visible">1942</td>
<td class="ui-table-priority-1 ui-table-cell-visible">97%</td>
<td class="ui-table-priority-5 ui-table-cell-visible">64</td>
</tr>
</tbody>
</table>

Options

classes.columnBtn 

Type: String
Default: "ui-table-columntoggle-btn"
Class assigned to the column toggle button.

Note: The reflow mode has one option, classes, which is only configurable via JavaScript because it expects an object literal value. The classes option has two properties that define the structural classnames that the plugin uses.

classes.columnToggleTable 

Type: String
Default: "ui-table-columntoggle"
Class assigned to the table.

Note: The reflow mode has one option, classes, which is only configurable via JavaScript because it expects an object literal value. The classes option has two properties that define the structural classnames that the plugin uses.

classes.popup 

Type: String
Default: "ui-table-columntoggle-popup"
Class assigned to the column chooser popup.

Note: The reflow mode has one option, classes, which is only configurable via JavaScript because it expects an object literal value. The classes option has two properties that define the structural classnames that the plugin uses.

classes.priorityPrefix 

Type: String
Default: "ui-table-priority-"
Class prefix added to each cell in a column. This string is appended to the priority value set on the headers.

Note: The reflow mode has one option, classes, which is only configurable via JavaScript because it expects an object literal value. The classes option has two properties that define the structural classnames that the plugin uses.

columnBtnText 

Type: String
Default: default: "Columns..."
Sets the theme for the column chooser button. Set to any valid swatch letter in your theme.

This option is also exposed as a data attribute:data-column-btn-text="Show columns".

Code examples:

Initialize the table-columntoggle with the columnBtnText option specified:

1
2
3
$( ".selector" ).table-columntoggle({
columnBtnText: "Show columns"
});

Get or set the columnBtnText option, after initialization:

1
2
3
4
5
// Getter
var columnBtnText = $( ".selector" ).table-columntoggle( "option", "columnBtnText" );
// Setter
$( ".selector" ).table-columntoggle( "option", "columnBtnText", "Show columns" );

columnBtnTheme 

Type: String
Default: null
Sets the theme for the column chooser button. Set to any valid swatch letter in your theme.

This option is also exposed as a data attribute:data-column-btn-theme="b".

Code examples:

Initialize the table-columntoggle with the columnBtnTheme option specified:

1
2
3
$( ".selector" ).table-columntoggle({
columnBtnTheme: "b"
});

Get or set the columnBtnTheme option, after initialization:

1
2
3
4
5
// Getter
var columnBtnTheme = $( ".selector" ).table-columntoggle( "option", "columnBtnTheme" );
// Setter
$( ".selector" ).table-columntoggle( "option", "columnBtnTheme", "b" );

columnPopupTheme 

Type: String
Default: null
Sets the theme for the column chooser popup checkboxes. Set to any valid swatch letter in your theme.

This option is also exposed as a data attribute:data-popup-theme="a".

Code examples:

Initialize the table-columntoggle with the columnPopupTheme option specified:

1
2
3
$( ".selector" ).table-columntoggle({
columnPopupTheme: "a"
});

Get or set the columnPopupTheme option, after initialization:

1
2
3
4
5
// Getter
var columnPopupTheme = $( ".selector" ).table-columntoggle( "option", "columnPopupTheme" );
// Setter
$( ".selector" ).table-columntoggle( "option", "columnPopupTheme", "a" );

enhanced 

Type: Boolean
Default: false
Indicates that the markup necessary for a table-columntoggle widget has been provided as part of the original markup.

This option is also exposed as a data attribute: data-enhanced="true".

Code examples:

Initialize the table-columntoggle with the enhanced option specified:

1
2
3
$( ".selector" ).table-columntoggle({
enhanced: true
});

Get or set the enhanced option, after initialization:

1
2
3
4
5
// Getter
var enhanced = $( ".selector" ).table-columntoggle( "option", "enhanced" );
// Setter
$( ".selector" ).table-columntoggle( "option", "enhanced", true );

Methods

refresh()Returns: jQuery (plugin only)

Updates the labels in the cells.
  • This method does not accept any arguments.
Code examples:

Invoke the refresh method:

1
$( ".selector" ).table-columntoggle( "refresh" );

Events

create( event, ui )Type: tablecreate

Since this plugin is written as an extension to the core table plugin, it binds to the tablecreate event but does not issue any additional events.

Note: The ui object is empty but included for consistency with other events.

Code examples:

Initialize the table-columntoggle with the create callback specified:

1
2
3
$( ".selector" ).table-columntoggle({
create: function( event, ui ) {}
});

Bind an event listener to the tablecreate event:

1
$( ".selector" ).on( "tablecreate", function( event, ui ) {} );

Example:

A basic example of a responsive table in column toggle mode.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>table-columntoggle demo</title>
<link rel="stylesheet" href="//code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<div data-role="page" id="page1">
<div data-role="header">
<h1>jQuery Mobile Example</h1>
</div>
<div role="main" class="ui-content">
<table data-role="table" id="table-column-toggle" data-mode="columntoggle" class="ui-responsive table-stroke">
<thead>
<tr>
<th data-priority="2">Rank</th>
<th>Movie Title</th>
<th data-priority="3">Year</th>
<th data-priority="1"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th data-priority="5">Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td>
<td>1941</td>
<td>100%</td>
<td>74</td>
</tr>
<tr>
<th>2</th>
<td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td>
<td>1942</td>
<td>97%</td>
<td>64</td>
</tr>
<tr>
<th>3</th>
<td><a href="http://en.wikipedia.org/wiki/The_Godfather" data-rel="external">The Godfather</a></td>
<td>1972</td>
<td>97%</td>
<td>87</td>
</tr>
<tr>
<th>4</th>
<td><a href="http://en.wikipedia.org/wiki/Gone_with_the_Wind_(film)" data-rel="external">Gone with the Wind</a></td>
<td>1939</td>
<td>96%</td>
<td>87</td>
</tr>
<tr>
<th>5</th>
<td><a href="http://en.wikipedia.org/wiki/Lawrence_of_Arabia_(film)" data-rel="external">Lawrence of Arabia</a></td>
<td>1962</td>
<td>94%</td>
<td>87</td>
</tr>
<tr>
<th>6</th>
<td><a href="http://en.wikipedia.org/wiki/Dr._Strangelove" data-rel="external">Dr. Strangelove Or How I Learned to Stop Worrying and Love the Bomb</a></td>
<td>1964</td>
<td>92%</td>
<td>74</td>
</tr>
<tr>
<th>7</th>
<td><a href="http://en.wikipedia.org/wiki/The_Graduate" data-rel="external">The Graduate</a></td>
<td>1967</td>
<td>91%</td>
<td>122</td>
</tr>
<tr>
<th>8</th>
<td><a href="http://en.wikipedia.org/wiki/The_Wizard_of_Oz_(1939_film)" data-rel="external">The Wizard of Oz</a></td>
<td>1939</td>
<td>90%</td>
<td>72</td>
</tr>
<tr>
<th>9</th>
<td><a href="http://en.wikipedia.org/wiki/Singin%27_in_the_Rain" data-rel="external">Singin' in the Rain</a></td>
<td>1952</td>
<td>89%</td>
<td>85</td>
</tr>
<tr>
<th>10</th>
<td class="title"><a href="http://en.wikipedia.org/wiki/Inception" data-rel="external">Inception</a></td>
<td>2010</td>
<td>84%</td>
<td>78</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

Demo: