React Grid | Get Started with ag-Grid and React

ag-Grid is the industry standard for React Enterprise Applications. Developers using ag-Grid are building applications that would not be possible if ag-Grid did not exist.

Quick Look Code Example
import { AgGridReact } from '@ag-grid-community/react'; import {AllCommunityModules} from '@ag-grid-community/all-modules'; import '@ag-grid-community/all-modules/dist/styles/ag-grid.css'; import '@ag-grid-community/all-modules/dist/styles/ag-theme-balham.css'; class App extends Component { constructor(props) { super(props); this.state = { columnDefs: [ { headerName: "Make", field: "make" }, { headerName: "Model", field: "model" }, { headerName: "Price", field: "price" }], rowData: [ { make: "Toyota", model: "Celica", price: 35000 }, { make: "Ford", model: "Mondeo", price: 32000 }, { make: "Porsche", model: "Boxter", price: 72000 }] } } render() { return ( <div className="ag-theme-balham" style={ {height: '200px', width: '600px'} }> <AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.rowData} modules={AllCommunityModules}> </AgGridReact> </div> ); } } render(<App />, document.getElementById('root'));
<div id="root"></div>

Getting Started

In this article, we will walk you through the necessary steps to add ag-Grid (both Community and Enterprise are covered) to an existing React project, and configure some of the essential features of it. We will show you some of the fundamentals of the grid (passing properties, using the API, etc). As a bonus, we will also tweak the grid's visual appearance using Sass variables.

Add ag-Grid to Your Project

For the purposes of this tutorial, we are going to scaffold a react app with create-react-app. Don't worry if your project has a different configuration. ag-Grid and the React wrapper are distributed as NPM packages, which should work with any common React project module bundler setup. Let's follow the create-react-app instructions - run the following commands in your terminal:

npx create-react-app my-app cd my-app npm start
npx comes with npm 5.2+ and higher, see instructions for older npm versions

If everything goes well, npm start has started the web server and conveniently opened a browser pointing to localhost:3000.

As a next step, let's add the ag-Grid NPM packages. run the following command in my-app (you may need a new instance of the terminal):

npm install --save @ag-grid-community/all-modules @ag-grid-community/react # or, if using Enterprise features npm install --save @ag-grid-enterprise/all-modules @ag-grid-community/react

After a few seconds of waiting, you should be good to go. Let's get to the actual coding! Open src/App.js in your favorite text editor and change its contents to the following:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { AgGridReact } from '@ag-grid-community/react';
import {AllCommunityModules} from '@ag-grid-community/all-modules';

import '@ag-grid-community/all-modules/dist/styles/ag-grid.css';
import '@ag-grid-community/all-modules/dist/styles/ag-theme-balham.css';

// or, if using Enterprise features
// import '@@ag-grid-enterprise/all-modules/dist/styles/ag-grid.css';
// import '@@ag-grid-enterprise/all-modules/dist/styles/ag-theme-balham.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      columnDefs: [{
        headerName: "Make", field: "make"
      }, {
        headerName: "Model", field: "model"
      }, {
        headerName: "Price", field: "price"
      }],
      rowData: [{
        make: "Toyota", model: "Celica", price: 35000
      }, {
        make: "Ford", model: "Mondeo", price: 32000
      }, {
        make: "Porsche", model: "Boxter", price: 72000
      }]
    }
  }

  render() {
    return (
      <div 
        className="ag-theme-balham"
        style={{ 
        height: '500px', 
        width: '600px' }} 
      >
        <AgGridReact
          columnDefs={this.state.columnDefs}
          rowData={this.state.rowData}
          modules={AllCommunityModules}>
        </AgGridReact>
      </div>
    );
  }
}

export default App;

Done? If everything is correct, we should see a simple grid that looks like this:

ag-Grid in its simplest form

Let's go over the App.jsx changes we made:

import {AgGridReact} from '@ag-grid-community/react';
import {AllCommunityModules} from '@ag-grid-community/all-modules';

import '@ag-grid-community/all-modules/dist/styles/ag-grid.css';
import '@ag-grid-community/all-modules/dist/styles/ag-theme-balham.css';

// or, if using Enterprise features
// import '@@ag-grid-enterprise/all-modules/dist/styles/ag-grid.css';
// import '@@ag-grid-enterprise/all-modules/dist/styles/ag-theme-balham.css';

The three lines above import the AgGridReact component, the modules we wish to use, the grid "structure" stylesheet (ag-grid.css), and one of the available grid themes: (ag-theme-balham.css).

You can find out more about modules here, but for now all you need to know is that modules make up the parts of the grid that you wish to use. In this case we're going to use all the functionality in the Community version of ag-Grid.

The grid ships several different themes; pick one that matches your project design. You can customize it further with Sass variables, a technique which we will cover further down the road.

constructor(props) { super(props); this.state = { columnDefs: [{ headerName: "Make", field: "make" }, { headerName: "Model", field: "model" },{ headerName: "Price", field: "price" }], rowData: [{ make: "Toyota", model: "Celica", price: 35000 },{ make: "Ford", model: "Mondeo", price: 32000 },{ make: "Porsche", model: "Boxter", price: 72000 }] } }

The code above presents two essential configuration properties of the grid - the column definitions (columnDefs) and the data (rowData). In our case, the column definitions contain three columns; each column entry specifies the header label and the data field to be displayed in the body of the table.

The actual data is defined in the rowData as an array of objects. Notice that the fields of the objects match the field values in the columnDefs configuration object.

<div style={{ height: '150px', width: '600px' }} className="ag-theme-balham">
    <AgGridReact
        columnDefs={this.state.columnDefs}
        rowData={this.state.rowData}
        modules={AllCommunityModules}>
    </AgGridReact>
</div>

Finally, the JSX code above describes a wrapper DIV element which sets the grid dimensions and specifies the grid's theme by setting the className to ag-theme-balham. As you may have already noticed, the CSS class matches the name of CSS file we imported earlier.

Inside the container, we place an AgGridReact component with the configuration objects (columnDefs and rowData) from the component's constructor passed as properties.

Enable Sorting And Filtering

So far, so good. But wouldn't it be nice to be able to sort the data to help us see which car is the least/most expensive? Well, enabling sorting in ag-Grid is actually quite simple - all you need to do is set the sort property to the column definitions.

columnDefs: [{ headerName: "Make", field: "make", sortable: true }, { headerName: "Model", field: "model", sortable: true }, { headerName: "Price", field: "price", sortable: true }]

After adding the property, you should be able to sort the grid by clicking on the column headers. Clicking on a header toggles through ascending, descending and no-sort.

Our application doesn't have too many rows, so it's fairly easy to find data. But it's easy to imagine how a real-world application may have hundreds (or even hundreds of thousands!) or rows, with many columns. In a data set like this filtering is your friend.

As with sorting, enabling filtering is as easy as setting the filter property:

columnDefs: [{ headerName: "Make", field: "make", sortable: true, filter: true }, { headerName: "Model", field: "model", sortable: true, filter: true },{ headerName: "Price", field: "price", sortable: true, filter: true }]

With this property set, the grid will display a small column menu icon when you hover the header. Pressing it will display a popup with filtering UI which lets you choose the kind of filter and the text that you want to filter by.

ag-Grid sorting and filtering

Fetch Remote Data

Displaying hard-coded data in JavaScript is not going to get us very far. In the real world, most of the time, we are dealing with data that resides on a remote server. Thanks to React, implementing this is actually quite simple. Notice that the actual data fetching is performed outside of the grid component - We are using the HTML5 fetch API.

}, { headerName: "Price", field: "price" }] - rowData: [{ - make: "Toyota", model: "Celica", price: 35000 - }, { - make: "Ford", model: "Mondeo", price: 32000 - }, { - make: "Porsche", model: "Boxter", price: 72000 - }] } } + componentDidMount() { + fetch('https://api.myjson.com/bins/15psn9') + .then(result => result.json()) + .then(rowData => this.setState({rowData})) + } + render() {

Here, we replaced the rowData assignment in the constructor with a data fetch from a remote service. The remote data is the same as the one we initially had, so you should not notice any actual changes to the grid.

Enable Selection

Being a programmer is a hectic job. Just when we thought that we are done with our assignment, the manager shows up with a fresh set of requirements! It turned out that we need to allow the user to select certain rows from the grid and to mark them as flagged in the system. We will leave the flag toggle state and persistence to the backend team. On our side, we should enable the selection and, afterwards, to obtain the selected records and pass them with an API call to a remote service endpoint.

Fortunately, the above task is quite simple with ag-Grid. As you may have already guessed, it is just a matter of adding and changing couple of properties:

this.state = { columnDefs: [{ - headerName: "Make", field: "make" - }, { + headerName: "Make", + field: "make", + checkboxSelection: true + }, { headerName: "Model", field: "model" },
<AgGridReact + rowSelection="multiple"

Great! Now the first column contains a checkbox that, when clicked, selects the row. The only thing we have to add is a button that gets the selected data and sends it to the server. To do this, we need the following change:


  <div style={{ height: '150px', width: '600px' }} className="ag-theme-balham">
  +    <button onClick={this.onButtonClick}>Get selected rows</button>
  +
   <AgGridReact
  +      onGridReady={ params => this.gridApi = params.api }

Afterwards, add the following event handler at the end of the component class:

onButtonClick = e => { const selectedNodes = this.gridApi.getSelectedNodes() const selectedData = selectedNodes.map( node => node.data ) const selectedDataStringPresentation = selectedData.map( node => node.make + ' ' + node.model).join(', ') alert(`Selected nodes: ${selectedDataStringPresentation}`) }

Well, we cheated a bit. Calling alert is not exactly a call to our backend. Hopefully you will forgive us this shortcut for the sake of keeping the article short and simple. Of course, you can substitute that bit with a real-world application logic after you are done with the tutorial.

What happened above? Several things:

  • onGridReady={ params => this.gridApi = params.api } obtained a reference to the ag-grid API instance;
  • We added a button with an event handler;
  • Inside the event handler, we accessed the grid api object reference to access the currently selected grid row nodes;
  • Afterwards, we extracted the row nodes' underlying data items and converted them to a string suitable to be presented to the user in an alert box.

Grouping (enterprise)

Grouping is a feature exclusive to ag-Grid Enterprise. You are free to trial ag-Grid Enterprise to see what you think. You only need to get in touch if you want to start using ag-Grid Enterprise in a project intended for production.

In addition to filtering and sorting, grouping is another effective way for the user to make sense out of large amounts of data. In our case, the data is not that much. Let's switch to a slightly larger data set:

componentDidMount() { - fetch('https://api.myjson.com/bins/15psn9') + fetch('https://api.myjson.com/bins/ly7d1') .then(result => result.json()) .then(rowData => this.setState({rowData})) } ag-Grid final

Now, let's enable grouping! Change the state assignment to this:

this.state = { columnDefs: [{ headerName: "Make", field: "make", rowGroup: true },{ headerName: "Price", field: "price" }], autoGroupColumnDef: { headerName: "Model", field: "model", cellRenderer:'agGroupCellRenderer', cellRendererParams: { checkbox: true } } }

Then, change the component definition to receive the autoGroupColumnDef property and the groupSelectsChildren:

columnDefs={this.state.columnDefs} + groupSelectsChildren={true} + autoGroupColumnDef={this.state.autoGroupColumnDef} rowData={this.state.rowData} >

There we go! The grid now groups the data by make, while listing the model field value when expanded. Notice that grouping works with checkboxes as well - the groupSelectsChildren property adds a group-level checkbox that selects/deselects all items in the group.

Don't worry if this step feels a bit overwhelming - the grouping feature is very powerful and supports complex interaction scenarios which you might not need initially. The grouping documentation section contains plenty of real-world runnable examples that can get you started for your particular case.

Customize the Theme Look

The last thing which we are going to do is to change the grid look and feel by modifying some of the theme's Sass variables.

By default, ag-Grid ships a set of pre-built theme stylesheets. If we want to tweak the colors and the fonts of theme, we should add a Sass preprocessor to our project, override the theme variable values, and refer the ag-grid Sass files instead of the pre-built stylesheets so that the variable overrides are applied.

Adding Sass Preprocessor to create-react-app is well documented - follow the steps outlined in the respective help section.

After you are done with the setup, assuming that you have renamed src/App.css to src/App.scss, you can replace its contents with this:

@import "../node_modules/@ag-grid-community/all-modules/src/styles/ag-grid.scss"; @import "../node_modules/@ag-grid-community/all-modules/src/styles/ag-theme-balham/sass/ag-theme-balham.scss"; // or, if using Enterprise features // @import "../node_modules/@ag-grid-enterprise/all-modules/src/styles/ag-grid.scss"; // @import "../node_modules/@ag-grid-enterprise/all-modules/src/styles/ag-theme-balham/sass/ag-theme-balham.scss";

To avoid importing the stylesheets twice, remove the imports from src/App.js:

import { AgGridReact } from '@ag-grid-community/react'; -import '@ag-grid-community/all-modules/dist/styles/ag-grid.css'; -import '@ag-grid-community/all-modules/dist/styles/ag-theme-balham.css'; // or, if using Enterprise features -import '@ag-grid-enterprise/all-modules/dist/styles/ag-grid.css'; -import '@ag-grid-enterprise/all-modules/dist/styles/ag-theme-balham.css';
+$odd-row-background-color: #CFD8DC;

If everything is configured correctly, the second row of the grid will get slightly darker. Congratulations! You now know now bend the grid look to your will - there are a few dozens more Sass variables that let you control the font family and size, border color, header background color and even the amount of spacing in the cells and columns. The full Sass variable list is available in the themes documentation section.

Summary

With this tutorial, we managed to accomplish a lot. Starting from the humble beginnings of a three row / column setup, we now have a grid that supports sorting, filtering, binding to remote data, selection and even grouping! While doing so, we learned how to configure the grid, how to access its API object, and how to change the styling of the component.