https://github.com/flipbyte/redux-datatable
Datatable for react-redux
https://github.com/flipbyte/redux-datatable
data-table datatable react react-datatable redux redux-datatable
Last synced: 25 days ago
JSON representation
Datatable for react-redux
- Host: GitHub
- URL: https://github.com/flipbyte/redux-datatable
- Owner: flipbyte
- License: mit
- Created: 2019-02-13T08:36:08.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2023-04-30T10:54:59.000Z (almost 3 years ago)
- Last Synced: 2025-10-03T15:40:08.445Z (4 months ago)
- Topics: data-table, datatable, react, react-datatable, redux, redux-datatable
- Language: JavaScript
- Homepage:
- Size: 2.62 MB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# @flipbyte/redux-datatable
[Developed by Flipbyte](https://www.flipbyte.com/)
[![npm package][npm-badge]][npm]
[![Codacy Badge][codacy-badge]][codacy]
Datatable built using React and Redux to fetch JSON data asynchronously
using REST API.
- Filterable columns by date ranges, numeric ranges and text.
- Pagination
- Sortable columns
- Configurable column widths
- Editable table
- Built in windowing to handle large dataset with thousands of rows
- Customizable limiter options
- Customizable toolbar with the ability to add custom renderers
- Easily configurable layout
- Custom row level actions
- Thunks to handle custom mass or row actions externally.
- Compatible with normalizr to handle externally managed states
- Easily styleable with styled-components and/or external css.
- Show or hide columns dynamically using the Columns item in the
toolbar.
## Installation
Run the following command to install using npm
```sh
npm i @flipbyte/redux-datatable
```
## Usage
### Add the table reducer and epics to your store
```javascript
// Get the table reducer and epics as follows
import { reducer, epics } from '@flipbyte/redux-datatable';
// Add the above reducer and epics to your store.
```
### Preparing your table config object
```javascript
{
name: 'your_table_name', // this is the key used to set your table data inside the table reducer
height: 400,
rowHeight: 50,
editing: false,
primaryKey: 'id',
noResultsMessage: 'No row(s) found',
routes: { // You can add other routes and handle them using custom actions.
get: { // The route used to fetch data and it's params
route: '/{your_route}',
sort: 'id',
dir: 'asc',
resultPath: {
data: 'data'
},
params: {
...your_params_key_value_pair
}
},
...
},
entity: { // optional. Check example code in /demo.
state: '{your state path}',
responseSchema: // normalizr schema,
schema: // normal;izr schema
},
layout: [
['Editable'],
['MassActions', 'SimpleButton', 'ResetFilters', 'Spacer', 'Print', 'Columns'],
['Limiter', 'Spacer', 'ResultCount', 'Spacer', 'Pages'],
[{ id: 'Table', layout: [
['Header'],
['Filters'],
['Body'],
['Header']
]}],
['Limiter', 'Spacer', 'ResultCount', 'Spacer', 'Pages'],
],
components: {
Header: {
rowClassName: 'your custom class names',
colClassName: 'your custom class names',
className: 'your custom class names',
},
Body: {
rowClassName: 'your custom class names',
colClassName: 'your custom class names',
className: 'your custom class names',
},
Filters: {
rowClassName: 'your custom class names',
colClassName: 'your custom class names',
className: 'your custom class names',
},
Loader: {
styles: {
mask: { ... },
spinner: { ... }
}
},
ResultCount: {
className: 'your custom class names',
styles: { ... }
},
Pages: {
firstClassName: 'your custom class names',
lastClassName: 'your custom class names',
nextClassName: 'your custom class names',
prevClassName: 'your custom class names',
pageNumberClassName: 'your custom class names',
activeClassName: 'your custom class names',
styles: {
first: { ... },
last: { ... },
previous: { ... },
next: { ... },
pageNumber: { ... },
}
},
Editable: {
type: 'editable',
labels: {
show: 'Make editable',
hide: 'Hide editable',
save: 'Save',
},
classNames: {
show: 'your custom class names',
hide: 'your custom class names',
save: 'your custom class names',
},
save: ( config ) => ( dispatch, getState ) => {
const tableState = getState()[config.reducerName][config.name];
console.log('toolbar save click with modified data', config, tableState.modified);
config.action(MODIFY_DATA)({ clear: true });
// Dispatch MODIFY_DATA action with clear: true, to reset the modified data
// Dispatch REQUEST_DATA action "config.action(REQUEST_DATA)" to refresh data.
},
styles: {
show: { ... },
hide: { ... },
save: { ... }
}
// renderer: ( props ) => { ... }
},
MassActions: {
name: 'actions',
label: 'Actions',
id: 'dropdown',
className: 'your custom class names',
btnClassName: 'your custom class names',
menuClassName: 'your custom class names',
menuItemClassName: 'your custom class names',
activeClassName: 'your custom class names',
styles: {
button: { ... },
dropdownMenu: { ... },
dropdownItem: { ... }
}
options: [{
type: 'action',
name: 'delete',
label: 'Delete',
styles: { ... },
thunk: ( config ) => ( dispatch, getState ) => {
// Get current table state.
const tableState = getState()[config.reducerName][config.name];
console.log(config, tableState);
console.log(getItemIds(tableState.selection, tableState.items, config.primaryKey/*, config.entity.schema*/))
confirm('Are your sure you want to delete the selected items?')
? console.log('delete items', config, getState(), tableState)
: console.log(false);
// Filter your selected item ids here for deletion
// You can find the selection data in the selection key of the tableState.
// When all:true, exclude the ids in the selected object with value false and vice versa.
}
}, {
type: 'action',
name: 'edit',
label: 'Edit this field',
}, ...]
},
SimpleButton: {
type: 'button',
label: 'Simple Button',
className: 'your custom class names',
thunk: ( config ) => ( dispatch, getState ) => { ... },
styles: { ... }
},
ResetFilters: {
type: 'reset-filters',
label: 'Reset Filters',
className: 'your custom class names',
styles: { ... }
},
Print: {
type: 'print',
label: 'Print Table',
className: 'your custom class names',
styles: { ... }
},
Columns: {
name: 'columns',
type: 'columns',
label: 'Columns',
visible: true,
className: 'your custom class names',
btnClassName: 'your custom class names',
menuClassName: 'your custom class names',
menuItemClassName: 'your custom class names',
activeClassName: 'your custom class names',
styles: {
button: { ... },
dropdownMenu: { ... },
dropdownItem: { ... }
}
},
Limiter: {
type: 'limiter',
options: [10, 20, 50, 200, 2000, 0],
default: 200,
className: 'your custom class names',
selectClassName: 'your custom class names',
styles: { ... }
},
Table: {
className: 'your custom class names',
styles: {
table: { ... },
thead: { ... },
tbody: { ... },
filters: { ... },
tr: {
header: { ... },
filters: { ... },
body: { ... }
},
th: { ... },
td: {
filters: { ... },
body: { ... }
}
},
columns: [{
name: 'id',
label: '',
sortable: false,
type: 'selection',
width: 50,
}, {
label: 'ID',
type: 'number',
name: 'id',
sortable: true,
width: 150,
filterable: true,
sortable: true,
}, {
label: "Status",
type: "options",
name: "status",
sortable: true,
filterable: true,
textAlign: "center",
options: {
"published": {
label: "Published"
},
"draft": {
label: "Draft"
},
"archived": {
label: "Archived"
},
...
}
}, {
label: 'Avatar',
type: 'image',
name: 'avatar',
sortable: false,
textAlign: 'center',
width: 200,
filterable: false,
imgHeight: 50
}, {
label: 'First Name',
type: 'string',
name: 'first_name',
sortable: true,
textAlign: 'text-left',
width: 200,
filterable: true,
}, {
label: 'Actions',
type: 'actions',
name: 'actions',
width: 100,
items: [{
type: 'action',
name: 'edit',
label: 'Edit',
btnClass: 'btn btn-secondary',
icon: 'edit',
thunk: ( payload ) => ( dispatch, getState ) => {
console.log('edit', payload, getState());
},
style: { ... }
}, {
type: 'action',
name: 'delete',
label: 'Delete',
icon: 'trash-alt',
thunk: ( payload ) => ( dispatch, getState ) => {
confirm("Are your sure you want to delete this page?")
? console.log('delete', getState())
: console.log(false);
},
style: { ... }
},
...
]
},
...
]
}
}
}
```
### Render table component
```javascript
import ReduxDatatable from '@flipbyte/redux-datatable';
const YourComponent = () =>
```
### Table config props
| Key | Type | Required | Default | Description |
| ---------------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------------------ |
| name | string | true | - | key in the row data whose value needs to be loaded for the column (does not have to be unique) |
| height | integer | true | - | The maximum height of the table |
| rowHeight | integer | true | - | The maximum height of each table body row |
| routes | object | true | - | Routes definition to fetch data and other custom routes config for custom handling (Check below) |
| components | object | true | - | All the components required for your table |
| entity | object | false | - | [Normalizr](https://github.com/paularmstrong/normalizr) specification. Check below for details. |
| layout | array | true | - | The layout of your table |
| editing | boolean | false | false | Set the default state of the table to be in editing mode |
| primaryKey | string | true | - | Set the primary key column of the table for actions like editing. |
| noResultsMessage | string | true | - | Set the message to be displayed when table is empty |
#### Routes object
| Key | Type | Required | Default | Description |
| ---------- | ------ | -------- | ------- | ---------------------------------------------------------------------------------------------------- |
| get | object | true | - | The configuration for fetching data |
| **- get** | | | | |
| route | string | true | - | Your data fetching route |
| sort | string | true | - | Your key to sort with |
| dir | string | true | - | Sort by 'asc' or 'desc' order |
| resultPath | object | true | - | The keys object to your data. Required { data: '{your data path in json response. Ex: result.data}'} |
| params | object | false | - | Key-value pairs of additional params that you want to pass to the request |
#### Components object
Components can be defined within this object as key value pairs, where `key` is the id of the component and needs to be unique and `value` is a configuration object for the specific component.
All available components are listed below with their configuration. Custom components can be added and existing components can be overridden by using the key `renderer` in the configuration object of the component.
Please check the example table config object above.
#### Layout array
An array of arrays where each inner array represents a row in the layout, within which components can be specified, which will be displayed in the frontend.
Please check the example table config object above.
#### Entity array
All the fields are required when entity is defined (data normalized). However, entity key itself is optional in the table config.
| Key | Type | Required | Default | Description |
| -------------- | ------ | -------- | ------- | --------------------------------------------------------------------------------------- |
| state | object | true | - | Path to sub state in your top level redux state where the normalized data will be saved |
| responseSchema | object | true | - | Define how the data is represented in your fetch data api response |
| schema | object | true | - | Define how the data is represented in each row item of the table fetch repsonse |
| selectors | object | true | - | Add the selectors that will be used by columns to fetch respective data |
Note: Check the [example](https://github.com/flipbyte/redux-datatable/blob/master/demo/src/schema/normalized.js) code.
#### Available Components
**_Common Properties_**
| Key | Type | Required | Default | Description |
| --------- | -------- | -------- | ------- | -------------------------------------------------------------------------------------------------- |
| styles | object | false | {} | styled-component styles object or key-value pairs with values being styled-component styles object |
| renderer | function | false | - | returns a react component |
| type | string | true | - | the type of the object |
| className | string | true | varies | html class names for top-level html element in the component |
##### Loader
Note: This component cannot be added to the layout and does not have any other properties except styles.
**_Styles object properties_**
| Key | Type | Required | Default | Description |
| ------- | ------ | -------- | ------- | ------------------------------ |
| mask | object | false | {} | styled-component styles object |
| spinner | object | false | {} | styled-component styles object |
##### ResultCount
No unique properties
##### Pages
**_Properties_**
| Key | Type | Required | Default | Description |
| ------------------- | ------ | -------- | ------------ | ---------------- |
| firstClassName | string | false | rdt-pg-first | html class names |
| lastClassName | string | false | rdt-pg-last | html class names |
| prevClassName | string | false | rdt-pg-prev | html class names |
| nextClassName | string | false | rdt-pg-next | html class names |
| pageNumberClassName | string | false | rdt-pg-num | html class names |
| activeClassName | string | false | active | html class names |
**_Styles object properties_**
| Key | Type | Required | Default | Description |
| ---------- | ------ | -------- | ------- | ------------------------------ |
| first | object | false | {} | styled-component styles object |
| last | object | false | {} | styled-component styles object |
| previous | object | false | {} | styled-component styles object |
| next | object | false | {} | styled-component styles object |
| pageNumber | object | false | {} | styled-component styles object |
##### Editable (type: editable)
Toggles the table between editable and non-editable and shows a save button when the content of the table is modified
**_Properties_**
| Key | Type | Required | Default | Description |
| ---------- | -------- | -------- | ----------- | ----------------------------------------------- |
| labels | object | false | check below | check below |
| save | function | false | - | ( config ) => ( dispatch, getState ) => { ... } |
| classNames | object | false | check below | check below |
**_classNames object properties_**
| Key | Type | Required | Default | Description |
| ---- | ------ | -------- | ---------------------- | ---------------- |
| show | string | false | rdt-toolbar-button | html class names |
| hide | string | false | rdt-toolbar-button | html class names |
| save | string | false | Sardt-toolbar-buttonve | html class names |
**_Labels object properties_**
| Key | Type | Required | Default | Description |
| ---- | ------ | -------- | ------------- | ----------------------------------------------- |
| show | string | false | Make editable | Label for the button to show editable table |
| hide | string | false | Hide editable | Label for the button to hide editable table |
| save | string | false | Save | Label for the button to save the modified table |
**_Styles object properties_**
| Key | Type | Required | Default | Description |
| ---- | ------ | -------- | ------- | ------------------------------ |
| show | object | false | {} | styled-component styles object |
| hide | object | false | {} | styled-component styles object |
| save | object | false | {} | styled-component styles object |
##### Actions (type: mass-actions)
**_Properties_**
| Key | Type | Required | Default | Description |
| ----------------- | ------ | -------- | ------------------ | ------------------------------------- |
| options | array | true | \[] | array of actions objects |
| label | string | true | - | Label for the actions dropdown button |
| btnClassName | string | false | rdt-toolbar-button | html class names |
| menuClassName | string | false | rdt-toolbar-menu | html class names |
| menuItemClassName | string | false | rdt-toolbar-item | html class names |
| activeClassName | string | false | show | html class names |
**_Actions object properties_**
| Key | Type | Required | Default | Description |
| ----- | -------- | -------- | ------- | ----------------------------------------------- |
| type | string | true | - | action |
| name | string | true | - | Unique name |
| label | string | true | - | Label for the action item |
| role | string | false | - | Add role 'menu-item' to hide dropdown on click |
| thunk | function | true | - | ( config ) => ( dispatch, getState ) => { ... } |
**_Styles object properties_**
| Key | Type | Required | Default | Description |
| ------------ | ------ | -------- | ------- | ------------------------------ |
| button | object | false | {} | styled-component styles object |
| dropdownMenu | object | false | {} | styled-component styles object |
| dropdownItem | object | false | {} | styled-component styles object |
##### Button (type: button)
**_Properties_**
| Key | Type | Required | Default | Description |
| ----- | ------ | -------- | ------- | ------------------------------------- |
| label | string | required | - | Label for the actions dropdown button |
##### ResetFilters (type: reset-filters)
**_Properties_**
| Key | Type | Required | Default | Description |
| ----- | ------ | -------- | ------- | ------------------------------------- |
| label | string | required | - | Label for the actions dropdown button |
##### Print (type: print)
Makes the table printable.
**_Properties_**
| Key | Type | Required | Default | Description |
| ----- | ------ | -------- | ------- | ------------------------------------- |
| label | string | required | - | Label for the actions dropdown button |
##### Columns (type: columns)
Shows the columns toggling dropdown.
**_Properties_**
| Key | Type | Required | Default | Description |
| ----------------- | ------ | -------- | ------------------ | ------------------------------------- |
| label | string | required | - | Label for the actions dropdown button |
| btnClassName | string | false | rdt-toolbar-button | html class names |
| menuClassName | string | false | rdt-toolbar-menu | html class names |
| menuItemClassName | string | false | rdt-toolbar-item | html class names |
| activeClassName | string | false | show | html class names |
**_Styles object properties_**
| Key | Type | Required | Default | Description |
| ------------ | ------ | -------- | ------- | ------------------------------ |
| button | object | false | {} | styled-component styles object |
| dropdownMenu | object | false | {} | styled-component styles object |
| dropdownItem | object | false | {} | styled-component styles object |
##### Limiter (type: limiter)
| Key | Type | Required | Default | Description |
| --------------- | ------- | -------- | ------------------ | --------------------------------------------------------------------- |
| options | array | required | \[] | array of limiter counts |
| default | integer | required | \[] | default limiter option (should be a value in the options array above) |
| selectClassName | string | false | rdt-limiter-select | html class names |
##### Table (type: table)
| Key | Type | Required | Default | Description |
| ------- | ----- | -------- | ------- | ----------------------------------------- |
| columns | array | required | \[] | array of object with column configuration |
**_Columns object properties_**
| Key | Type | Required | Default | Description | |
| ------------------------------- | -------- | -------- | ------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | string | true | - | Unique name for the column | |
| label | string | true | - | Label for the column | |
| sortable | boolean | false | true | Whether the column is sortable | |
| filterable | boolean | false | true | Whether the column is filterable | |
| editable | boolean | false | false | When the table is set to be editable, set whether the respective column is among the editable | |
| visible | boolean | false | true | Whether the column is visible on load | |
| type | string | true | string | Available types: selection, number, date, string, image, options, actions | |
| width | integer | true | - | Width of the column | |
| textAlign | string | false | left | Text alignment in the column | |
| renderer | function | false | - | Define a custom renderer for column body. | |
| selector | string | object | false | - | Define a custom selector to pick the value for the column from the state. When string is used, the selector should be defined under entity.selectors |
| **type: actions** | | | | | |
| items | array | true | - | array of item configuration object | |
| **- item configuration object** | | | | | |
| name | string | true | - | Unique name for the action | |
| label | string | true | - | Label for the action | |
| thunk | function | true | - | An action creator which is dispatched on action click. Check demo schema. | |
**_Properties specific to column of type 'options'_**
| Key | Type | Required | Default | Description |
| ------- | ------ | -------- | ------- | -------------------------------------------- |
| options | object | true | - | Defines options for the column. Check below. |
`options` key is an object with a unique key for each value object. The value object consists of a property `label` used to define the label of the said option. Please check the following example:
```js
options: {
active: {
label: 'Active'
},
inactive: {
label: 'Inactive'
}
...
}
```
**_Properties specific to column of type 'actions'_**
| Key | Type | Required | Default | Description |
| ----- | ----- | -------- | ------- | ---------------------------------- |
| items | array | true | - | array of item configuration object |
**_Properties for a single item of type 'actions'_**
| Key | Type | Required | Default | Description |
| ------ | -------- | -------- | ------- | ------------------------------------------------------------------------------- |
| name | string | true | - | Unique name for the action |
| label | string | true | - | Label for the action |
| thunk | function | true | - | An action creator which is dispatched on action click. Check the example below. |
| styles | object | false | {} | styled-component styles object |
Example:
```js
{
type: 'action',
name: 'edit',
label: 'Edit',
btnClass: 'btn btn-secondary',
icon: 'edit',
thunk: ( payload ) => ( dispatch, getState ) => {
console.log('edit', payload, getState());
},
styles: { ... }
}
```
**_Styles object properties_**
| Key | Type | Required | Default | Description |
| ------- | ------ | -------- | ------- | ------------------------------ |
| table | object | false | {} | styled-component styles object |
| thead | object | false | {} | styled-component styles object |
| tbody | object | false | {} | styled-component styles object |
| filters | object | false | {} | styled-component styles object |
| tr | object | false | {} | check below |
| th | object | false | {} | styled-component styles object |
| td | object | false | {} | check below |
**_tr Styles object properties_**
| Key | Type | Required | Default | Description |
| ------- | ------ | -------- | ------- | ------------------------------ |
| header | object | false | {} | styled-component styles object |
| filters | object | false | {} | styled-component styles object |
| body | object | false | {} | styled-component styles object |
**_td Styles object properties_**
| Key | Type | Required | Default | Description |
| ------- | ------ | -------- | ------- | ------------------------------ |
| filters | object | false | {} | styled-component styles object |
| body | object | false | {} | styled-component styles object |
## License
The MIT License (MIT)
[npm-badge]: https://img.shields.io/npm/v/@flipbyte/redux-datatable.svg
[npm]: https://www.npmjs.com/package/@flipbyte/redux-datatable
[codacy-badge]: https://api.codacy.com/project/badge/Grade/67274650b4874f5db55ede76156ab4d2
[codacy]: https://www.codacy.com/app/flipbyte/redux-datatable?utm_source=github.com&utm_medium=referral&utm_content=flipbyte/redux-datatable&utm_campaign=Badge_Grade