Data Table
- Data Table Layout
- Pagination Footer
- Selectable Rows
- Inputs In Table Head
- Table Title/Header
- Sortable
- Collapsible
- Data Table App Methods
- Data Table Parameters
- Data Table Events
- CSS Variables
Data tables display sets of raw data. They usually appear in desktop enterprise products
Data Table Layout
Common Data Table layout could be treated as the following:
<div class="data-table">
<table>
<thead>
<tr>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
...
<th class="medium-only">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
...
<td class="medium-only">I like it!</td>
</tr>
...
</tbody>
</table>
</div>
Within Card:
<div class="data-table card">
<table>
<thead>
...
</thead>
<tbody>
...
</tbody>
</table>
</div>
Where
data-table
- main Data Table wrapper. Requiredtable
- table itself. Requiredthead
- table headtbody
- table body. Requiredlabel-cell
- main label cell (only one such kind of cell per row, usually first cell)numeric-cell
- cell to display numeric data (right-aligned)medium-only
- additional class to show this cell/column only when app width >= 768px. For full set of such responsive classes check Grid docs. They arexsmall-only
,small-only
,medium-only
,large-only
,xlarge-only
.
Pagination Footer
<div class="card data-table">
<table>
<thead>
<tr>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
<th class="numeric-cell">Fat (g)</th>
<th class="numeric-cell">Carbs</th>
<th class="numeric-cell">Protein (g)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
<td class="numeric-cell">6.0</td>
<td class="numeric-cell">24</td>
<td class="numeric-cell">4.0</td>
</tr>
...
</tbody>
</table>
<div class="data-table-footer">
<div class="data-table-rows-select">
Per page:
<div class="input input-dropdown">
<select>
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="all">All</option>
</select>
</div>
</div>
<div class="data-table-pagination">
<span class="data-table-pagination-label">1-5 of 10</span>
<a href="#" class="link disabled">
<i class="icon icon-prev color-gray"></i>
</a>
<a href="#" class="link">
<i class="icon icon-next color-gray"></i>
</a>
</div>
</div>
</div>
Where
data-table-footer
- data table footer main elementdata-table-rows-select
- container with amount per page selectdata-table-pagination
- container with information about current page and prev/next navigation buttonsdata-table-pagination-label
- current paging label
Selectable Rows
<div class="data-table data-table-init card">
<table>
<thead>
<tr>
<th class="checkbox-cell">
<label class="checkbox">
<input type="checkbox"/>
<i class="icon-checkbox"></i>
</label>
</th>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
...
<th class="numeric-cell">Protein (g)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="checkbox-cell">
<label class="checkbox">
<input type="checkbox"/>
<i class="icon-checkbox"></i>
</label>
</td>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
...
<td class="numeric-cell">4.0</td>
</tr>
...
</tbody>
</table>
</div>
Where
data-table-init
- additional class to enable JavaScript action required for selectable rowsCheckbox cell. Such cell in table header will select/deselect all rows in table body:
<td class="checkbox-cell"> <label class="checkbox"> <input type="checkbox"/> <i class="icon-checkbox"></i> </label> </td>
Inputs In Table Head
Such tables are widely used in admin interfaces for filtering or search data
<div class="card data-table">
<table>
<thead>
<tr>
<th class="input-cell">
<span class="table-head-label">ID</span>
<div class="input" style="width: 50px">
<input type="number" placeholder="Filter" />
</div>
</th>
<th class="input-cell">
<span class="table-head-label">Name</span>
<div class="input">
<input type="text" placeholder="Filter" />
</div>
</th>
...
<th class="input-cell">
<span class="table-head-label">Gender</span>
<div class="input input-dropdown">
<select>
<option value="All">All</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John Doe</td>
<td>[email protected]</td>
<td>Male</td>
</tr>
...
</tbody>
</table>
</div>
Where
input-cell
- additional class on table cell required to display input<span class="table-head-label">
- input label<div class="input">
- input container
Table Title/Header
When data table is used within Card it is possible to use additional data table title with actions in card header.
With title and actions
<div class="data-table data-table-init card">
<!-- Card Header -->
<div class="card-header">
<!-- Table title -->
<div class="data-table-title">Nutrition</div>
<!-- Table actions -->
<div class="data-table-actions">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">line_horizontal_3_decrease</i>
<i class="icon material-icons md-only">sort</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">ellipsis_vertical_circle</i>
<i class="icon material-icons md-only">more_vert</i>
</a>
</div>
</div>
<!-- Card Content -->
<div class="card-content">
<table>
<thead>
<tr>
<th class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</th>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
...
</tr>
</thead>
<tbody>
<tr>
<td class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</td>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
...
</tr>
...
</tbody>
</table>
</div>
</div>
Where
data-table-title
- table titledata-table-actions
- main table actions
Different actions on select
<div class="data-table data-table-init card">
<!-- Card header -->
<div class="card-header">
<!-- Default table header -->
<div class="data-table-header">
<!-- Default table title -->
<div class="data-table-title">Nutrition</div>
<!-- Default table actions -->
<div class="data-table-actions">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">line_horizontal_3_decrease</i>
<i class="icon material-icons md-only">sort</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">ellipsis_vertical_circle</i>
<i class="icon material-icons md-only">more_vert</i>
</a>
</div>
</div>
<!-- Selected table header -->
<div class="data-table-header-selected">
<!-- Selected table title -->
<div class="data-table-title-selected"><span class="data-table-selected-count"></span> items selected</div>
<!-- Selected table actions -->
<div class="data-table-actions">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">trash</i>
<i class="icon material-icons md-only">delete</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">ellipsis_vertical_circle</i>
<i class="icon material-icons md-only">more_vert</i>
</a>
</div>
</div>
</div>
<div class="card-content">
<table>
<thead>
<tr>
<th class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</th>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
...
</tr>
</thead>
<tbody>
<tr>
<td class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</td>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
...
</tr>
...
</tbody>
</table>
</div>
</div>
Where
data-table-header
- default table header. Visible when there are no selected rowsdata-table-header-selected
- selected table header. Visible when there are selected rowsdata-table-selected-count
- count of selected table rows. Number will be placed here by JavaScript
Alternate header with row actions
<div class="data-table data-table-init card">
<div class="card-header">
<!-- Table links/actions -->
<div class="data-table-links">
<a class="link">Add</a>
<a class="link">Remove</a>
</div>
<!-- Table actions -->
<div class="data-table-actions">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">line_horizontal_3_decrease</i>
<i class="icon material-icons md-only">sort</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">ellipsis_vertical_circle</i>
<i class="icon material-icons md-only">more_vert</i>
</a>
</div>
</div>
<div class="card-content">
<table>
<thead>
<tr>
<th class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</th>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
...
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</td>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
...
<td class="actions-cell">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">square_pencil</i>
<i class="icon material-icons md-only">edit</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">trash</i>
<i class="icon material-icons md-only">delete</i>
</a>
</td>
</tr>
...
</tbody>
</table>
</div>
</div>
Where
data-table-links
- alternate/additional table actionsactions-cell
- action links/icons cell
Sortable
<div class="data-table data-table-init card">
<div class="card-header">
<div class="data-table-title">Nutrition</div>
<div class="data-table-actions">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">line_horizontal_3_decrease</i>
<i class="icon material-icons md-only">sort</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">ellipsis_vertical_circle</i>
<i class="icon material-icons md-only">more_vert</i>
</a>
</div>
</div>
<div class="card-content">
<table>
<thead>
<tr>
<th class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</th>
<th class="label-cell sortable-cell sortable-cell-active">Dessert (100g serving)</th>
<th class="numeric-cell sortable-cell">Calories</th>
<th class="numeric-cell sortable-cell">Fat (g)</th>
<th class="numeric-cell sortable-cell">Carbs</th>
<th class="numeric-cell sortable-cell">Protein (g)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="checkbox-cell">
<label class="checkbox">
<input type="checkbox" />
<i class="icon-checkbox"></i>
</label>
</td>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
<td class="numeric-cell">6.0</td>
<td class="numeric-cell">24</td>
<td class="numeric-cell">4.0</td>
</tr>
...
</tbody>
</table>
</div>
</div>
Where
sortable-cell
- additional class to make cell/column is sortablesortable-cell-active
- additional class to specify active/default sortable cell/columnsortable-asc
- additional class to specify current sorting as ascending (default)sortable-desc
- additional class to specify current sorting as descending
Note, there is no actual sortable logic provided by framework. Actual sorting logic should be realized manually
Collapsible
The following table will be collapsed to kind of List View on small screens:
<div class="card data-table data-table-collapsible data-table-init">
<div class="card-header">
<div class="data-table-title">Nutrition</div>
<div class="data-table-actions">
<a class="link icon-only">
<i class="icon f7-icons if-not-md">line_horizontal_3_decrease</i>
<i class="icon material-icons md-only">sort</i>
</a>
<a class="link icon-only">
<i class="icon f7-icons if-not-md">ellipsis_vertical_circle</i>
<i class="icon material-icons md-only">more_vert</i>
</a>
</div>
</div>
<div class="card-content">
<table>
<thead>
<tr>
<th class="label-cell">Dessert (100g serving)</th>
<th class="numeric-cell">Calories</th>
...
<th class="numeric-cell">Protein (g)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="label-cell">Frozen yogurt</td>
<td class="numeric-cell">159</td>
...
<td class="numeric-cell">4.0</td>
</tr>
...
</tbody>
</table>
</div>
</div>
Where
data-table-collapsible
- additional table class to enable collapsible logic. Note that "data-table-init" class is also required for this.
Data Table App Methods
In case you add data table dynamically and you need such selecting rows or switching headers logic you need to init it manually. Let's look at related app methods to work with data table:
app.dataTable.create(parameters)- create Data Table instance
- parameters - object. Object with data table parameters
Method returns created Data Table's instance
app.dataTable.destroy(el)- destroy Data Table instance
- el - HTMLElement or string (with CSS Selector) or object. Data Table element or Data Table instance to destroy.
app.dataTable.get(el)- get Data Table instance by HTML element
- el - HTMLElement or string (with CSS Selector). Data Table element.
Method returns Data Table's instance
Data Table Parameters
Now let's look at list of available parameters we need to create Data Table:
Parameter | Type | Default | Description |
---|---|---|---|
el | HTMLElement string | Data Table element. Can be useful if you already have Data Table element in your HTML and want to create new instance using this element |
Data Table Events
Data Table will fire the following DOM events on data table element and events on app and data table instance:
DOM Events
Event | Target | Description |
---|---|---|
datatable:sort | Data Table Element<div class="data-table"> | Event will be triggered data table sort changed |
datatable:beforedestroy | Data Table Element<div class="data-table"> | Event will be triggered right before Data Table instance will be destroyed |
App and Data Table Instance Events
Data Table instance emits events on both self instance and app instance. App instance events has same names prefixed with dataTable
.
Event | Arguments | Target | Description |
---|---|---|---|
sort | dataTable, sort | dataTable | Event will be triggered data table sort changed |
dataTableSort | dataTable, sort | app | |
beforeDestroy | dataTable | dataTable | Event will be triggered right before Data Table instance will be destroyed |
dataTableBeforeDestroy | dataTable | app |
CSS Variables
Below is the list of related CSS variables (CSS custom properties).
Note that commented variables are not specified by default and their values is what they fallback to in this case.
:root {
--f7-table-head-font-size: 12px;
--f7-table-body-font-size: 14px;
--f7-table-footer-font-size: 12px;
--f7-table-input-height: 24px;
--f7-table-input-font-size: 14px;
--f7-table-collapsible-cell-padding: 16px;
--f7-table-link-icon-only-icon-size: 20px;
--f7-table-head-bg-color: transparent;
--f7-table-card-header-bg-color: transparent;
--f7-table-card-header-height: 64px;
--f7-table-cell-padding-vertical: 0px;
--f7-table-sortable-icon-color: #000;
}
:root .theme-dark,
:root.theme-dark {
--f7-table-cell-border-color: rgba(255, 255, 255, 0.15);
--f7-table-sortable-icon-color: #fff;
--f7-table-input-text-color: #fff;
}
.ios {
--f7-table-head-font-weight: 600;
--f7-table-head-cell-height: 44px;
--f7-table-head-icon-size: 18px;
--f7-table-body-cell-height: 44px;
--f7-table-cell-padding-horizontal: 16px;
--f7-table-edge-cell-padding-horizontal: 16px;
--f7-table-label-cell-padding-horizontal: 16px;
--f7-table-checkbox-cell-width: 22px;
/* --f7-table-actions-cell-link-color: var(--f7-theme-color); */
/* --f7-table-actions-link-color: var(--f7-theme-color); */
--f7-table-title-font-size: 17px;
--f7-table-title-font-weight: 600;
--f7-table-footer-height: 44px;
--f7-table-head-text-color: rgba(0, 0, 0, 0.45);
--f7-table-cell-border-color: rgba(0, 0, 0, 0.22);
--f7-table-selected-row-bg-color: rgba(0, 0, 0, 0.03);
--f7-table-footer-text-color: rgba(0, 0, 0, 0.45);
--f7-table-input-text-color: #000;
}
.ios .theme-dark,
.ios.theme-dark {
--f7-table-head-text-color: rgba(255, 255, 255, 0.55);
--f7-table-footer-text-color: rgba(255, 255, 255, 0.55);
--f7-table-selected-row-bg-color: rgba(255, 255, 255, 0.08);
}
.md {
--f7-table-head-font-weight: 500;
--f7-table-head-cell-height: 56px;
--f7-table-head-icon-size: 16px;
--f7-table-body-cell-height: 48px;
--f7-table-cell-padding-horizontal: 28px;
--f7-table-edge-cell-padding-horizontal: 24px;
--f7-table-label-cell-padding-horizontal: 24px;
--f7-table-checkbox-cell-width: 18px;
--f7-table-title-font-size: 20px;
--f7-table-title-font-weight: 400;
--f7-table-footer-height: 56px;
--f7-table-head-text-color: rgba(0, 0, 0, 0.54);
--f7-table-cell-border-color: rgba(0, 0, 0, 0.12);
--f7-table-actions-cell-link-color: rgba(0, 0, 0, 0.54);
--f7-table-selected-row-bg-color: #f5f5f5;
--f7-table-actions-link-color: rgba(0, 0, 0, 0.54);
--f7-table-footer-text-color: rgba(0, 0, 0, 0.54);
--f7-table-input-text-color: #212121;
}
.md .theme-dark,
.md.theme-dark {
--f7-table-head-text-color: rgba(255, 255, 255, 0.54);
--f7-table-footer-text-color: rgba(255, 255, 255, 0.54);
--f7-table-selected-row-bg-color: rgba(255, 255, 255, 0.05);
--f7-table-actions-cell-link-color: rgba(255, 255, 255, 0.54);
--f7-table-actions-link-color: rgba(255, 255, 255, 0.54);
}
.aurora {
--f7-table-input-height: 32px;
--f7-table-head-font-weight: 600;
--f7-table-head-cell-height: 56px;
--f7-table-head-icon-size: 18px;
--f7-table-body-cell-height: 48px;
--f7-table-cell-padding-horizontal: 16px;
--f7-table-edge-cell-padding-horizontal: 16px;
--f7-table-label-cell-padding-horizontal: 16px;
--f7-table-checkbox-cell-width: 22px;
/* --f7-table-actions-cell-link-color: var(--f7-theme-color); */
/* --f7-table-actions-link-color: var(--f7-theme-color); */
--f7-table-title-font-size: 20px;
--f7-table-title-font-weight: 600;
--f7-table-footer-height: 56px;
--f7-table-head-text-color: rgba(0, 0, 0, 0.6);
--f7-table-cell-border-color: rgba(0, 0, 0, 0.12);
--f7-table-selected-row-bg-color: rgba(0, 0, 0, 0.03);
--f7-table-footer-text-color: rgba(0, 0, 0, 0.5);
--f7-table-input-text-color: #000;
--f7-table-head-bg-color: #f6f6f7;
--f7-table-card-header-bg-color: #f6f6f7;
}
.aurora .theme-dark,
.aurora.theme-dark {
--f7-table-selected-row-bg-color: rgba(255, 255, 255, 0.03);
--f7-table-head-text-color: rgba(255, 255, 255, 0.54);
--f7-table-footer-text-color: rgba(255, 255, 255, 0.54);
--f7-table-head-bg-color: rgba(255, 255, 255, 0.05);
--f7-table-card-header-bg-color: rgba(255, 255, 255, 0.05);
}