Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Table: Review widget #7360

Closed
14 of 20 tasks
gabrielschulhof opened this issue May 1, 2014 · 7 comments
Closed
14 of 20 tasks

Table: Review widget #7360

gabrielschulhof opened this issue May 1, 2014 · 7 comments

Comments

@gabrielschulhof
Copy link

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 the data-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 and window directly - uses this.document and this.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
@gabrielschulhof gabrielschulhof added this to the 1.5.0 milestone May 1, 2014
@gabrielschulhof gabrielschulhof self-assigned this May 1, 2014
@frequent
Copy link
Contributor

frequent commented May 2, 2014

@gabrielschulhof : have you ever considered building the whole widget in memory/detached?

@arschmitz
Copy link
Contributor

Defaults is not an option and should not be listed as such its a flag that prevents the options from being read

@arschmitz
Copy link
Contributor

@gabrielschulhof I know you have not changed this from the current implementation but the classes option is not being used correctly here this should be a mapping of structural classes to theme classes where the theme classes can be overridden but structural classes are non optional as they are often required by the widget for normal operation. see https://github.com/jquery/jquery-ui/pull/790/files for how this should be implemented as an option.

@arschmitz
Copy link
Contributor

@gabrielschulhof also can you please update this ticket based on discussions about column toggle popup

@gabrielschulhof
Copy link
Author

This ticket is not fixed until the columntoggle button opens the popup via .popup( "open" ) rather than via the central click routing.

@apsdehal
Copy link
Contributor

apsdehal commented May 8, 2016

@cgack I assume this can be safely closed now?

@arschmitz
Copy link
Contributor

Yes this was landed in 1.5-dev

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants