DataTable
A configurable data table for datasets, datasources, filtering, sorting, pagination and row selection workflows.
import { DataTable } from "@schukai/monster/source/components/datatable/datatable.mjs";Introduction
The Monster Datatable is the main data grid component for dataset views with filtering, sorting, pagination and row actions. Use it when users need to inspect, compare and work with structured records instead of reading a simple static table.
When to use Datatable
- Use it for operational data views: Lists of orders, users, products or logs benefit from the built-in grid behavior and row actions.
- Use it when data comes from a datasource: The component integrates well with DOM, REST and other Monster datasource patterns.
- Use it when users need control over the result set: Pagination, filtering, sorting and row selection are first-class workflows.
- Do not use it for short static comparisons: If the content is editorial and not interactive, a plain HTML table is often easier and faster.
Key Features
- Datasource integration: Fill the grid from inline data or from a dedicated datasource without rewriting the table template.
- Operational controls: Combine filtering, ordering, pagination and selection to support day-to-day backoffice workflows.
- Template-driven rows: Define columns and row content with Monster templates instead of custom rendering code.
- Row events and state changes: Listen to documented selection and row mutation events for follow-up UI logic.
Typical mistakes
Start with a clear row template and a stable data contract. Many Datatable problems come from mixing presentation, filtering and datasource concerns too early. If the user only needs a handful of read-only values, a simpler table or metric component usually communicates the information better.
The Empty State
This is a simple and empty datatable. It is a powerful and flexible tool for displaying data in a tabular format. The Monster Datatable is designed to be straightforward to use and highly customizable, making it suitable for a wide range of applications.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";HTML
<monster-datatable>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/The Data Using Javascript
In this example, the data is set using JavaScript. To do this, the data option is set. The columns are defined in the html using the template.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.querySelector("monster-datatable");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.getElementById("id1agf2");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});</script>HTML
<monster-datatable>
<template id="row">
<div data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/The Alignment
In this example, the data is set using JavaScript. The class `end` is used to align the content to the right, center to the center, and start to the left. So that the content is aligned correctly.
The data-monster-align attribute is used to align the header of the column. The values end, center, and start are used to align the header to the right, center, and left, respectively.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.querySelector("monster-datatable");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.getElementById("id12x23");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});</script>HTML
<monster-datatable>
<template id="row">
<div class="end" data-monster-align="end" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div class="center" data-monster-align="center" data-monster-head="name" data-monster-replace="path:row.name"></div>
<div class="start" data-monster-align="start" data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div class="center" data-monster-align="center" data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/The Row Mode
The data-monster-row-mode attribute allows you to set the row mode. The default value is visible. Possible values are: visible, hidden, and fixed. Using visible displays the row normally. With hidden, the row is hidden, but the data remains in the DOM, so it can be made visible again through settings or via JavaScript. The fixed option is a special setting that not only makes the row visible but also fixes it in place. It cannot be hidden and remains visible at all times.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.querySelector("monster-datatable");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.getElementById("idRaXe21a");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});</script>HTML
<monster-datatable>
<template id="row">
<div data-monster-mode="fixed" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-mode="hidden" data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-mode="visible" data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div data-monster-mode="hidden" data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-mode="hidden" data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/The Grid Template
The data-monster-grid-template attribute allows you to define the width of individual columns. As shown in the example, a column can be made wider or narrower.
Any valid CSS values can be used for the data-monster-grid-template attribute. For more information, please refer to the CSS specification.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.querySelector("monster-datatable");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.getElementById("idac2df");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654",
"email": "max.mustermann@example.com"
}
]);
});</script>HTML
<monster-datatable>
<template id="row">
<div data-monster-grid-template="1.2rem" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-grid-template="auto" data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-grid-template="3fr" data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/The Overview Class
In this example, we explain the different CSS classes that can be applied to table columns within shadow roots. Since these columns are within the shadow DOM, they can only use internally defined classes. The following classes provide various text and layout handling options.
monospaceDefines a monospace font, ideal for displaying numbers or IDs that need to be easily compared across rows.ellipsisThis class is designed to prevent long text from disrupting the layout. When applied, the text is truncated with an ellipsis if it overflows the cell width, keeping the table row height fixed and preventing the table from becoming too tall.wrapEnables word wrapping within the cell. When the text reaches the cell boundary, it wraps to the next line, integrating neatly into the layout without overflow.autoUnlikeellipsis, this class prevents text from being truncated. Instead, it adds a horizontal scroll bar for text that exceeds the cell width, allowing users to scroll to view the full content.visibleTypically used with components likemonster-button-barthat may include pop-ups. Applying this class ensures that the pop-up remains visible when it appears.center,end,startThese alignment classes were discussed in a previous example but are included here for completeness. They control the horizontal alignment of content within the cell:centeraligns content in the center,endaligns it to the right, andstartaligns it to the left.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.querySelector("monster-datatable");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "In Remembrance of the Historic Stories and Heroes of Our City Along the Old Oak Pathway",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456 233353435242 233242 345345345 233242 345345435 233242 233242",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "In Remembrance of the Historic Stories and Heroes of Our City Along the Old Oak Pathway",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321 233242 34534534 534534 233242 234234 233242 233242",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "In Remembrance of the Historic Stories and Heroes of Our City Along the Old Oak Pathway",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654 233242 234234 233242 234234 233242 233242",
"email": "max.mustermann@example.com"
}
]);
});<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import {domReady} from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const datatable = document.getElementById("idFe22aD");
datatable.setOption('data', [
{
"id": 1,
"name": "John Doe",
"street": "In Remembrance of the Historic Stories and Heroes of Our City Along the Old Oak Pathway",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 123456 233353435242 233242 345345345 233242 345345435 233242 233242",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "In Remembrance of the Historic Stories and Heroes of Our City Along the Old Oak Pathway",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 654321 233242 34534534 534534 233242 234234 233242 233242",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "In Remembrance of the Historic Stories and Heroes of Our City Along the Old Oak Pathway",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 987654 233242 234234 233242 234234 233242 233242",
"email": "max.mustermann@example.com"
}
]);
});</script>HTML
<monster-datatable>
<template id="row">
<div class="monospace" data-monster-mode="fixed" data-monster-head="id"
data-monster-replace="path:row.id"></div>
<div class="ellipsis" data-monster-mode="hidden" data-monster-head="name"
data-monster-replace="path:row.name"></div>
<div class="auto" data-monster-mode="visible" data-monster-head="street"
data-monster-replace="path:row.street"></div>
<div class="auto" data-monster-head="city" data-monster-replace="path:row.city"></div>
<div class="auto" data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div class="auto" data-monster-mode="hidden" data-monster-head="country"
data-monster-replace="path:row.country"></div>
<div class="center wrap monospace" data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div class="ellipsis" data-monster-mode="hidden" data-monster-head="email"
data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/Use A Datasource
In this example, we introduce the concept of a DataSource in Monster. A DataSource is an object that can hold a data structure, making it versatile for managing data within components. Here, we demonstrate a basic example using a DOM-based DataSource.
In this simple setup, data is embedded as JSON within the DOM, specifically in a <script> tag. In real-world scenarios, however, data typically originates from an API through a REST interface. This means that switching the DataSource from a DOM-based source to an API-based source is straightforward and requires minimal adjustments to the setup—without any changes to the structure of the table itself.
To link a DataSource to a DataTable in Monster, use the data-monster-datasource-selector attribute. This attribute points to the id of the element containing the JSON data within the DOM.
In this example, the data-monster-datasource-selector attribute on the DataTable points to #myDataSourceID, which contains the JSON data embedded in the DOM.
By changing the DataSource to point to a REST API instead of a JSON script tag, the DataTable will be populated with data from the external source, while the internal structure and bindings remain unaffected. This makes Monster a flexible tool for integrating data dynamically, suitable for a range of applications from simple to complex.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";</script>HTML
<monster-datasource-dom id="myDataSourceID">
<script type="application/json">
{
"dataset": [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 1234.56",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 6543.21",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 1111.11",
"email": "max.mustermann@example.com"
},
{
"id": 4,
"name": "Lena Schmidt",
"street": "Hauptstrasse 4",
"city": "Cologne",
"zipcode": "50667",
"country": "Germany",
"phone": "+49 221 9876.54",
"email": "lena.schmidt@example.com"
},
{
"id": 5,
"name": "Markus Meier",
"street": "Ringstrasse 5",
"city": "Frankfurt",
"zipcode": "60311",
"country": "Germany",
"phone": "+49 69 4321.98",
"email": "markus.meier@example.com"
}
]
}
</script>
</monster-datasource-dom>
<monster-datatable data-monster-datasource-selector="#myDataSourceID">
<template id="row">
<div data-monster-grid-template="1.2rem" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-grid-template="auto" data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-grid-template="3fr" data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/Use Pagination
In this example, we introduce pagination to a DataTable in Monster. Like the DataTable, the pagination component also needs to connect to the same DataSource to ensure synchronized data management across both components.
To link both the DataTable and pagination to the DataSource, use the data-monster-datasource-selector attribute. This attribute should be specified on both the DataTable and pagination elements, pointing to the same DataSource id.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";</script>HTML
<monster-datasource-dom id="myDataSourceID">
<script type="application/json">
{
"dataset": [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 1234.56",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 6543.21",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 1111.11",
"email": "max.mustermann@example.com"
}
],
"sys": {
"pagination": {
"pages": 10,
"objectsPerPage": 3,
"currentPage": 2
}
}
}
</script>
</monster-datasource-dom>
<monster-datatable data-monster-datasource-selector="#myDataSourceID">
<div slot="bar" class="monster-button-group">
<monster-embedded-pagination id="pagination" data-monster-datasource-selector="#myDataSourceID"></monster-embedded-pagination>
</div>
<template id="row">
<div data-monster-grid-template="1.2rem" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-grid-template="auto" data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-grid-template="3fr" data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/Filer The Data
In this example, we enhance the DataTable in Monster by adding a filter. A filter allows users to search for specific values within the data source, refining the displayed data based on the criteria entered.
To enable filtering in the DataTable, the filter component, DataTable, and pagination must all be connected to the same DataSource. This is achieved by specifying the data-monster-datasource-selector attribute on each component, ensuring they work seamlessly together.
This setup ensures that the filter, table, and pagination components remain in sync. When a user enters text into the filter field, the displayed data in the DataTable and the pagination are both updated to match the filtered results. This configuration makes it easy to manage and display refined data dynamically within Monster.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/datatable/filter/range.mjs";
import "@schukai/monster/source/components/datatable/filter/select.mjs";
import "@schukai/monster/source/components/datatable/filter/date-range.mjs";
import "@schukai/monster/source/components/datatable/filter/range.mjs";
import "@schukai/monster/source/components/datatable/filter/input.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";
import "@schukai/monster/source/components/layout/tabs.mjs";<script type="module">import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/datatable/filter/range.mjs";
import "@schukai/monster/source/components/datatable/filter/select.mjs";
import "@schukai/monster/source/components/datatable/filter/date-range.mjs";
import "@schukai/monster/source/components/datatable/filter/range.mjs";
import "@schukai/monster/source/components/datatable/filter/input.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";
import "@schukai/monster/source/components/layout/tabs.mjs";</script>HTML
<monster-datasource-dom id="myDataSourceID">
<script type="application/json">
{
"dataset": [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 1234.56",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 6543.21",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 1111.11",
"email": "max.mustermann@example.com"
}
]
}
</script>
</monster-datasource-dom>
<monster-host>
<monster-config-manager></monster-config-manager>
</monster-host>
<monster-datatable data-monster-datasource-selector="#myDataSourceID">
<monster-collapse id="filter-collapse" data-monster-role="filter-collapse">
<div class="flex">
<monster-tabs style="width: 100%"
data-monster-option-features-opendelay="500"
data-monster-option-classes-navigation="monster-theme-background-inherit"
data-monster-option-classes-button="monster-theme-background-inherit" id="filtertabs">
<div data-monster-button-label="Filter" data-monster-state="active" class="active">
<monster-datatable-filter id="listfilter1" slot="filter"
data-monster-option-storedconfig-selector="#filtertabs">
<label data-monster-label="ID" id="id"
data-monster-template="${value | call:range:oid}">
ID
<monster-filter-range></monster-filter-range>
</label>
</monster-datatable-filter>
</div>
</monster-tabs>
</div>
</monster-collapse>
<div slot="bar" class="monster-button-group">
<monster-embedded-pagination data-monster-datasource-selector="#myDataSourceID"></monster-embedded-pagination>
<monster-datasource-status
data-monster-option-datasource-selector="#myDataSourceID"></monster-datasource-status>
<monster-datatable-filter-button data-monster-reference="#filter-collapse"
data-monster-role="filter-button">Filter
</monster-datatable-filter-button>
</div>
<template id="row">
<div data-monster-grid-template="1.2rem" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-grid-template="auto" data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-grid-template="3fr" data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="zipcode" data-monster-replace="path:row.zipcode"></div>
<div data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/Sort Data
To enable sorting for individual columns, the attribute data-monster-sortable with the desired field name must be set in the template for the desired column. In this example, the columns id, full_name, country, and username are sortable.
Your individual sorting preferences will then, in the case of a REST data source, be appended to the URL. For example, the URL will look like this:
/example?limit=5&page=${page}&orderBy=${order}
The structure of the query string can be modified using the data-monster-order-template attribute in the respective column in the row template. The default value is ${field} ${direction}. Multiple sorting parameters are separated by commas. The comma delimiter can be changed using the data-monster-datasource-orderdelimiter attribute in the monster-datatable tag.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";<script type="module">// import "@schukai/monster/source/components/datatable/datatable.mjs";
// import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
// import "@schukai/monster/source/components/form/button.mjs";
// import "@schukai/monster/source/components/form/state-button.mjs";
// import "@schukai/monster/source/components/form/confirm-button.mjs";
// import "@schukai/monster/source/components/form/button-bar.mjs";
// import "@schukai/monster/source/components/form/field-set.mjs";</script>HTML
<monster-datasource-rest id="myDatasource"
data-monster-option-features-autoInit="true"
data-monster-option-read-url="/example?limit=5&page=${page}&orderBy=${order}"
></monster-datasource-rest>
<monster-datatable data-monster-datasource-selector="#myDatasource">
<template id="row">
<div data-monster-sortable="id" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-sortable="full_name" data-monster-head="full_name" data-monster-replace="path:row.full_name"></div>
<div data-monster-sortable="country" data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-sortable="username" data-monster-head="username" data-monster-replace="path:row.username"></div>
<div data-monster-head="registered_date" data-monster-replace="path:row.registered_date"></div>
<div data-monster-head="status" data-monster-replace="path:row.status"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/Select Rows
This example demonstrates how to implement row selection in a datatable. It is recommended to ensure the selection column remains visible and has a restricted width, though this is optional.
When a user selects a row, an event is triggered that can be listened to and handled as needed. Among the available events, the most relevant is the generic monster-datatable-selection-changed.
To perform actions on selected rows, a button can be displayed once a selection is made. The selected rows can be retrieved using the getSelectedRows() method, which returns their indices. These indices can then be used to fetch the corresponding data from the datasource.
To automatically show and hide the action buttons, the attribute data-monster-role="row-action-button" must be set. To prevent layout issues, the enclosing container should have the CSS class monster-button-group.
Javascript
import "@schukai/monster/source/components/datatable/datatable.mjs";
import "@schukai/monster/source/components/datatable/embedded-pagination.mjs";
import "@schukai/monster/source/components/datatable/filter.mjs";
import "@schukai/monster/source/components/form/button.mjs";
import "@schukai/monster/source/components/form/state-button.mjs";
import "@schukai/monster/source/components/form/confirm-button.mjs";
import "@schukai/monster/source/components/form/button-bar.mjs";
import "@schukai/monster/source/components/form/field-set.mjs";
const datatable = document.querySelector("monster-datatable");
const eventHandler = function () {
const selected = datatable.getSelectedRows();
// do something with the selected rows
console.log("Selected rows: ", selected);
}
/**
* Listen for the selection change event on the datatable.
*/
datatable.addEventListener("monster-datatable-selection-changed", eventHandler);<script type="module">// const actionButton = document.getElementById("cur34-button-1")
// const datatable = document.getElementById("cur34");
//
// const eventHandler = function () {
// const selected = datatable.getSelectedRows();
// }
//
// datatable.addEventListener("monster-datatable-selection-changed", eventHandler);</script>HTML
<monster-datasource-dom id="myDatasource">
<script type="application/json">
{
"dataset": [
{
"id": 1,
"name": "John Doe",
"street": "Main Street 1",
"city": "Berlin",
"zipcode": "10115",
"country": "Germany",
"phone": "+49 30 1234.56",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"street": "Second Avenue 2",
"city": "Munich",
"zipcode": "80331",
"country": "Germany",
"phone": "+49 89 6543.21",
"email": "jane.doe@example.com"
},
{
"id": 3,
"name": "Max Mustermann",
"street": "Example Road 3",
"city": "Hamburg",
"zipcode": "20095",
"country": "Germany",
"phone": "+49 40 1111.11",
"email": "max.mustermann@example.com"
},
{
"id": 4,
"name": "Lena Schmidt",
"street": "Hauptstrasse 4",
"city": "Cologne",
"zipcode": "50667",
"country": "Germany",
"phone": "+49 221 9876.54",
"email": "lena.schmidt@example.com"
},
{
"id": 5,
"name": "Markus Meier",
"street": "Ringstrasse 5",
"city": "Frankfurt",
"zipcode": "60311",
"country": "Germany",
"phone": "+49 69 4321.98",
"email": "markus.meier@example.com"
}
]
}
</script>
</monster-datasource-dom>
<monster-datatable data-monster-datasource-selector="#myDatasource">
<div slot="bar" class="monster-button-group">
<div class="row-action-buttons">
<monster-button data-monster-role="row-action-button" id="action-button">ACTION</monster-button>
</div>
</div>
<template id="row">
<div data-monster-grid-template="2rem" data-monster-mode="fixed" data-monster-head="id" data-monster-replace="path:row.id"></div>
<div data-monster-grid-template="2rem" data-monster-mode="fixed" data-monster-features="select"><input type="checkbox" data-monster-role="select-row"></div>
<div data-monster-head="name" data-monster-replace="path:row.name"></div>
<div data-monster-head="street" data-monster-replace="path:row.street"></div>
<div data-monster-head="city" data-monster-replace="path:row.city"></div>
<div data-monster-head="country" data-monster-replace="path:row.country"></div>
<div data-monster-head="phone" data-monster-replace="path:row.phone"></div>
<div data-monster-head="email" data-monster-replace="path:row.email"></div>
</template>
</monster-datatable>Stylesheet
/** no additional stylesheet is defined **/Component Design
This component is built using the Shadow DOM, which allows it to encapsulate its internal structure and styling. By using a shadow root, the component's internal elements are isolated from the rest of the webpage, ensuring that external styles or scripts cannot accidentally modify its internal layout or behavior.
Shadow DOM and Accessibility
Since the component is encapsulated within a shadow root, direct access to its internal elements is restricted. This means that developers cannot manipulate or style these elements from outside the component. The Shadow DOM helps maintain consistency in the design and behavior of the component by preventing external interference.
Customizing Through Exported Parts
While the Shadow DOM restricts direct access to the component's internal structure, customization is still possible through exported parts. Specific parts of the component are made accessible for styling by being explicitly marked for export. These exported parts can be targeted and customized using CSS, allowing you to modify the appearance of the component without compromising its encapsulation.
Available Part Attributes
control: This part represents the entire control area of the slider, including navigation buttons and thumbnails. Use this to style the general layout and background of the control panel.
Below is an example of how to use CSS part attributes to customize different parts of the Control.
monster-button::part(control) {
background-color: #f0f0f0;
padding: 10px;
}
Explanation of the Example
monster-button::part(control): Styles the entire control panel, giving it a light background color and some padding.
Accessibility
Accessibility is a key consideration in the design of this component. By following best practices for web accessibility, the component ensures that users of all abilities can interact with it effectively. This includes support for keyboard navigation, screen readers, and other assistive technologies to provide an inclusive user experience.
HTML Structure
<monster-data-table></monster-data-table>JavaScript Initialization
const element = document.createElement('monster-data-table');
document.body.appendChild(element);Exported
DataTableDerived from
CustomElementOptions
The Options listed in this section are defined directly within the class. This class is derived from several parent classes, including the CustomElement class. Therefore, it inherits Options from these parent classes. If you cannot find a specific Options in this list, we recommend consulting the documentation of the CustomElement.
- since
- deprecated
Properties and Attributes
The Properties and Attributes listed in this section are defined directly within the class. This class is derived from several parent classes, including the CustomElement class and ultimately from HTMLElement. Therefore, it inherits Properties and Attributes from these parent classes. If you cannot find a specific Properties and Attributes in this list, we recommend consulting the documentation of the CustomElement.
data-monster-options: Sets the configuration options for the collapse component when used as an HTML attribute.data-monster-option-[name]: Sets the value of the configuration option[name]for the collapse component when used as an HTML attribute.
Methods
The methods listed in this section are defined directly within the class. This class is derived from several parent classes, including the CustomElement class and ultimately from HTMLElement. Therefore, it inherits methods from these parent classes. If you cannot find a specific method in this list, we recommend consulting the documentation of the CustomElement.
Behavioral methods
addRow(data)data{object}: data
- {DataTable}
monster-datatable-row-added
removeRow(index)index{number|string}: index
- {DataTable}
monster-datatable-row-removed
Structural methods
getGridElements(selector)selector{string}: selector
- {NodeList}
getSelectedRows()Static methods
[instanceSymbol]()- {symbol}
instanceof operator.getCSSStyleSheet()- {CSSStyleSheet[]}
getTag()- {string}
Lifecycle methods
Lifecycle methods are called by the environment and are usually not intended to be called directly.
[assembleMethodSymbol]()- void
connectedCallback()- {void}
disconnectedCallback()- {void}
Other methods
copyRow(fromIndex,toIndex)fromIndex{number|string}: fromIndextoIndex{number|string}: toIndex
- {DataTable}
monster-datatable-row-copied
Events
The component emits the following events:
monster-datatable-row-copiedmonster-datatable-row-removedmonster-datatable-row-addedmonster-datatable-row-selectedmonster-datatable-row-deselectedmonster-datatable-all-rows-selectedmonster-datatable-all-rows-deselectedmonster-datatable-selection-changedmonster-datatable-row-copiedmonster-datatable-row-removedmonster-datatable-row-added
For more information on how to handle events, see the mdn documentation.