In this article, we'll discuss which capabilities are expected from a smart table, and assess a few open-source alternatives.
Introduction
Tables are one of the easiest ways to present data on web pages. Plain HTML tables can meet the basic data presentation needs, but trying to squeeze anything sophisticated from them will quickly make you frustrated.
This is when you need to make some important decisions about your application development path. You can start coding enhancements around old-fashioned HTML tables — at the risk of losing focus on your project — or you look at the existing products that are designed to solve your problems.
Today’s market offers dedicated smart table controls that handle the table part for you and provide additional features, including selection modes, sorting and column reordering.
Many companies use data tables to show complex reports, dashboards, financial data, sales results, and even interactive spreadsheets. High demand begot specialized supply, so tables are well represented in web component libraries.
In this article, we'll discuss which capabilities are expected from a smart table, assess a few open-source alternatives, and demonstrate how to create superior HTML smart data tables with GrapeCity's solution for the React JavaScript library. We are assuming that you have some web development experience and preferably familiarity with React.
Table Capabilities
There are some key features that people expect from a smart data table:
-
Data features
- Load data from the various sources, including local files, databases, and APIs
- Searching, filtering, and sorting options
- Load and display of large datasets with pagination
- Ability to import and export data
-
UI features
- Showing and hiding columns
- Inline editing
- Responsiveness — built-in support for multiple devices
- Resizable columns to accommodate long data points inside a column (multi-line comments)
- Horizontal and vertical scroll support
- Data validations and visualizations, such as sparklines
Modern frameworks have built-in implementations of some of these features. However, you have to code more advanced features yourself.
Open Source Frameworks
Created and maintained by Facebook, React is a massively popular open-source JavaScript library. Currently, it holds around 60% of the JavaScript framework market share. With such widespread adoption in the industry, it’s no wonder that many products have been created to serve applications built on React.
Here are some popular open-source smart data table libraries made for React:
These open-source projects have advantages and disadvantages. Depending on which feature you are looking for, some of these components are better than others.
Create a React App with React Data Grid
Let’s build a new Node-based, React application with React Data Grid, an open-source component that has a look-and-feel close to what we are trying to demonstrate.
Install Node.js. Then, using a command-line console, create a new Node React app:
npx create-react-app my-app
cd my-app
npm start
Install the React Data Grid package. Open the package.json file and add these lines in the dependencies section:
"babel-loader": "^8.1.0",
"react-data-grid": "5.0.1",
"react-data-grid-addons": "5.0.4",
"bootstrap": "^4.5.2"
Append the following lines after the browserslist section:
"devDependencies": {
"immutable": "^4.0.0-rc.12"
}
To install the React Data Grid package and its dependencies, run the npm install
command-line instruction:
npm install
Add a new data folder under the src folder, and create a new file named data.js. The user will use the data to populate our data grid:
export const recentSales = [
{
id: 1,
country: "Canada",
soldBy: "Bill",
client: "Cerberus Corp.",
description: "Prothean artifacts",
value: 6250,
itemCount: 50
},
{
id: 2,
country: "Canada",
soldBy: "Bill",
client: "Strickland Propane",
description: "Propane and propane accessories",
value: 2265,
itemCount: 20
},
{
id: 3,
country: "USA",
soldBy: "Ted",
client: "Dunder Mifflin",
description: "Assorted paper-making supplies",
value: 4700,
itemCount: 10
},
{
id: 4,
country: "USA",
soldBy: "Ted",
client: "Utopia Planitia Shipyards",
description: "Dilithium, duranium, assorted shipbuilding supplies",
value: 21750,
itemCount: 250
},
{
id: 5,
country: "USA",
soldBy: "Ted",
client: "Glengarry Estates",
description: "Desks, phones, coffee, steak knives, and one Cadillac",
value: 5000,
itemCount: 5
},
{
id: 6,
country: "Germany",
soldBy: "Angela",
client: "Wayne Enterprises",
description: "Suit armor and run-flat tires",
value: 35000,
itemCount: 25
},
{
id: 7,
country: "Germany",
soldBy: "Angela",
client: "Stark Industries",
description: "Armor and rocket fuel",
value: 25000,
itemCount: 10
},
{
id: 8,
country: "Germany",
soldBy: "Angela",
client: "Nakatomi Trading Corp.",
description: "Fire extinguishers and replacement windows",
value: 15000,
itemCount: 50
},
{
id: 9,
country: "UK",
soldBy: "Jill",
client: "Spaceley Sprockets",
description: "Anti-gravity propulsion units",
value: 25250,
itemCount: 50
},
{
id: 10,
country: "UK",
soldBy: "Jill",
client: "General Products",
description: "Ion engines",
value: 33200,
itemCount: 40
}
];
Add a new components folder under the src folder, and create a new file named OpenSourceTable-Demo.js:
/my-app
/src
/components
OpenSourceTable-Demo.js
Open the OpenSourceTable-Demo.js file and add the following code. (Here, we import the ReactDataGrid
component and declare the React state variables that will be used by the data grid as column definitions and the component’s data source):
import 'bootstrap/dist/css/bootstrap.min.css';
import React, { useState } from 'react';
import ReactDOM from "react-dom";
import ReactDataGrid from "react-data-grid";
import { recentSales } from "../data/data";
export const OpenSourceTableDemo = () => {
const [columns, setColumns] = new useState([
{ key: "id", name: "Id" },
{ key: "country", name: "Country" },
{ key: "soldBy", name: "Sold by" },
{ key: "client", name: "Client" },
{ key: "description", name: "Description" },
{ key: "value", name: "Value" },
{ key: "itemCount", name: "Item Count" }
]);
const [sales, setSales] = new useState(recentSales);
}
Modify the OpenSourceTableDemo
component so that it returns the HTML with the ReactDataGrid
component:
return (
<div className="card main-panel">
<div className="card-header">
<h1>Open Source</h1>
</div>
<div className="card-body">
<h5>React Data Grid Demo</h5>
<p>
Building a Smart Data Table in React with React Data Grid
</p>
<div className="container-fluid">
<div className="row">
<ReactDataGrid
columns={columns}
rowGetter={i => sales[i]}
rowsCount={recentSales.length}
/>
</div>
</div>
</div>
</div>);
Edit the App.js file and replace its contents with the lines below:
import React from 'react';
import './App.css';
import { OpenSourceTableDemo } from './components/OpenSourceTable-Demo.js'
function App() {
return (
<OpenSourceTableDemo/>
);
}
export default App;
Now run the app:
npm start
Once the app is running, you’ll see the React Data Grid displaying the sales data:
To show some of the component features, let’s start customizing our open-source data grid to support cell value updates, row sorting, and column reordering.
Implement Cell Value Update
Open the OpenSourceTable-Demo.js file and add the editable: true attribute to each of the grid column definitions:
{ key: "id", name: "Id", editable: true },
{ key: "country", name: "Country", editable: true },
{ key: "soldBy", name: "Sold by", editable: true },
{ key: "client", name: "Client", editable: true },
{ key: "description", name: "Description", editable: true },
{ key: "value", name: "Value", editable: true },
{ key: "itemCount", name: "Item Count", editable: true }
Add a new onGridRowsUpdated
function to handle cell updates and update the underlying data source:
const onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const s = sales.slice();
for (let i = fromRow; i <= toRow; i++) {
s[i] = { ...s[i], ...updated };
}
setSales(s);
};
Modify the ReactDataGrid
component to add the enableCellSelect={true}
attribute and an onGridRowsUpdated={onGridRowsUpdated}
event handler:
<ReactDataGrid
columns={columns}
rowGetter={i => sales[i]}
rowsCount={recentSales.length}
enableCellSelect={true}
onGridRowsUpdated={onGridRowsUpdated}
/>
These changes allow your React Data Grid to handle updates and persist them in the underlying data source:
Implement Row Sorting
Open the OpenSourceTable-Demo.js file and add the sortable: true
attribute to each column definition to enable column sortability:
{ key: "id", name: "Id", editable: true, sortable: true },
{ key: "country", name: "Country", editable: true, sortable: true },
{ key: "soldBy", name: "Sold by", editable: true, sortable: true },
{ key: "client", name: "Client", editable: true, sortable: true },
{ key: "description", name: "Description", editable: true, sortable: true },
{ key: "value", name: "Value", editable: true, sortable: true },
{ key: "itemCount", name: "Item Count", editable: true, sortable: true }
Implement the new sortRows
function:
const sortRows = (initialRows, sortColumn, sortDirection) => rows => {
const comparer = (a, b) => {
if (sortDirection === "ASC") {
return a[sortColumn] > b[sortColumn] ? 1 : -1;
} else if (sortDirection === "DESC") {
return a[sortColumn] < b[sortColumn] ? 1 : -1;
}
};
return sortDirection === "NONE" ? initialRows : [...rows].sort(comparer);
};
Modify the ReactDataGrid
component to implement the onGridSort
event handler and reference the function we have just created:
<ReactDataGrid
columns={columns}
rowGetter={i => sales[i]}
rowsCount={recentSales.length}
enableCellSelect={true}
onGridRowsUpdated={onGridRowsUpdated}
onGridSort={(sortColumn, sortDirection) =>
setSales(sortRows(sales, sortColumn, sortDirection))
}
/>
Go back to the web page and notice how the columns are now sortable:
Implement Column Reordering
Open the OpenSourceTable-Demo.js file and add this declaration after the imports
section:
const {
DraggableHeader: { DraggableContainer }
} = require("react-data-grid-addons");
Add the draggable: true
property to each column definition to enable column repositioning:
{ key: "id", name: "Id", editable: true, sortable: true, draggable: true },
{ key: "country", name: "Country", editable: true, sortable: true, draggable: true },
{ key: "soldBy", name: "Sold by", editable: true, sortable: true, draggable: true },
{ key: "client", name: "Client", editable: true, sortable: true, draggable: true },
{ key: "description", name: "Description", editable: true, sortable: true, draggable: true },
{ key: "value", name: "Value", editable: true, sortable: true, draggable: true },
{ key: "itemCount", name: "Item Count", editable: true, sortable: true, draggable: true }
Add the onHeaderDrop
function to handle column drag-and-drop event:
const onHeaderDrop = (source, target) => {
var columnsCopy = columns.slice();
const columnSourceIndex = columns.findIndex(
i => i.key === source
);
const columnTargetIndex = columns.findIndex(
i => i.key === target
);
columnsCopy.splice(
columnTargetIndex,
0,
columnsCopy.splice(columnSourceIndex, 1)[0]
);
setColumns(columnsCopy.splice());
setColumns(columnsCopy);
};
Wrap your existing ReactDataGrid
component inside a new DraggableContainer
component:
<DraggableContainer onHeaderDrop={onHeaderDrop}>
<ReactDataGrid
columns={columns}
rowGetter={i => sales[i]}
rowsCount={recentSales.length}
enableCellSelect={true}
onGridRowsUpdated={onGridRowsUpdated}
onGridSort={(sortColumn, sortDirection) =>
setSales(sortRows(sales, sortColumn, sortDirection))
}
/>
</DraggableContainer>
Rerun the app and try moving the grid columns around:
That looks pretty good, but it was a lot of work to implement those features. Now you're on the hook to maintain that code.
Wrapping Up
You can create and use React-based smart data tables in various ways. Some approaches require far more manual work than others, but you can’t tell that until you have already spent enough time trying to use them.
There’s plenty of free and open-source table libraries that might meet your everyday needs. We’ve seen how to implement one of them in this article.
History
- 11th June, 2021: Initial version