DataTable

A beautiful and highly customizable data table. It can be used to display data from a data source.

Import
the javascript logo
import { DataTable } from "@schukai/monster/source/components/datatable/datatable.mjs";
Source
the git logo
Package
the npm logo
Since
1.0.0

Introduction

The Monster Datatable web component is a powerful and flexible tool for displaying data in a tabular format. It is designed to be user-friendly and highly customizable, making it suitable for a wide range of applications.

Key Features

  • Dynamic Interaction: Allows users to interact with content dynamically, making the web experience more intuitive and user-focused.
  • Customizable Appearance: Enables customization of the table’s appearance to align with the visual style of your brand or application, ensuring a consistent look and feel.
  • Accessibility: Built with accessibility in mind, ensuring a seamless experience for all users.
  • Programmatic Control: Offers methods like click, focus, and blur to programmatically control the table’s behavior, giving developers enhanced flexibility.

Enhancing the User Experience

The Monster Datatable enhances user experience by providing a more intuitive and interactive way to display data. It allows users to interact dynamically with content, making the web experience more engaging and user-centered.

Getting Started

Let's begin with a simple example to demonstrate the functionality of the Monster Datatable.

A Basic Example

First, add the Monster Datatable element to your HTML document:

<monster-datatable></monster-datatable>

Now, define the template for each column by using the <template> element within the Monster Datatable element. Each <div> within the template represents a column.

<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>
    </template>
</monster-datatable>

In this setup, the <div> elements in the template have the data-monster-head attribute, which specifies the column header. The data-monster-replace attribute defines the column value, with values sourced from the row object passed to the template.

You can also configure the key for the row object using the templateMapping.row-key option. If not configured, the default key row is used.

Next, you can add data to the table using JavaScript. The simplest way to do this is by setting data through the setOption method:

const datatable = document.querySelector('monster-datatable');
datatable.setOption('data', [
    { "id": "1", "name": "John Doe" },
    { "id": "2", "name": "John Smith" },
    { "id": "3", "name": "Max Mustermann" }
]);

Using a Data Source

Alternatively, you can use a data source to populate the table with data.

<monster-datasource-dom></monster-datasource-dom>

Add the data to be displayed in the table within this data source element. The data source element must have a unique selector, allowing the Monster Datatable element to identify which data source to use. In the simplest case, you can assign an ID to the element, which acts as a selector.

By default, the DataTable looks for the key "dataset" in the data source as the data provider for the table, but this can be configured using the mapping.data option.

<monster-datasource-dom id="myDataSourceID">
    <script type="application/json">
        {
            "dataset": [
                { "id": 1, "name": "John Doe" },
                { "id": 2, "name": "Jane Doe" },
                { "id": 3, "name": "Max Mustermann" }
            ]
        }
    </script>
</monster-datasource-dom>

Now, specify the data source for the Monster Datatable by using the data-monster-datasource-selector attribute.

<monster-datatable data-monster-datasource-selector="#myDataSourceID"></monster-datatable>

As with the basic example, the table is now fully functional. Data is loaded from the data source into the table. For more complex cases, such as data from a REST API, additional configuration options are available.

Further examples can be found in the Usage tab.

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"
        }
    ]);
});

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"
        }
    ]);
});

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"
        }
    ]);
});

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"
        }
    ]);
});

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.

  • monospace Defines a monospace font, ideal for displaying numbers or IDs that need to be easily compared across rows.

  • ellipsis This 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.

  • wrap Enables 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.

  • auto Unlike ellipsis, 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.

  • visible Typically used with components like monster-button-bar that may include pop-ups. Applying this class ensures that the pop-up remains visible when it appears.

  • center, end, start These alignment classes were discussed in a previous example but are included here for completeness. They control the horizontal alignment of content within the cell: center aligns content in the center, end aligns it to the right, and start aligns 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"
        }
    ]);
});

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";

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";

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.

Filter

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";

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";

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);

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

DataTable

Derived from

CustomElement

Options

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.

Option
Type
Default
Description
templates
object
Template definitions
templates.main
string
undefined
Main template
datasource
object
Datasource configuration
datasource.selector
string
Selector for the datasource
datasource.orderDelimiter
string
,
Order delimiter
mapping
object
Mapping configuration
mapping.data
string
dataset
Data mapping
data
array
undefined
Data
headers
array
undefined
Headers
responsive
object
Responsive configuration
responsive.breakpoint
number
900
Breakpoint for responsive mode
labels
object
undefined
Labels
labels.theListContainsNoEntries
string
undefined
Label for empty state
classes
object
Classes
classes.container
string
Container class
features
object
Features
features.settings
boolean
true
Settings feature
features.footer
boolean
true
Footer feature
features.autoInit
boolean
true
Auto init feature (init datasource automatically)
features.doubleClickCopyToClipboard
boolean
true
Double click copy to clipboard feature
features.copyAll
boolean
true
Copy all feature
features.help
boolean
true
Help feature
templateMapping
object
Template mapping
templateMapping.row-key
string
undefined
Row key
templateMapping.filter-id
string
undefined
Filter id

  • 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)
Parameters
  • data {object}: data
Returns
  • {DataTable}
Events
  • monster-datatable-row-added
Add a row to the datatable
removeRow(index)
Parameters
  • index {number|string}: index
Returns
  • {DataTable}
Events
  • monster-datatable-row-removed
Remove a row from the datatable

Structural methods

getGridElements(selector)
Parameters
  • selector {string}: selector
Returns
  • {NodeList}
getSelectedRows()
Get the row number of the selected rows as an array

Static methods

[instanceSymbol]()
Returns
  • {symbol}
This method is called by the instanceof operator.
getCSSStyleSheet()
Returns
  • {CSSStyleSheet[]}
getTag()
Returns
  • {string}

Lifecycle methods

Lifecycle methods are called by the environment and are usually not intended to be called directly.

[assembleMethodSymbol]()
Returns
  • void
connectedCallback()
Returns
  • {void}
disconnectedCallback()
Returns
  • {void}

Other methods

copyRow(fromIndex,toIndex)
Parameters
  • fromIndex {number|string}: fromIndex
  • toIndex {number|string}: toIndex
Returns
  • {DataTable}
Events
  • monster-datatable-row-copied
Copy a row from the datatable

Events

The component emits the following events:

  • monster-datatable-row-copied
  • monster-datatable-row-removed
  • monster-datatable-row-added
  • monster-datatable-row-selected
  • monster-datatable-row-deselected
  • monster-datatable-all-rows-selected
  • monster-datatable-all-rows-deselected
  • monster-datatable-selection-changed
  • monster-datatable-row-copied
  • monster-datatable-row-removed
  • monster-datatable-row-added

For more information on how to handle events, see the mdn documentation.

The current width of the area is too small to display the content correctly.