Table View

Table View

Table View organizes data into rows (of items) and columns (of item attributes). Tables make structured data easy to scan, compare, sort, and analyze. Tables can be embedded into other design patterns. Tables are familiar to users and often the correct choice for structured data, but be careful not to overuse tables. The table pattern should NOT be used if:

  • Users need to find patterns within a data set. Consider a Line Chart or a Bar Chart.
  • Users need to browse the data set without knowing exactly what to look for. Consider using a List View.

Default Table

Table View with Simple Expansion

Use a Table View with expanding rows when you want to display details in place without requiring drill-down to a new page. This is useful when you want to allow users to view details of an object without reloading the page, or when the detail information is small and does not require its own page.

Table with Expanding Rows

Table View

Table States

Table with a single row selected

  1. Toolbar: This version of the Table View is using a toolbar with filters and actions. Item count is also included in the toolbar on the right hand side.
  2. Column Visibility: Control what data displays by hiding and showing columns. See Column Visibility for more details about interaction with the control, and Toolbar for more examples of icon placement in the toolbar.
  3. Sorting: All columns are sortable. Click the column header to change the sort direction/order. The active column will be highlighted with a blue line above the column and blue text. The carat indicates the direction of the sort.
  4. Select Row(s): Click on the checkbox to select multiple rows in order to perform bulk actions on those rows simultaneously. Selecting a checkbox activates and highlights the row. This highlight is more prominent than the highlight for hovering over a row.
  5. Hover State: When the user hovers over a row, that row will be lightly highlighted and outlined. This helps the user to isolate the row, especially when clicking on items in the row.
  6. Inline Actions: Inline actions can be performed within a single row to manipulate the data. The most common 1-2 (max) actions are shown as a button with additional actions, if any, available via a dropdown menu. These actions should use words rather than icons for clarity. Please reference Kebab Menu for details.
  7. Row Shading: Use alternating row colors to help the user read the content of the table more easily.
  8. Unavailable (optional): Users can use “--” when the value of a cell should be rendered as unavailable.

Table States – continued

Table with a all rows selected

  1. Select All Rows: Selecting the checkbox in the header row selects all rows on the page. The total number of rows selected is shown near the table action buttons.
  2. Filtering (optional): Users can see results of simple filters here. Results include the item and results count, list of active filters (with ability to remove individual filters), and button to clear all filters.
  3. Column Reordering: Users can change the order of columns listed in the table. Click on a column header and drag it along the row of headers into the desired position. Note that only one column can be moved at a time.
  4. Bulk Item Actions: Bulk item action buttons are activated when multiple rows are selected. Some actions are available as both a table action and a bulk item action. The number of rows selected is shown near the table action buttons.

Column Visibility

Table with a column visibility menu active

  1. Column Visibility Icon: Displays in the toolbar in the sort control group after the filter control group. Sort controls may or may not be include in the toolbar. If sort controls are included, then column visibility is the last item in the sort control group.
  2. Column Visibility Dropdown: Lists all columns that can be displayed in the table.
    • Each list item is a checkbox with the column header as the label.
    • The list is sorted by the same order that the columns appear in the table.
    • When a checkbox is unchecked, the column is removed from the table, and the other columns expand to fill the width of the table. Alternatively, when a checkbox is selected, the column is added to the table.

Simple Expansion

Table with expandable rows

  1. Icon: Placing the caret at the front of the row signifies that this row is expandable. The caret points to the right when it is closed and down when it is expanded.
  2. Interaction: Hovering over a row highlights it. Single clicking the caret expands the row. If the row is open and the checkbox is selected, the selection color will take precedence.
  3. Expansion Panel: When the row is expanded, a panel is inserted between the bottom of the row and the top of the next row. All other content is pushed down the page. Content can be anything that is required to convey details of a selected object. If content exceeds the height of the panel, a scroll bar will be exposed.
  4. Close/Collapse: Clicking the Close icon will collapse the expansion panel and return the table to its original (collapsed) state. Alternatively, clicking on the caret again will have the same effect. Note: Use of the Close/Collapse icon is not advised if the content of the panel requires its full width.

States and Row Styling

The background color of a row will change to indicate current states. These are listed with corresponding hex color values below:

  • Hover - when the user hovers over a row, even when a row is expanded (#edf8ff)
  • Selected - when the user selects a row via selecting the checkbox (#0088ce)
  • Open - when a row is expanded (#def3ff)

Additional Notes about Behavior

  • Empty State: If no items exist in the table, display the Empty State pattern. If there are no items to display as the result of a null filter result, see the Filter pattern for more information about how to display this.
  • Loading State: If content is loading, display the Loading State pattern.
  • Pagination: Table View supports pagination. See Pagination for more details.


What’s not covered in the current design:

  • Simple sort.
  • Multi-column sort.
  • Sticky column headers.
  • Mobile design.

PatternFly Core Example


Data Tables

See http://datatables.net for complete data tables documentation.

Note: jquery.dataTables.js must occur in the HTML source before patternfly*.js.

1 of 3
0 of 0 selected
Rendering Engine Browser Platform(s) Engine Version CSS Grade Actions
per page
1-15 of 75
of 5

Reference Markup

<!-- Toolbar -->
<div class="row toolbar-pf table-view-pf-toolbar" id="toolbar1">
  <div class="col-sm-12">
    <form class="toolbar-pf-actions">
      <div class="form-group toolbar-pf-filter">
        <label class="sr-only" for="filter">Rendering Engine</label>
        <div class="input-group">
          <div class="input-group-btn">
            <button type="button" class="btn btn-default dropdown-toggle" id="filter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Rendering Engine <span class="caret"></span></button>
            <ul class="dropdown-menu">
              <li><a href="#" id="filter1">Rendering Engine</a></li>
              <li><a href="#" id="filter2">Browser</a></li>
              <li><a href="#" id="filter3">Platform(s)</a></li>
              <li><a href="#" id="filter4">Engine Version</a></li>
              <li><a href="#" id="filter5">CSS Grade</a></li>
            </ul>
          </div>
          <input type="text" class="form-control" placeholder="Filter By Rendering Engine..." autocomplete="off" id="filterInput">
        </div>
      </div>
      <div class="form-group">
        <button class="btn btn-default" type="button" id="deleteRows1">Delete Rows</button>
        <button class="btn btn-default" type="button" id="restoreRows1" disabled>Restore Rows</button>
        <div class="dropdown btn-group  dropdown-kebab-pf">
  <button class="btn btn-link dropdown-toggle" type="button" id="dropdownKebab" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
    <span class="fa fa-ellipsis-v"></span>
  </button>
  <ul class="dropdown-menu " aria-labelledby="dropdownKebab">
    <li><a href="#">Action</a></li>
    <li><a href="#">Another Action</a></li>
    <li><a href="#">Something Else Here</a></li>
    <li role="separator" class="divider"></li>
    <li><a href="#">Separated Link</a></li>
  </ul>
</div>

      </div>
      <div class="toolbar-pf-action-right">
        <div class="form-group toolbar-pf-find">
          <button class="btn btn-link btn-find" type="button">
            <span class="fa fa-search"></span>
          </button>
          <div class="find-pf-dropdown-container">
            <input type="text" class="form-control" id="find" placeholder="Find By Keyword...">
            <div class="find-pf-buttons">
              <span class="find-pf-nums">1 of 3</span>
              <button class="btn btn-link" type="button">
                <span class="fa fa-angle-up"></span>
              </button>
              <button class="btn btn-link" type="button">
                <span class="fa fa-angle-down"></span>
              </button>
              <button class="btn btn-link btn-find-close" type="button">
                <span class="pficon pficon-close"></span>
              </button>
            </div>
          </div>
        </div>
      </div>
    </form>
    <div class="row toolbar-pf-results">
      <div class="col-sm-9">
        <div class="hidden">
          <h5>0 Results</h5>
          <p>Active filters:</p>
          <ul class="list-inline"></ul>
          <p><a href="#">Clear All Filters</a></p>
        </div>
      </div>
      <div class="col-sm-3 table-view-pf-select-results">
        <strong>0</strong> of <strong>0</strong> selected
      </div>
    </div>
  </div>
</div>

<!-- Table HTML -->
<table class="table table-striped table-bordered table-hover" id="table1">
  <thead>
    <tr>
      <th><label class="sr-only" for="selectAll">Select all rows</label><input type="checkbox" id="selectAll" name="selectAll"></th>
      <th>Rendering Engine</th>
      <th>Browser</th>
      <th>Platform(s)</th>
      <th>Engine Version</th>
      <th>CSS Grade</th>
      <th colspan="2">Actions</th>
    </tr>
  </thead>
</table>

<form class="content-view-pf-pagination table-view-pf-pagination clearfix" id="pagination1">
  <div class="form-group">
    <select class="selectpicker pagination-pf-pagesize">
      <option value="6">6</option>
      <option value="10" >10</option>
      <option value="15" selected="selected">15</option>
      <option value="25">25</option>
      <option value="50">50</option>
    </select>
    <span>per page</span>
  </div>
  <div class="form-group">
    <span><span class="pagination-pf-items-current">1-15</span> of <span class="pagination-pf-items-total">75</span></span>
    <ul class="pagination pagination-pf-back">
      <li class="disabled"><a href="#" title="First Page"><span class="i fa fa-angle-double-left"></span></a></li>
      <li class="disabled"><a href="#" title="Previous Page"><span class="i fa fa-angle-left"></span></a></li>
    </ul>
    <label for="pagination1-page" class="sr-only">Current Page</label>
    <input class="pagination-pf-page" type="text" value="1" id="pagination1-page"/>
    <span>of <span class="pagination-pf-pages">5</span></span>
    <ul class="pagination pagination-pf-forward">
      <li><a href="#" title="Next Page"><span class="i fa fa-angle-right"></span></a></li>
      <li><a href="#" title="Last Page"><span class="i fa fa-angle-double-right"></span></a></li>
    </ul>
  </div>
</form>

<!-- Blank Slate HTML -->
<div class="blank-slate-pf table-view-pf-empty hidden" id="emptyState1">
  <div class="blank-slate-pf-icon">
    <span class="pficon pficon pficon-add-circle-o"></span>
  </div>
  <h1>
    Empty State Title
  </h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  </p>
  <p>
    Learn more about this <a href="#">in the documentation</a>.
  </p>
  <div class="blank-slate-pf-main-action">
    <button class="btn btn-primary btn-lg"> Main Action </button>
  </div>
  <div class="blank-slate-pf-secondary-action">
    <button class="btn btn-default">Secondary Action</button>
    <button class="btn btn-default">Secondary Action</button>
  </div>
</div>

<script>
$(document).ready(function() {

// JSON data for Table View
var dataSet = [{
  engine: "Trident",
  browser: "Internet Explorer 4.0",
  platforms: "Win 95+",
  version: "4",
  grade: "X"
},{
  engine: "Trident",
  browser: "Internet Explorer 5.0",
  platforms: "Win 95+",
  version: "5",
  grade: "C"
}, {
  engine: "Trident",
  browser: "Internet Explorer 5.5",
  platforms: "Win 95+",
  version: "5.5",
  grade: "A"
}, {
  engine: "Trident",
  browser: "Internet Explorer 6",
  platforms: "Win 98+",
  version: "6",
  grade: "A"
}, {
  engine: "Trident",
  browser: "Internet Explorer 7",
  platforms: "Win XP SP2+",
  version: "7",
  grade: "A"
}, {
  engine: "Trident",
  browser: "AOL browser (AOL desktop)",
  platforms: "Win XP",
  version: "6",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Firefox 1.0",
  platforms: "Win 98+ / OSX.2+",
  version: "1.7",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Firefox 1.5",
  platforms: "Win 98+ / OSX.2+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Firefox 2.0",
  platforms: "Win 98+ / OSX.2+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Firefox 3.0",
  platforms: "Win 2k+ / OSX.3+",
  version: "1.9",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Camino 1.0",
  platforms: "OSX.2+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Camino 1.5",
  platforms: "OSX.3+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Netscape 7.2",
  platforms: "Win 95+ / Mac OS 8.6-9.2",
  version: "1.7",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Netscape Browser 8",
  platforms: "Win 98SE+",
  version: "1.7",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Netscape Navigator 9",
  platforms: "Win 98+ / OSX.2+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.0",
  platforms: "Win 95+ / OSX.1+",
  version: "1",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.1",
  platforms: "Win 95+ / OSX.1+",
  version: "1.1",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.2",
  platforms: "Win 95+ / OSX.1+",
  version: "1.2",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.3",
  platforms: "Win 95+ / OSX.1+",
  version: "1.3",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.4",
  platforms: "Win 95+ / OSX.1+",
  version: "1.4",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.5",
  platforms: "Win 95+ / OSX.1+",
  version: "1.5",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.6",
  platforms: "Win 95+ / OSX.1+",
  version: "1.6",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.7",
  platforms: "Win 98+ / OSX.1+",
  version: "1.7",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Mozilla 1.8",
  platforms: "Win 98+ / OSX.1+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Seamonkey 1.1",
  platforms: "Win 98+ / OSX.2+",
  version: "1.8",
  grade: "A"
}, {
  engine: "Gecko",
  browser: "Epiphany 2.20",
  platforms: "Gnome",
  version: "1.8",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "Safari 1.2",
  platforms: "OSX.3",
  version: "125.5",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "Safari 1.3",
  platforms: "OSX.3",
  version: "312.8",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "Safari 2.0",
  platforms: "OSX.4+",
  version: "419.3",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "Safari 3.0",
  platforms: "OSX.4+",
  version: "522.1",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "OmniWeb 5.5",
  platforms: "OSX.4+",
  version: "420",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "iPod Touch / iPhone",
  platforms: "iPod",
  version: "420.1",
  grade: "A"
}, {
  engine: "Webkit",
  browser: "S60",
  platforms: "S60",
  version: "413",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 7.0",
  platforms: "Win 95+ / OSX.1+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 7.5",
  platforms: "Win 95+ / OSX.2+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 8.0",
  platforms: "Win 95+ / OSX.2+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 8.5",
  platforms: "Win 95+ / OSX.2+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 9.0",
  platforms: "Win 95+ / OSX.3+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 9.2",
  platforms: "Win 88+ / OSX.3+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera 9.5",
  platforms: "Win 88+ / OSX.3+",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Opera for Wii",
  platforms: "Wii",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Nokia N800",
  platforms: "N800",
  version: "-",
  grade: "A"
}, {
  engine: "Presto",
  browser: "Nintendo DS browser",
  platforms: "Nintendo DS",
  version: "8.5",
  grade: "C/A<sup>1</sup>"
}, {
  engine: "KHTML",
  browser: "Konqureror 3.1",
  platforms: "KDE 3.1",
  version: "3.1",
  grade: "C"
}, {
  engine: "KHTML",
  browser: "Konqureror 3.3",
  platforms: "KDE 3.3",
  version: "3.3",
  grade: "A"
}, {
  engine: "KHTML",
  browser: "Konqureror 3.5",
  platforms: "KDE 3.5",
  version: "3.5",
  grade: "A"
}, {
  engine: "Tasman",
  browser: "Internet Explorer 4.5",
  platforms: "Mac OS 8-9",
  version: "-",
  grade: "X"
}, {
  engine: "Tasman",
  browser: "Internet Explorer 5.1",
  platforms: "Mac OS 7.6-9",
  version: "1",
  grade: "C"
}, {
  engine: "Tasman",
  browser: "Internet Explorer 5.2",
  platforms: "Mac OS 8-X",
  version: "1",
  grade: "C"
}, {
  engine: "Misc",
  browser: "NetFront 3.1",
  platforms: "Embedded devices",
  version: "-",
  grade: "C"
}, {
  engine: "Misc",
  browser: "NetFront 3.4",
  platforms: "Embedded devices",
  version: "-",
  grade: "A"
}, {
  engine: "Misc",
  browser: "Dillo 0.8",
  platforms: "Embedded devices",
  version: "-",
  grade: "X"
}, {
  engine: "Misc",
  browser: "Links",
  platforms: "Text only",
  version: "-",
  grade: "X"
}, {
  engine: "Misc",
  browser: "Lynx",
  platforms: "Text only",
  version: "-",
  grade: "X"
}, {
  engine: "Misc",
  browser: "IE Mobile",
  platforms: "Windows Mobile 6",
  version: "-",
  grade: "C"
}, {
  engine: "Misc",
  browser: "PSP browser",
  platforms: "PSP",
  version: "-",
  grade: "C"
}, {
  engine: "Other browsers",
  browser: "All others",
  platforms: "-",
  version: "-",
  grade: "U"
}];

// DataTable Config
$("#table1").DataTable({
  columns: [
    { data: null,
      className: "table-view-pf-select",
      render: function (data, type, full, meta) {
        // Select row checkbox renderer
        var id = "select" + meta.row;
        return '<label class="sr-only" for="' + id + '">Select row ' + meta.row +
          '</label><input type="checkbox" id="' + id + '" name="' + id + '">';
      },
      sortable: false
    },
    { data: "engine" },
    { data: "browser" },
    { data: "platforms" },
    { data: "version" },
    { data: "grade"},
    { data: null,
      className: "table-view-pf-actions",
      render: function (data, type, full, meta) {
        // Inline action button renderer
        return '<div class="table-view-pf-btn"><button class="btn btn-default" type="button">Actions</button></div>';
      }
    }, {
      data: null,
      className: "table-view-pf-actions",
      render: function (data, type, full, meta) {
        // Inline action kebab renderer
        return '<div class="dropdown dropdown-kebab-pf">' +
          '<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">' +
          '<span class="fa fa-ellipsis-v"></span></button>' +
          '<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight">' +
          '<li><a href="#">Action</a></li>' +
          '<li><a href="#">Another action</a></li>' +
          '<li><a href="#">Something else here</a></li>' +
          '<li role="separator" class="divider"></li>' +
          '<li><a href="#">Separated link</a></li></ul></div>';
      }
    }
  ],
  data: dataSet,
  dom: "t",
  language: {
    zeroRecords: "No records found"
  },
  order: [[ 1, 'asc' ]],
  pfConfig: {
    emptyStateSelector: "#emptyState1",
    filterCaseInsensitive: true,
    filterCols: [
      null,
      {
        default: true,
        optionSelector: "#filter1",
        placeholder: "Filter By Rendering Engine..."
      }, {
        optionSelector: "#filter2",
        placeholder: "Filter By Browser..."
      }, {
        optionSelector: "#filter3",
        placeholder: "Filter By Platform(s)..."
      }, {
        optionSelector: "#filter4",
        placeholder: "Filter By Engine Version..."
      }, {
        optionSelector: "#filter5",
        placeholder: "Filter By CSS Grade..."
      }
    ],
    paginationSelector: "#pagination1",
    toolbarSelector: "#toolbar1",
    selectAllSelector: 'th:first-child input[type="checkbox"]',
    colvisMenuSelector: '.table-view-pf-colvis-menu'
  },
  select: {
    selector: 'td:first-child input[type="checkbox"]',
    style: 'multi'
  },
});

/**
 * Utility to show empty Table View
 *
 * @param {object} config - Config properties associated with a Table View
 * @param {object} config.data - Data set for DataTable
 * @param {string} config.deleteRowsSelector - Selector for delete rows control
 * @param {string} config.restoreRowsSelector - Selector for restore rows control
 * @param {string} config.tableSelector - Selector for the HTML table
 */
var emptyTableViewUtil = function (config) {
  var self = this;

  this.dt = $(config.tableSelector).DataTable(); // DataTable
  this.deleteRows = $(config.deleteRowsSelector); // Delete rows control
  this.restoreRows = $(config.restoreRowsSelector); // Restore rows control

  // Handle click on delete rows control
  this.deleteRows.on('click', function() {
    self.dt.clear().draw();
    $(self.restoreRows).prop("disabled", false);
  });

  // Handle click on restore rows control
  this.restoreRows.on('click', function() {
    self.dt.rows.add(config.data).draw();
    $(this).prop("disabled", true);
  });

  // Initialize restore rows
  if (this.dt.data().length === 0) {
    $(this.restoreRows).prop("disabled", false);
  }
};

// Initialize empty Table View util
new emptyTableViewUtil({
  data: dataSet,
  deleteRowsSelector: "#deleteRows1",
  restoreRowsSelector: "#restoreRows1",
  tableSelector: "#table1"
});

/**
 * Utility to find items in Table View
 */
var findTableViewUtil = function (config) {
  // Upon clicking the find button, show the find dropdown content
  $(".btn-find").click(function () {
    $(this).parent().find(".find-pf-dropdown-container").toggle();
  });

  // Upon clicking the find close button, hide the find dropdown content
  $(".btn-find-close").click(function () {
    $(".find-pf-dropdown-container").hide();
  });
};

// Initialize find util
new findTableViewUtil();

});
</script>


<script src="/components/datatables/media/js/jquery.dataTables.js"></script>
<script>
// Initialize Datatables
$(document).ready(function() {
$('.datatable').dataTable();
});
</script>