Using ORGENIC UI Datatable Component
Tags: orgenicui, webcomponents, ux, design
Published: 2019-05-20 13:01:44

---
title: Using ORGENIC UI Datatable Component
published: true
description: ORGENIC UI is a growing set of web components with focus on UX and design.
tags: ORGENIC UI, Web Components, UX, Design
cover_image: https://thepracticaldev.s3.amazonaws.com/i/gz0auh41gwm4ien2mbc2.png
series: ORGENIC UI Tutorials
---

ORGENIC UI is a growing set of web components with focus on UX and design. This tutorial shows how to use the datatable component.

The datatable component can be used to display large sets of data in a high-performance flexible table. The component is based on [Tabulator](https://github.com/olifolkerd/tabulator) and some easy-to-use interfaces to hide the complexity of the library.

In this tutorial we are using plain JS without any framework, but you can also use any framework like Angular, React or Vue with its comfortable databinding.


## General

The datatable itself is just a single line of code. Everything else like configuration and data providers are set via JavaScript or can be set via data binding using the framework of your choice.

```html
<og-datatable id="datatable"></og-datatable>
```

In JavaScript resolve the data table element using query selector:

```javascript
const datatable = document.querySelector('#datatable');
```

## Configuration

The datatable only has one configuration object with column definition and a data service which can serve client side data or (lazy loaded) data from the backend. Also an optional message which is displayed if no data is available can be defined.

```javascript
datatable.config =  {
    noDataMessage: 'No items available',
    dataService: paginatedDataService,
    columns: columnConfiguration
};
```

## Columns

A basic column declaration is very simple. It's just the definition of the data property and the column title.

```javascript
const columnConfiguration = [
    //...
    {
        property: 'name',
        title: 'Label'
    },
    //...
];
```

### Custom Column Formatter

A custom column formatter can be specified as string or a function to add custom code. This example shows how to draw colored circles according to the value of the activity property.

```javascript
const columnConfiguration = [
    //...
    {
        property: 'activity',
        title: 'Activity',
        formatter: (cell, formatterParams, onRendered) => {
            let colored = '';
            for (let i = 0; i < cell.getValue(); i++) {
                const hue = 150 - (37.5 * i);
                colored += '<span style="color: hsl(' + hue + ',100%,40%)">&#10687;</span>';
            }
            return '<strong>' + colored + '</strong>';
        }
    }
    //...
]
```

You can read more about the formatter specification at the [Tabulator documentation](http://tabulator.info/docs/4.0/format).

### Custom Column Sorter

If you need a column sorter for e.g. columns containing formatted dates, you can add a sort function.

This function has two parameters that represent to cell values to be compared. The result should be a negative value if `a` is smaller than `b`, `0` if the two values are equal or a positive value if `a` is greater than `b`.

```javascript
const columnConfiguration = [
    //...
    {
        property: 'date',
        title: 'Date',
        sorter: (a, b) => {
            // this example requires momentjs
            return moment(a, 'DD.MM.YYYY').valueOf() - moment(b, 'DD.MM.YYYY').valueOf();
        }
    }
    //...
]
```

## Data Service

The datatable component can be used in two different presentation modes: you can have an infinite scrolling table or a paginated table. Both modes can be used with in-memory-data or with lazy loaded data from a remote resource.

If you have a large amount of data on the client side, you can also implement a lazy loading data service. This data service serves smaller chunks of data on demand to boost performance of the table.

The data service interface is split into these parts:

* __type__ (scrolled / paginated)
* __options__ (optional)
* __provider__
  * __type__ (default / lazy)
  * __getData__ (async function returning array of data or object of type LazyDataResponse)

### Scrolling

The first scenario is an infinite scrolling data service with all data available on client side. You just have to return the array in an async function.

```javascript
const scrollDataService = {
    type: 'scrolled',
    provider: {
        type: 'default',
        getData: async () => tableData
    }
};
```

### Scrolling + Lazy Loading

If you need to have a large amount of data, you should load it lazily. Also if you have all the data available on client side it might be a good idea to use a lazy data provider to improve table initialization performance.

The property `requestLimit` within the options object defines how many items will be requested per chunk.

The return value of the async function `getData` must contain the total row count (`totalRows`) and the data array.

```javascript
const scrollLazyDataService = {
    type: 'scrolled',
    options: {
        requestLimit: 10
    },
    provider: {
        type: 'lazy',
        getData: async (page, size, sorters) => {
            // request data from server and return:
            return {
                totalRows: 0, // total number of available rows
                data: [ ] // data array
            };
        }
    }
};
```

### Pagination

If you'd like to use a paginated table you configure this service type and set the page size within the options object. The default data provider has an async function `getData` returning the plain data array.

```javascript
const paginatedDataService = {
    type: 'paginated',
    options: {
        pageSize: 5
    },
    provider: {
        type: 'default',
        getData: async () => tableData
    }
};
```

### Pagination + Lazy Loading

Using a lazy data provider for paginated table does not need any additional configuration. The chunk size for each request is defined by `pageSize`.

The return value of the async function `getData` must contain the total row count (`totalRows`) and the data array.

```javascript
const paginatedLazyDataService = {
    type: 'paginated',
    options: {
        pageSize: 5
    },
    provider: {
        type: 'lazy',
        getData: async (page, size, sorters) => {
            // request data from server and return:
            return {
                totalRows: 0, // total number of available rows
                data: [ ] // data array
            };
        }
    }
};
```

## Handling Selection Events

Selecting items will emit an event that you can handle with an event listener. You can add this event listener on the HTML object selected by a query selector or by binding an event listener when working with a framework like angular, react or vue.

```javascript
const datatable = document.querySelector('#datatable');
datatable.addEventListener('itemSelected', e => {
    // e.detail contains selected object
});
```

## Comments
For using the async function or a function returning a promise you should use babel to transpile your code to ES5 if you need to enhance browser support.


To see the datatables in action, take a look at this CodePen:

{% codepen https://codepen.io/orgenic-team/pen/EzxqQz %}

Please visit us at:

* [ORGENIC.org](https://orgenic.org/?utm_source=devto&utm_medium=article&utm_campaign=datatable)
* [Documentation](https://docs.orgenic.org/components/og-datatable)
* [Github](https://github.com/orgenic/orgenic-ui)
* [Twitter](https://twitter.com/orgenicUI)