Using AG Grid in SPFx - Netwoven
Blog

Using AG Grid in SPFx

By Debopoma Chaudhury  |  Published on July 6, 2021

Using AG Grid in SPFx

Background:

Having worked on quite a range in SPFx, I’ve some handy tips for dashboards, reports, task list etc. in my other blogs (jQuery Data Table with Both Row and Column Selections, Kendo Grids vs UI Fabric Grids in SPFx). While having extensively worked with UI Fabric grids, Kendo grids, jQuery grids, I still faced a lot of issues. In some, customization was not feasible, in some not all features where available and in some performance was extremely slow. That is where we discovered that AG grid is the most apt for these scenarios where there is both customization and bulk of data or one needs real time data update (like mailboxes, reporting tools).

Sample Application

The below sample has three representations of AG Grid in three tabs. I have shown here the flat grid as I have provided the code snippets for the same. The other tabs represent customized grids and advanced grids with custom columns, grouping and other advanced features.

Using AG Grid in SPFx

Steps to implement AG Grid in SPFx:

Create SPFx application

First, we need to create a basic SPFx application from the command prompt using the command “yo @microsoft/sharepoint” and follow the necessary steps as mentioned in this link https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part

Npm install the necessary package files

"@ag-grid-community/all-modules": "^24.1.0",
    "@ag-grid-community/client-side-row-model": "^24.1.0",
    "@ag-grid-enterprise/all-modules": "^24.1.0",
    "ag-grid-community": "^24.1.0",
    "ag-grid-enterprise": "^24.1.0",
    "ag-grid-react": "^24.1.1",

Connect with libraries

Import the necessary libraries for creating grid as shown below:

import { AgGridReact as AgGridReactAdvanced, AgGridColumn as AgGridColumnAdvanced } from 'ag-grid-react';

Create a flat grid in render function

<AgGridReactAdvanced
                    rowSelection="multiple"
                    onGridReady={this.onGridReady}
                    onSelectionChanged={this.onSelectionChanged}
                    defaultColDef={{
                        flex: 1,
                        minWidth: 30,
                        resizable: true,
                        headerCheckboxSelection: this.isFirstColumn,
                        headerCheckboxSelectionFilteredOnly: true,
                        checkboxSelection: this.isFirstColumn,
                    }}
                    onCellFocused={this.cellFocus}
                    onRowSelected={this.rowSelected}
                    suppressDragLeaveHidesColumns={true}
                    suppressMakeColumnVisibleAfterUnGroup={true}
                    components={{
                        loadingRenderer: function (params) {
                            if (params.value !== undefined) {
                                return params.value;
                            } else {
                                return '<img src="https://raw.githubusercontent.com/ag-grid/ag-grid/master/grid-packages/ag-grid-docs/src/images/loading.gif">';
                            }
                        },
                    }}
                    rowBuffer={0}
                    onBodyScroll={(e) => this.scrollHandler(e, this)}
                    rowData={this.props.gridData}>

                    {this.props.columns.map((column, index) => {
                        return (

                            <AgGridColumnAdvanced
                                key={index}
                                hide={column.hide}
                                field={column.field}
                                sortable={column.sortable}
                                filter={column.filter}
                                width={column.width}
                                headerName={column.headerName}
                                rowGroup={false}
                                enableRowGroup={false}
                                lockPosition={column.lockPosition ? column.lockPosition : false}
                                floatingFilter={true}
                                cellRenderer={column.cellRenderer ? column.cellRenderer : null}
                                showRowGroup={false}
                                cellRendererParams={column.cellRendererParams ? column.cellRendererParams : null}
                                maxWidth={column.maxWidth ? column.maxWidth : null}
                                minWidth={column.minWidth ? column.minWidth : null}
                            />

                        );
                    })}
                </AgGridReactAdvanced>

The above code snippet is of a flat grid which has large data and data is loaded on reaching scroll end of grid page. The grid needs various related properties and methods which need to be provided to be fully functional. The columns and grid data are passed from the .tsx file properties based on requirement.

Grid methods

The below methods are provided to the grid for implementation of all necessary features

OnGridReady

In this function the grid apis are initialized.

 onGridReady = (params) => {
        
        this.gridApi = params.api;
        this.gridColumnApi = params.columnApi;
    };
OnSelectionChanged

In this function the current selected row information is captured for further use (say to update/view detailed data).

onSelectionChanged = (ev) => {
        
        var selectedRows = this.gridApi.getSelectedRows();
        this.props.checkBoxSelection(selectedRows);

    }
CellFocus

This function is used to capture the selected column information.

 cellFocus = (e) => {
        

        let col = e.column.getUserProvidedColDef();
        this.setState({
            selectedColumn: col.field
        })

    }
isFirstColumn

This function is used to return the first column of the grid. This will be required if you need to display checkboxes in the first column.

 isFirstColumn = (params) => {
       
        var displayedColumns = params.columnApi.getAllDisplayedColumns();
        var thisIsFirstColumn = displayedColumns[0] === params.column;
        return thisIsFirstColumn;
    }
rowSelected

This function is used to capture all data for further use when you select multiple rows as shown in this snippet.

 rowSelected = (event) => {
        
        if (event.node.selected == true && this.state.selectedColumn != "selected" && event.api.getDisplayedRowCount() != event.api.getSelectedRows().length) {
            this.setState(
                {
                    
                    selectedItem: [event.data],
                });
        }
        if (event.api.getDisplayedRowCount() == event.api.getSelectedRows().length) {
            this.props.checkBoxSelectionMultiple(event.node.selected, event.api.getSelectedRows());
        }

    }
scrollHandler

This function is used to load the next set of data on reaching grid page scroll end.

public scrollHandler(event, target) {
        
        let bufferHeight = 600; 
        if (
            event.top > bufferHeight
        ) {
            if (this.state.isLoaded) {

                this.setState({ isLoaded: false }, () => {
                    this.props.loadMore();
                });
            }
        }
    }

Constraints

There are different versions of AG Grid. The basic features are available for free use in AG Grid Community version; however, the advanced features are available in AG Grid Enterprise which is a paid version.

The features with are required by most enterprise applications is paid and hence one needs to buy the paid version of AG Grid.

Benefits over other grids

Despite its constraints, the benefits cannot be ignored. Below are some features that I found extremely outstanding, apart from a range of others.

  • Handles large data with very efficient performance.
  • Provides a fully featured grid with all possible features that are required in enterprise solutions.
  • Coding is short and crisp with functions exposed for all sorts of custom features.

Conclusion

So, what have we really got here? For most cases, we might consider going for UI Fabric Grids for simple dashboards and task lists as it is inbuilt with SPFx. In other cases when one needs an advanced grid with detailed features it is best to choose AG Grid if price is not a limitation. A detailed documentation of AG Grid is available here https://www.ag-grid.com/documentation-main/documentation.php

2 comments

Leave a comment

Your email address will not be published. Required fields are marked *

Unravel The Complex
Stay Connected

Subscribe and receive the latest insights

Netwoven Inc. - Microsoft Solutions Partner

Get involved by tagging Netwoven experiences using our official hashtag #UnravelTheComplex