Tables - Done

Download HTML File
Updated: Jan 9 2025 12:05pm PST
View Live Version
Security Note
Security Note When Developing: Disabling a checkbox (or any UI element) in the interface is purely for user experience and error prevention—it’s not a security measure. If someone re-enables a disabled checkbox by modifying the markup (for example, using browser dev tools) and attempts to use it, your backend should respond in a way that prevents any unintended action. In other words, at best nothing should happen, or at worst the user should see an error message. Under no circumstances should modifying source (such as using browser tools) change/effect how they create, access, modify or delete data server-side data.
Dependencies
Some dependencies are taken care of by Global Dependencies and are provided here for reference.
Module | Global Depenedency | Description |
|---|---|---|
jQuery 3.5.1 | Yes | Required for animations, Date Range Picker and other functions. |
Date Range Picker | Yes | Provides single date, and date range selection UI. Depends on jQuery and Moment.js. |
Moment.js | Yes | Required by Date Range Picker. Provides date manipulation and formatting. |
Built-in Functions
Download as CSV
Description
Exports table contents (header row and data rows as a CSV file and initates download in the browser).
Audit
Records an entry to the audit log of the user downloading the data.
Inline Edit
Description
When enabled, by clicking the inline edit icon in the cell the cell's data can be edited. Once editing is complete there is a Save button. There is also a cancel button to cancel the edit and revert the change.
Inline Edit Types
There are different editor types.
Type | Description |
|---|---|
Text | Is a plain text edit input, there is a max length option to restrict text input length |
Dropdown | A dropdown list generated based on a object populated via the JSON |
Date | Uses the datePicker. Can be a single date or range if needed. Settings for the picker such as the start date/initial date are set in the JSON |
Phone | Is a text-box input, that on blur, or when clicking save uses the validatePhone function to validate and reformat entries before save. Saves |
Is a text-box input, that on blur, or when clicking save uses the validateEmail function to validate and reformat entries before save. | |
URL | Is a text-box input, that on blur, or when clicking save uses the validateURL function to validate and reformat entries before save. |
Validation Error Handling
If an error is returned by one of the function it returns an error message in the respose, that error message should be displayed in the <div class="validation-error inline-edit">error message</div>. You can use this same DIV to return server-side valiation errors as well. DIV is display:none by default. When using you must enable to make it visible. As a best practice when clearing an error you should clear the contents of the DIV as well as hide it.
Date Picker
Description
The date picker we are using is daterangepicker.js. It is suitable for both individual date, date/time, and date ranges. This will be used in tables in two different areas, as a date range filter for filtering date columns. And as a date picker for in-line editing.
Note a final .js and documentation for this is being revised and will be published very soon.
HTML Structure
Below is the general HTML structure of a table inside.
<!-- Dropdown Portal to Prevent Clipping -->
<div id="dropdown-portal" style="position: relative; z-index: 1000;"></div>
<!--Dynamic Table -->
<form>
<div class="table-outline">
<div class="table-scroll-container">
<table class="table">
<thead class="table-head">
<tr class="table-header-row">
<th class="table-checkbox-column">
<label class="w-checkbox table-checkbox-field">
<div class="w-checkbox-input w-checkbox-input--inputType-custom table-checkbox"></div>
<input type="checkbox" style="opacity:0;position:absolute;z-index:-1"> <!-- if checked, checks all items in table, if filtered, only selects filtered items -->
</label>
</th>
<th>
<div class="table-cell-content">
<div class="table-heading">Name</div>
<svg class="table-sort-button w-embed"></svg> <!-- onClick sort by this column -->
</div>
</th>
-- more data columns --
<th class="action-column">
<div class="table-header-icon-container">
<a href="#" class="table-header-button w-inline-block">
<div class="table-button-icon w-embed">
<svg></svg>
</div>
</a>
<div data-delay="0" data-hover="false" class="table-menu-container w-dropdown">
<div class="table-menu-button w-dropdown-toggle" aria-haspopup="menu" aria-expanded="false" role="button" tabindex="0">
<div class="table-header-button">
<div class="table-button-icon w-embed">
<svg></svg> </div>
</div>
</div>
<nav class="table-menu w-dropdown-list">
<a href="#" class="table-menu-item w-inline-block" tabindex="0">
<div class="table-menu-item-icon w-embed">
<svg></svg>
</div>
<div>Delete Selected</div>
</a>
<a href="#" class="table-menu-item w-inline-block" tabindex="0">
<div class="table-menu-item-icon w-embed">
<svg></svg>
</div>
<div>Export to CSV</div>
</a>
</nav>
</div>
</div>
</th>
</tr>
<!-- START Optional Filter Row -->
<tr class="table-filter-row">
<th class="table-checkbox-column"></th>
<th>
<div class="table-filter-cell-content">
<!-- This is a text filter. -->
<input class="input-filter w-input" maxlength="256" placeholder="Filter" type="text">
<!-- End example text filter. -->
</div>
</th>
<th>
<div class="table-filter-cell-content">
<!-- This is a dropdown filter. -->
<div data-hover="false" data-delay="0" class="dropdown w-dropdown" style="">
<div class="dropdown-closed table-filter w-dropdown-toggle" aria-haspopup="menu" aria-expanded="false" role="button" tabindex="0">
<div class="filter-dropdown-arrow w-icon-dropdown-toggle" aria-hidden="true"></div>
<div>Select one...</div>
</div>
<nav class="dropdown-open w-dropdown-list">
<a href="#" class="dropdown-option-simple w-inline-block" tabindex="0">
<div class="dropdown-option-selected-icon-container">
<div class="dropdown-option-selected-icon w-embed">
<svg></svg>
</div>
</div>
<div class="dropdown-option-simple-text">Canada</div>
</a>
<a href="#" class="dropdown-option-simple w-inline-block" tabindex="0">
<div class="dropdown-option-selected-icon-container">
<div class="dropdown-option-selected-icon selected w-embed">
<svg></svg>
</div>
</div>
<div class="dropdown-option-simple-text">United States</div>
</a>
</nav>
</div>
<!-- End example dropdown filter. -->
</div>
</th>
<th>
<div class="table-filter-cell-content">
<!-- This is a Date Range Filter -->
<div class="date-filter">
<input class="input-filter date-picker w-input" maxlength="256" placeholder="YYYY-MM-DD - YYYY-MM-DD" type="text">
<div id="dateFilterButton" class="date-filter-icon-container">
<div class="date-filter-icon w-embed">
<svg></svg>
</div>
</div>
</div>
<!-- End example Date Range Picker Filter -->
</div>
</th>
-- more filter columns --
<th></th> <!-- empty TH with no classes over in last column (action-column) -->
</tr>
<!-- END Optional Filter Row -->
</thead>
<tbody class="table-body">
<tr class="table-row">
<td class="table-checkbox-column">
<label class="w-checkbox table-checkbox-field">
<div class="w-checkbox-input w-checkbox-input--inputType-custom table-checkbox" <!-- IF DISABLED --> data-tippy-content="{checkboxDisabledTooltip}" data-placement="right" <!--End if disabled -->></div>
<input type="checkbox" style="opacity:0;position:absolute;z-index:-1">
</label>
</td>
<!-- Rich cell content -->
<td class="table-cell">
<div class="table-cell-content">
<div class="table-cell-left" data-tippy-content="{tooltip}">
<img width="32" src="https://cdn.prod.website-files.com/665515d66ae3ac9e19b76d10/6774353ae92924622819014e_5dd1ca04edfe6a591970a2cd_face-chad.jpg" alt="" class="table-image">
<div class="table-data overflow"><strong>Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry.</div>
</div>
<div class="table-cell-right">
<div class="table-cell-right-content" data-tippy-content="{rightContentTooltip}">
<svg class="table-cell-right-icon" >{Icon like TrendingUp}</svg>
</div>
</div>
</div>
</td>
<!-- Basic Cell Content -->
<td class="table-cell">
<div class="table-cell-content">
<div class="table-cell-left" data-tippy-content="{tooltip}">
<div class="table-data">555-555-5555</div>
</div>
<div class="table-cell-right">
<div class="table-cell-right-content" data-tippy-content="{rightContentTooltip}"></div>
</div>
</div>
</td>
<!-- End Basic Cell Content -->
<!-- Email Type Cell Content with inline edit button -->
<td class="table-cell">
<div class="table-cell-content">
<div class="table-cell-left" data-tippy-content="{tooltip}">
<a href="mailto:[email protected]" class="table-data">[email protected]</a>
</div>
<div class="table-cell-right">
<div class="inline-edit-button">
<div class="inline-edit-icon w-embed" data-tippy-content="Edit">
<svg></svg>
</div>
</div>
</div>
</div>
</td>
<!-- End Email Cell Content -->
<!-- Inline Edit of Cell -->
<td class="table-cell">
<div class="table-cell-content">
<div class="table-cell-left" data-tippy-content="{tooltip}">
<input class="input-filter w-input" maxlength="256" placeholder="Filter" type="text">
</div>
<div class="table-cell-right">
<div class="inline-edit-button green">
<div class="inline-edit-icon w-embed" data-tippy-content="Save">
<svg></svg>
</div>
</div>
<div class="inline-edit-button red">
<div class="inline-edit-icon w-embed" data-tippy-content="Cancel">
<svg></svg>
</div>
</div>
</div>
</div>
<div style="display: none;" class="inline-edit-validation-error">{validation error}</div>
</td>
<!-- End Inline Edit of Cell -->
<!-- Email Type Cell Content -->
<td class="table-cell">
<div class="table-cell-content">
<div class="table-cell-left" data-tippy-content="{tooltip}">
<a href="mailto:[email protected]" class="table-data">[email protected]</a>
</div>
<div class="table-cell-right"></div>
</div>
</td>
<!-- End Email Cell Content -->
<!-- Progress Bar Cell Content -->
<td class="table-cell">
<div class="table-cell-content">
<div class="progress-bar-container" data-tippy-content="{tooltip}">
<div class="progress-bar-base">
<div style="width: {progressPercent}%" class="progress-bar-progress"></div>
</div>
</div>
</div>
</td>
<!-- End Progress Bar Cell Content -->
<!-- Star Rating Cell Content -->
<td class="table-cell">
<div class="table-cell-content">
<div class="star-rating-container" data-rating="4.5" data-tippy-content="{tooltip}">
<div class="rating-star">
<svg></svg>
<svg></svg>
<svg></svg>
<svg></svg>
<svg></svg>
</div>
</div>
</div>
</td>
<!-- End Star Rating Cell Content -->
<!-- Toggle Switch Cell Content -->
<td class="table-cell">
<div class="table-cell-content">
<div class="toggle-container" data-tippy-content="{tooltip}">
<a href="#" data-ix="toggle" class="toggle-button active w-inline-block">
<div class="toggle-button-knob active"></div>
</a>
</div>
</div>
</td>
<!-- End Toggle Switch Cell Content -->
-- More Cells -->
<!-- Row Action Buttons -->
<td class="table-cell">
<div class="table-row-action-button-container">
<div class="table-row-action-button" data-tippy-content="Edit">
<div class="table-row-action-button-icon w-embed">
<svg></svg>
</div>
</div>
<div class="table-row-action-button" data-tippy-content="Delete">
<div class="table-row-action-button-icon delete w-embed">
<svg></svg>
</div>
</div>
</div>
</td>
<!-- End Row Action Buttons -->
</tr>
</tbody>
<!-- START Optional total row -->
<tfoot class="table-footer">
<tr class="table-total-row">
<!-- checkbox column cell -->
<td class="table-checkbox-column">
</td>
<!-- end checkbox column cell -->
<!-- empty column -->
<td class="table-cell">
<div class="table-footer-content"></div>
</td>
<!-- end empty column -->
<!-- column with total -->
<td class="table-cell">
<div class="table-cell-content">1234</div>
</td>
<!-- end column with total -->
-- more footer / total columns --
<!-- start empty cell for action column -->
<td class="table-cell"></td>
<!-- end action column -->
</tr>
</tfoot>
<!-- END Optional Total Row -->
</table>
</div>
<!-- START Optional Pagination -->
<div class="table-pagination">
<div class="pagination-left">
<div class="items-per-page-container">
<div>Items per page:</div>
<select id="ItemsPerPage" name="ItemsPerPage" class="pagination-dropdwn w-select">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="1000">1000</option>
</select>
</div>
<div class="paginaton-total-items">
<div>1–10 of 103 items</div>
</div>
</div>
<div class="pagination-right">
<div class="pagination-pages-dropdown">
<select id="PagesDropdown" name="PagesDropdown" class="pagination-dropdwn w-select">
<option value="1">1</option>
<option value="2">2</option>
</select>
<div>of 11 pages</div>
</div>
<div class="pagination-button">
<div class="pagination-icon w-embed">
<svg></svg>
</div>
</div>
</div>
</div>
<!-- END Optional Pagination -->
</div>
</form>HTML Special Notes
Last Data Row in Table
The last <tr> in the <tbody> should have the combo-class last-row added to it. E.g. <tr class="table-row last-row">. We could accomplish this programatically by doing this:
document.addEventListener('DOMContentLoaded', () => {
const tbodies = document.querySelectorAll('tbody');
tbodies.forEach(tbody => {
const lastTr = tbody.querySelector('tr:last-child');
if (lastTr) {
lastTr.classList.add('last-row');
}
});
});
JSON Schema
This document defines a JSON-based schema for configuring dynamic tables, including features like:
- Add button and actions menu
- Multi-row selection (checkboxes)
- Column filtering
- Sorting (default sort and per-column)
- Inline editing
- Totals row with sums/counts/averages
- Pagination
- Progress bars, toggles, and more
How to Use This Schema
Schema
Table-Level Configuration table
Field | Type | Description | How it Works |
|---|---|---|---|
headerRow | Object | Contains settings for the top row (Add Button, three-dot menu, multi-row selection). | |
filterRowEnabled | Boolean | If true, a filter row appears below the header row. Defaults to false if not specified. | |
defaultSortColumn | String | The ID of the column to sort by on first render (e.g., "Item Name"). | |
totalRowEnabled | Boolean | If true, displays a totals row at the bottom of the table (calculates sums, counts, averages where configured). | |
recordsPerPage | Number | Number of rows to display per page. If total rows > recordsPerPage, pagination controls appear. | |
rowSelection | Boolean | If true, the Checkbox Column is rendered on the table allowing single or multi-row selections. | If false don't render the checkbox column at all. Don't just hide the DIV. |
headerRow object
Field | Type | Description |
|---|---|---|
addButton | Object | Settings for the Add (+) button (label, enable/disable, on-click function). |
tableMenu | Object | Settings for the Table Menu (3 dots). |
headerRow.addButton object
Field | Type | Description |
|---|---|---|
tooltip | String | Text to be displayed if hovering the Add button. |
enabled | Boolean | If false, hides the Add button. |
onClickFunction | String | The function name or event handler triggered on button click (e.g., "addNewRecord"). |
headerRow.tableMenu object
Field | Type | Description |
|---|---|---|
enabled | Boolean | If false, hides the Table Menu. |
tooltip | String | Text to be displayed if hovering the Table Menu button. |
options | Array | An array of menu options. Each option is an object with name, enabled, onClickFunction. |
downloadAsCSV | Boolean | If true, a “Download as CSV” option is shown and triggers the table’s CSV export function. |
headerRow.tableMenu.options array of objects:
Field | Type | Description |
|---|---|---|
name | String | Display text for the menu item (e.g., "Delete Selected") |
onClickFunction | String | Name of the function to call when the user selects this item, e.g., "deleteSelectedRows". |
onlyWhenRowsSelected | Boolean | If true, this menu item is only visible when one or more rows are selected via checkboxes (assuming rowSelection = true). |
Column-Level Configuration columns
Each columAcceptablen is an object in the columns array.
Field | Type | Description | How it Works |
|---|---|---|---|
id | String* | A unique ID for each column used for filtering and sorting. | |
name | String* | The header label for the column, e.g. "Item Name". | |
type | String* | One of: text, date, email ,number, money, toggle, starRating or progress. | |
textAlign | String|null | Aligns text to the left, right, or center if null it defaults to left. | If right or center add style="text-align: " to the DIV with the table-data and table-heading classes for each cell in this column. (e.g. <div style="text-align: textAlign" class="table-heading"> and <div style="text-align: textAlign" class="table-data"> |
imageWidth | Number | Sets the image width/size in PX for this column. | For every image in this column, update the width: <img width="imageWidthpx">. If imageWidth is empty it defaults to 32px. |
imageAspectRatio | String|null | Sets the aspect ratio for the image. Options are "1/1", "16/9", or "3/2". | For every image in this column, add the appropriate class to the image. Note: .table-image defaults to 1:1. If 1/1 do nothing. Elseif 16/9 add class _169. Elseif 3/2 add class _32. The modifier class must come after the main class (e.g. class="table-image _169") |
dateFormat | String|null | Applicable when type="date". Example: "YYYY-MM-DD". | Acceptable inputs should be patterns we can pass directly to JS These should be formatDate Global Function. Default to YYYY-MM-DD |
filterEnabled | Boolean|null | Displays a filter control in the filter row if true. Default to true. | |
filterType | String|null | One of: text, dropdown, or datePicker. Default to text if null. | |
inlineEditEnabled | Boolean|null | If true, cells in this column can be edited in-line unless overridden by the row. Default to false. | |
inlineEditType | String|null | Editor type for in-line edits: text, dropdown, date, phone, email, or url. Default to text. | |
inlineEditDatePicker | Object | If inlineEditType is "date", the inlineEditDatePicker object is required. | |
inlineEditDropdown | Object | If inlineEditType is "dropdown", the inlineEditDropdown object is required. | |
inlineEditPlaceholder | String|null | Text to be used as the placeholder for the input box for text, phone, email, url, date etc. (shows when the input field is empty) | |
inlineEditTextMaxLength | Number|null | Sets the maximum number of characters allowed. | |
showTotal | Boolean | If true and totalRowEnabled is true, a total displays in the total row for this column. | |
totalType | String|null | The type of total/calculation: "sum", "count", or "average". | |
totalTooltip | String|null | Hover text explaining how the total is calculated, e.g., "Sum of all item prices". | |
Overflow | Boolean | If true, the column text is truncated with ellipses if it doesn’t fit. | |
minWidth | Number|null | Minimum width in pixels (e.g., 80). | |
maxWidth | Number|null | Maximum width in pixels (e.g., 150). If null, there is no explicit maximum (beyond the container’s constraints). | |
tooltipPosition | String|null | Changes the position where the tooltip opens. Options are top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, or left-end. If not provided it defaults to bottom. | Set the data-placement attribute on each element in the column with the data-tippy-content attribute set. (e.g. <div data-tippy-content="tooltip" data-placement="tooltipPosition">) |
progressVariableColor | String|null | If progressVariableColor (string) is set to "true", a dynamic gradient is applied based on progress percentage; if set to "reverse", the gradient is reversed. These are the only valid string options. | If provided, set the attribute data-progress-variable-color="progressVariableColor" on each <div> in the column with the class progress-bar-progress. (e.g. <div class="progress-bar-progress" data-progress-variable-color="true">) |
datePicker object
Field | Type | Description |
|---|---|---|
singleDatePicker | Boolean | Key switch for single date vs. date range. true → single date, false → date range. |
startDate | Date|null | The initial date (if singleDatePicker = true) or start of the initial range (if false). Must match dateFormat if it’s a string. Picks todays date if null |
endDate | Date|null | The end date of the initially selected range. Ignored if singleDatePicker = true. |
minDate | Date|null | Earliest date the user can select. |
maxDate | Date|null | Latest date the user can select. |
maxSpan | Object | (Optional) The largest allowed range between startDate and endDate, e.g. { "days": 7 }. |
showDropdowns | Boolean|null | Shows year/month dropdowns for quick jumps if true. |
timePicker | Boolean|null | Displays time selection if true. |
timePickerIncrement | Number|null | Interval for minutes in time selection (e.g., 15). Only matters if timePicker = true. |
opens | null | "left" | "right" | "center" | Positions the picker relative to the input: left, right, or center. |
autoApply | Boolean | If true, user’s selection is auto-applied. If false, they must press an “Apply” button. Default to true |
datePicker.maxSpan object
Key | Type | Description |
|---|---|---|
days | Number | Limits the date range to the specified number of days (e.g., 7 means start and end can’t exceed 7 days apart). |
weeks | Number | Limits the date range to the specified number of weeks (e.g., 2 means the user can select at most a 2-week span). |
months | Number | Limits the date range to the specified number of months. |
years | Number | Limits the date range to the specified number of years. |
Note:
- You only need to supply one of these keys in the maxSpan object. For instance, { "days": 7 } or { "weeks": 2 }.
- The Date Range Picker uses Moment.js under the hood, so any key/value supported by Moment’s add() method should work.
- If multiple keys are provided, each will be applied additively. However, that’s an advanced scenario—most commonly, you’ll specify just one.
inlineEditDropdown object (column-level - see cell-level and more info below)
Field | Type | Description |
|---|---|---|
dropdownFilter | Boolean | If true shows filter input at top of dropdown. Default false (no filter) |
sortByValue | Boolean | If true sorts the options by value instead of by name. Honors sortDescending. |
sort | String|null | If sort= null then no sort is applied. If sort= asc sorts descending. If sort= dsc sorts descending. |
options | Object|null | Optionally sets the list of options at the column level (for example things like statuses... Active, Pending etc.) |
inlineEditDropdown.options object (column-level - see cell-level and more info below)
Field | Type | Description |
|---|---|---|
name | String | Name of the option. |
value | String | Value to return when saving. |
isDefault | Boolean | If true this item is selected by default if cell data is empty. |
inlineEditDatePicker object
Same structure as datePicker object.
Special Notes
- type="progress" Requires each cell to have progressPercent.
- type="toggle" Generally displays a switch for “active”/“inactive” or true/false states. This is an inline edit option and should update the database when toggled.
- type="money" Typically formatted as currency. The UI may prefix with $ or localize as needed.
Row-Level Configuration rows
Each row is an object in the rows array.
Field | Type | Description | How it Works |
|---|---|---|---|
checkboxDisabled | Boolean | If true, the row’s selection checkbox is disabled (when multi-row selection is enabled in the header). | |
checkboxDisabledTooltip | String|null | An explanation for why the checkbox is disabled, displayed on hover. | |
disableInlineEdit | Boolean | Overrides any column inlineEditEnabled. If true, this row cannot be edited in-line. | |
editButton | Boolean | If true, an “Edit” button icon is displayed for this row. | |
deleteButton | Boolean | If true, a “Delete” button icon is displayed for this row. | |
bold | Boolean | If true, apply the class | If true apply the modifier class .bold to the <tr> |
cells | Array | The set of cells for this row, each corresponding to a column definition in columns. | |
Cell-Level Configuration
Within each row’s cells array:
Field | Type | Description | How it Works |
|---|---|---|---|
imagePath | String|null | URL/path to an image to show in the cell (e.g., user avatar, product image). | Add image as first element in side of DIV with class "table-cell-left" in this cell. (e.g. <div class="table-cell-left"><img src="imagePath" alt=" imageAlt" class="table-image">) |
imageAlt | String|null | Alt text for the image | See imagePath example above |
data | String | The main text data of the cell. For most column types, data is displayed directly. | The main text data of the cell. For most column types, data is displayed directly. Supports basic HTML formatting, such as for bold text. (e.g. <div class="table-data">data</div>) |
tooltip | String|null | Text to be shown on hover of DIV of the appropriate DIV in this cell. | IF type = progress then set the data-tippy-content attribute in the <DIV> with the class progress-bar-container in this cell. ELSEIF type = toggle then set the data-tippy-content in the <DIV> with the class toggle-container in this cell. ELSEIF type = starRating then set the data-tippy-content in the <DIV> with the class star-rating-container in this cell. ELSE set the data-tippy-content attribute in the <DIV> with the class table-cell-left in this cell. (e.g. <div class="table-cell-left" data-tippy-content="tooltip">) |
hyperlink | String|null | If entered data becomes a hyperlink. Contents of the hyperlink string are the URL for the link. | A <a> tag is wrapped around the 'data' string. (e.g. <a href="hyperlink" title="data" target="_blank">data</a>) |
rightContentType | String|null | When set to "UpArrow", "DownArrow", "TrendUp", "TrendDown", "Checkmark", "X", "StarOutline", "StarSolid" or "text", displays an icon or text on the right side of the cell. | Add other than text, add the appropriate SVG to the DIV with class "table-cell-right-content" in this cell. See below for SVGs. (e.g. <div class="table-cell-right-content"><svg></svg></div>) |
rightContentText | String|null | Used if rightContentType = "text" to show custom text at the cell’s right side. | Add text to the DIV with class "table-cell-right-content" in this cell. (e.g. <div class="table-cell-right-content">rightContentText</div>) |
rightContentColor | String|null | Color (e.g., "#28a745") to apply to the right-side icon or text. | Add a style="color:rightContentColor" to the DIV with class "table-cell-right-content" in this cell. (e.g. <div class="table-cell-right-content" style="color: rightContentColor;">) |
rightContentTooltip | String|null | Text to display in tooltip when hovering over rightContent icon or text. | Set the data-tippy-content in the <DIV> with the class "table-cell-right-content" in this cell. (e.g. <div class="table-cell-right-content" data-tippy-content="rightContentTooltip"> |
starRating | Number | A number of stars out of 5 stars for example 4.5. | Set the value the attribute data-rating of the <DIV> with the class star-rating-container in this cell. (e.g. <div class="star-rating-container" data-rating="starRating"> |
progressPercent | Number | Required if column type="progress", this is the % to show in the progress bar. Must be 0-100. | Set the width in percentage of the <DIV> with the class progress-bar-progress in this cell. (e.g. <div class="progress-bar-progress" style="width: progressPercent%;"> |
inlineEditDropdownOption | Object | Used if inlineEditType = dropdown. If options are set at the column level this is not needed (for example Statuses). If this dropdown is to have content specific to this row it can be set in this object. | |
inlineEditDropdownOptions object (column-level - see cell-level and more info below)
Field | Type | Description |
|---|---|---|
name | String | Name of the option. |
value | String | Value to return when saving. |
isDefault | Boolean | If true this item is selected by default if cell data is empty. |
Example JSON
{
"table": {
"headerRow": {
"addButton": {
"tooltip": "Add new row",
"enabled": true,
"onClickFunction": "handleAddRow"
},
"tableMenu": {
"enabled": true,
"tooltip": "Table options",
"options": [
{
"name": "Delete Selected",
"onClickFunction": "handleDeleteSelected",
"onlyWhenRowsSelected": true
}
],
"downloadAsCSV": true
}
},
"filterRowEnabled": true,
"defaultSortColumn": "description",
"totalRowEnabled": true,
"recordsPerPage": 5,
"rowSelection": true,
"progressVariableColor": true
},
"columns": [
{
"id": "description",
"name": "Description",
"type": "text",
"filterEnabled": true,
"filterType": "text",
"inlineEditEnabled": true,
"inlineEditType": "text",
"inlineEditPlaceholder": "Enter item description",
"showTotal": false,
"Overflow": true,
"tooltipPosition": "right"
},
{
"id": "releaseDate",
"name": "Release Date",
"type": "date",
"dateFormat": "YYYY-MM-DD",
"filterEnabled": true,
"filterType": "datePicker",
"inlineEditEnabled": true,
"inlineEditType": "date",
"inlineEditDatePicker": {
"singleDatePicker": true,
"startDate": "2025-01-01",
"minDate": "2024-01-01",
"maxDate": "2026-12-31",
"showDropdowns": true,
"timePicker": false,
"opens": "center",
"autoApply": true
},
"showTotal": false
},
{
"id": "price",
"name": "Price",
"type": "money",
"filterEnabled": true,
"filterType": "text",
"inlineEditEnabled": true,
"inlineEditType": "text",
"inlineEditPlaceholder": "$0.00",
"showTotal": true,
"totalType": "sum",
"totalTooltip": "Total of prices"
},
{
"id": "quantity",
"name": "Qty",
"type": "number",
"filterEnabled": true,
"filterType": "text",
"inlineEditEnabled": true,
"showTotal": true,
"totalType": "count",
"totalTooltip": "Count of items"
},
{
"id": "activeStatus",
"name": "Active Status",
"type": "toggle",
"filterEnabled": true,
"filterType": "dropdown",
"inlineEditEnabled": true,
"inlineEditType": "dropdown",
"inlineEditDropdownOptions": [
{ "name": "Active", "value": "true" },
{ "name": "Inactive", "value": "false" }
],
"showTotal": false
},
{
"id": "completion",
"name": "Completion",
"type": "progress",
"filterEnabled": false,
"inlineEditEnabled": false,
"showTotal": false
},
{
"id": "userEmail",
"name": "User Email",
"type": "email",
"filterEnabled": true,
"filterType": "text",
"inlineEditEnabled": true,
"inlineEditType": "email",
"inlineEditPlaceholder": "[email protected]",
"showTotal": false
}
],
"rows": [
{
"editButton": true,
"deleteButton": true,
"cells": [
{
"data": "Widget A",
"tooltip": "Click to see Widget A details",
"hyperlink": "https://example.com/widget-a",
"rightContentType": "StarSolid",
"rightContentColor": "#ffd700",
"rightContentTooltip": "It's a favorite"
},
{
"data": "2025-02-15",
"tooltip": "Release date"
},
{
"data": "19.99",
"tooltip": "Unit price"
},
{
"data": "12",
"tooltip": "Available quantity"
},
{
"data": "true",
"tooltip": "Active"
},
{
"progressPercent": 75,
"progressTooltip": "75% done"
},
{
"data": "[email protected]",
"tooltip": "Contact email"
}
]
},
{
"editButton": true,
"deleteButton": true,
"cells": [
{
"data": "Widget B",
"imagePath": "https://example.com/widget-b.png",
"imageAlt": "Widget B image",
"tooltip": "A fancy widget",
"rightContentType": "TrendDown",
"rightContentColor": "#dc3545",
"rightContentTooltip": "Trending down"
},
{
"data": "2025-03-10",
"tooltip": "Tentative release date"
},
{
"data": "29.99",
"tooltip": "Price"
},
{
"data": "5",
"tooltip": "Quantity in stock"
},
{
"data": "false",
"tooltip": "Inactive"
},
{
"progressPercent": 20,
"progressTooltip": "20% done"
},
{
"data": "[email protected]",
"tooltip": "Contact email"
}
]
}
]
}SVGs
UpArrow
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>DownArrow
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"></line><polyline points="19 12 12 19 5 12"></polyline></svg>TrendUp
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline><polyline points="17 6 23 6 23 12"></polyline></svg>TrendDown
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 18 13.5 8.5 8.5 13.5 1 6"></polyline><polyline points="17 18 23 18 23 12"></polyline></svg>Checkmark
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>X
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>StarOutline
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>StarSolid
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>