Expand All

  Getting Started

  Interfacing

  Features

  Row Models

  Themes

  Components

  Examples

Misc

Github stars make projects look great. Please help, donate a star, it's free.
Get informed on releases and other ag-Grid news only - never spam.
Follow on Twitter

Cell Rendering

Cell Rendering - this is a very powerful feature in ag-Grid. With this, you can put whatever you want in the grid. The job of the grid is to lay out the cells. What goes into the cells, that's where you come in! You customise the rendering inside the cells by providing 'cellRenderers'.

You configure cellRenderers as part of the column definition and can be one of the following:

  • function: The cellRenderer is a function that gets called once for each cell. The function should return a string (which will be treated as html) or a DOM object. Use this if you have no cleanup or refresh requirements of the cell - it's a 'fire and forget' approach to the cell rendering.
  • component: The grid will call 'new' on the provided class and treat the object as a component, using lifecycle methods. Use this if you need to do cleanup when the cell is removed or have refresh requirements.
  • string: The cellRenderer is looked up from the provided cellRenderers. Use this if you want to use a built in renderer (eg 'group').

cellRenderer Function

The easiest (but not as flexible) way to provide your own cellRenderer is to provide a function. The function takes a set of parameters (with information on what to render) and you return back either a) a string of HTML or b) a DOM object.

Below are some simple examples of cellRenderer function:

// put the value in bold
colDef.cellRenderer = function(params) {
    return '<b>' + params.value.toUpperCase() + '</b>';
}

// put a tooltip on the value
colDef.cellRenderer = function(params) {
    return '<span title="the tooltip">'+params.value+'</span>';
}

// create a DOM object 
colDef.cellRenderer = function(params) {
    var eDiv = document.createElement('div');
    eDiv.innerHTML = '<span class="my-css-class"><button class="btn-simple">Push Me</button></span>';
    var eButton = eDiv.querySelectorAll('.btn-simple')[0];

    var eButton.addEventListener('click', function() {
        console.log('button was clicked!!');
    });

    return eDiv;
}

See further below for the set of parameters passed to the rendering function.

cellRenderer Component

The most flexible (but a little more tricky) way to provide a cellRenderer is to provide a component class. The component class that you provide can have callback methods on it for refresh and destroy.

A cellRenderer Component is an ag-Grid concept that is similar in how 'components' work in other frameworks. Other than sharing the same concept and name, ag-Grid Components have nothing to do with Angular components, React components, or any other components.

An ag-Grid cellRenderer Component does not need to extend any class or do anything except implement the methods shown in the interface.

The interface for the cellRenderer component is as follows:

interface ICellRendererComp {
    // Optional - Params for rendering. The same params that are passed to the cellRenderer function.
    init?(params: any): void;

    // Mandatory - Return the DOM element of your editor, this is what the grid puts into the DOM
    getGui(): HTMLElement;

    // Optional - Gets called once by grid after editing is finished - if your editor needs to do any cleanup,
    // do it here
    destroy?(): void;

    // Optional - Get the cell to refresh. If this method is not provided, then when refresh is needed, the grid
    // will remove the component from the DOM and create a new component in it's place with the new values.
    refresh?(params: any): void;
}

Below is a simple example of cellRenderer class:

// function to act as a class
function MyCellRenderer () {}

// gets called once before the renderer is used
MyCellRenderer.prototype.init = function(params) {
    // create the cell
    this.eGui = document.createElement('div');
    this.eGui.innerHTML = '<span class="my-css-class"><button class="btn-simple">Push Me</button><span class="my-value"></span></span>';

    // get references to the elements we want
    this.eButton = this.eGui.querySelectorAll('.btn-simple')[0];
    this.eValue = this.eGui.querySelectorAll('.my-value')[0];

    // set value into cell
    this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value;

    // add event listener to button
    this.eventListener = function() {
        console.log('button was clicked!!');
    };
    this.eButton.addEventListener('click', this.eventListener);
};

// gets called once when grid ready to insert the element
MyCellRenderer.prototype.getGui = function() {
    return this.eGui;
};

// gets called whenever the user gets the cell to refresh
MyCellRenderer.prototype.refresh = function(params) {
    // set value into cell again
    this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value;
};

// gets called when the cell is removed from the grid
MyCellRenderer.prototype.destroy = function() {
    // do cleanup, remove event listener from button
    this.eButton.removeEventListener('click', this.eventListener);
};

cellRenderer Component Refresh

The grid is constantly refreshing rows and cells into the browser, but not every refresh of the grid results in the refresh method of your cellRenderer getting called. The following details when your cellRenderer refresh method gets called and when not.

The following will result in cellRenderer refresh method getting called:

  • Calling rowNode.setDataValue(colKey, value) to set a value directly onto the rowNode
  • When editing a cell and editing is stopped, so that cell displays new value after editing.
  • Calling api.refreshCells(rowNodes, colIds) to inform grid data has changed (see Refresh).
  • Calling api.softRefreshView() to inform grid data has changed (see Refresh).
If any of the above occur, the refresh() method will be called if it is provided. If not, the component will be destroyed and replaced.

The following will not result in cellRenderer refresh method getting called:

  • Calling rowNode.setData(data) to set new data into a rowNode.
  • Scrolling the grid vertically (results in rows getting ripped in / out of the dom).
  • All other api refresh methods (refreshRows, refreshView etc).
All of the above will result in the component getting destrotyed and recreated.

cellRenderer Component Lifecycle

The lifecycle of the cellRenderer is as follows:

  • new is called on the class.
  • init() is called once.
  • getGui() is called once.
  • refresh() is called 0..n times (ie it may never be called, or called multiple times)
  • destroy() is called once.
In other words, new(), init(), getGui() and destroy() are always called exactly once. refresh() is optionally called multiple times.

If you are implementing refresh(), remember that getGui() is only called once, so be sure to update the existing GUI in your refresh, do not think that the grid is going to call getGui() again to get a new version of the GUI.

cellRenderer Params

The cellRenderer function and cellRenderer component take parameters as follows:

  • cellRenderer function: Passed to function.
  • cellRenderer component: Passed to init method.
The parameters are identical regardless of which cellRenderer type you use and contain the following:

Value Description
value The value to be rendered.
valueFormatted If a valueFormatter was provided, is the result of calling the formatter.
valueGetter A function, that when called, gives you the value, calling the relevant valueGetter / expression if necessary. This can be called at any time after rendering should the value change and you find the refresh functionality provided by the grid is not enough.
formatValue A function, that when called, formats the value. The valueFormatted attribute already gives you the formatted value, however you can call this if you need to format another value, maybe you need to format a different value (this is used by the provided 'animation' cellRenderers where they need to format the delta difference).
node The RowNode of the row being rendered.
data The row (from the rowData array, where value was taken) been rendered.
column The column been rendered (in ag-Grid, each colDef is wrapped by a Column).
colDef The colDef been rendered.
$scope If compiling to Angular, is the row's child scope, otherwise null.
rowIndex The index of the row, after sorting and filtering.
api A reference to the grid api.
columnApi A reference to the column api.
context The context as set on the gridOptions.
refreshCell A callback function, to tell the grid to refresh this cell and reapply all css styles and classes. Useful if you update the data for the cell and want to just render again from scratch.
eGridCell A reference to the DOM element representing the grid cell that your component will live inside. Useful if you want to add event listeners or classes at this level. This is the DOM element that gets browser focus when selecting cells.
eParentOfValue If using checkbox selection, your component will live inside eParentOfValue which sits beside a checkbox and both live inside eGridCell.

Complementing cellRenderer Params

On top of the parameters provided by the grid, you can also provide your own parameters. This is useful if you want to 'configure' your cellRenderer. For example, you might have a cellRenderer for formatting currency but you need to provide what currency for your cellRenderer to use.

Provide params to a cellRenderer using the colDef option cellRendererParams.

// define cellRenderer to be reused
var myCellRenderer = function(params) {
    return '<span style="color: '+params.color+'">' + params.value + '</span>';
}

// use with a color
colDef.cellRenderer = myCellRenderer;
colDef.cellRendererParams = {
    color: 'guinnessBlack'
}

// use with another color
colDef.cellRenderer = myCellRenderer;
colDef.cellRendererParams = {
    color: 'irishGreen'
}

Provided cellRenderers

Instead of providing a cellRenderer function or component, you can select from ones that come with the grid or install your own into the grid.

The cellRenderers provided by the grid are as follows:

  • group: For group rendering.
  • animateShowChange: Cell renderer that when data changes, it animates showing the difference by showing the delta for a period of time.
  • animateSlide: Cell renderer that when data changes, it animates showing the old value fading away to the left.

From the provided cellRenderers, it is intended the you use 'group' as is, however 'animateShowChange' and 'animateSlide' are given as examples on what is possible. How you show changes or otherwise want to refresh is going to be different for everyone. So take influence from what you see, but consider creating your own.

Usage of group cellRenderer is detailed in the section Grouping Rows and Aggregation.

Usage of animateShowChange and animateSlide is demonstrated in the section Viewport.

Example: Using cellRenderers

The example below shows five columns formatted, demonstrating each of the methods above.

  • 'Month' column uses cellStyle to format each cell in the column with the same style.
  • 'Max Temp' and 'Min Temp' columns uses the Function method to format each cell in the column with the same style.
  • 'Days of Air Frost' column uses the Component method to format each cell in the column with the same style
  • 'Days Sunshine' and 'Rainfall (10mm)' use simple functions to display icons.

Cell Renderers and Row Groups

If you are mixing cellRenderers and row grouping, then you need to understand that the value and / or data may be missing in the group row. The data and value will be missing if you are not doing any aggregations (hence no data at the group level) and the value will be missing if you are doing aggregations but not on the column the cellRenderer is on.

This is simply fixed by checking for the existence of the data before you use it like the following:

colDef.cellRenderer = function(params) {

    // check the data exists, to avoid error when grouping but not aggregating
    if (params.data) {
        // data exists, so we can access it
        return '<b>'+params.data.theBoldValue+'</b>';
    } else {
        // when we return null, the grid will display a blank cell
        return null;
    }
};

Angular Cell Rendering

This section explains how to utilise ag-Grid cellRenders using Angular 2+. You should read about how Cell Rendering works in ag-Grid first before trying to understand this section.

It is possible to provide a Angular cellRenderers for ag-Grid to use. All of the information above is relevant to Angular cellRenderers. This section explains how to apply this logic to your Angular component.

For examples on Angular cellRendering, see the ag-grid-angular-example on Github. Angular Renderers are used on all but the first Grid on this example page (the first grid uses plain JavaScript Renderers)

Specifying a Angular cellRenderer

If you are using the ag-grid-angular component to create the ag-Grid instance, then you will have the option of additionally specifying the cellRenderers as Angular components.

cellRenderers from Angular Components

// create your cellRenderer as a Angular component
@Component({
    selector: 'square-cell',
    template: `{{valueSquared()}}`
})
class SquareComponent implements AgRendererComponent {
    private params:any;

    agInit(params:any):void {
        this.params = params;
    }

    private valueSquared():number {
        return this.params.value * this.params.value;
    }
}
// then reference the Component in your colDef like this
colDef = {
    {
        headerName: "Square Component",
        field: "value",
        // instead of cellRenderer we use cellRendererFramework
        cellRendererFramework: SquareComponent

        // specify all the other fields as normal
        editable:true,
        colId: "square",
        width: 200
    }
}

Your Angular components need to implement AgRendererComponent. The ag Framework expects to find the agInit method on the created component, and uses it to supply the cell params.

By using colDef.cellRendererFramework (instead of colDef.cellRenderer) the grid will know it's a Angular component, based on the fact that you are using the Angular version of ag-Grid.

This same mechanism can be to use a Angular Component in the following locations:

  • colDef.cellRendererFramework
  • colDef.floatingCellRendererFramework
  • gridOptions.fullWidthCellRendererFramework
  • gridOptions.groupRowRendererFramework
  • gridOptions.groupRowInnerRendererFramework
In other words, wherever you specify a normal cellRenderer, you can now specify a Angular cellRenderer in the property of the same name excepting ending 'Framework'. As long as you are using the Angular ag-Grid component, the grid will know the framework to use is Angular.

Example: Rendering using Angular Components

Using Angular Components in the Cell Renderers

Angular Methods / Lifecycle

All of the methods in the ICellRenderer interface described above are applicable to the Angular Component with the following exceptions:

  • init() is not used. Instead implement the agInit method (on the AgRendererComponent interface).
  • destroy() is not used. Instead implement the AngularOnDestroy interface (ngOnDestroy) for any cleanup you need to do.
  • getGui() is not used. Instead do normal Angular magic in your Component via the Angular template.

Handling Refresh

To receive update (for example, after an edit) you should implement the optional refresh method on the AgRendererComponent interface.

Example: Rendering using more complex Angular Components

Using more complex Angular Components in the Cell Renderers

The full ag-grid-angular-example repo shows many more examples for rendering, including grouped rows, full width renderers and so on, as well as examples on using Angular Components with both CellEditors and Filters

Aurelia Cell Rendering

This section explains how to utilise ag-Grid cellRenders using Aurelia. You should read about how Cell Rendering works in ag-Grid first before trying to understand this section.

It is possible to provide Aurelia Component cellRenderers for ag-Grid to use, with support for two way binding. All of the information above is relevant to Aurelia cellRenderers. This section explains how to apply this logic to your Aurelia component.

For examples on Aurelia cellRendering, see the ag-grid-aurelia-example on Github.

Specifying a Aurelia cellRenderer

If you are using the ag-grid-aurelia component to create the ag-Grid instance, then you will have the option of additionally specifying the cellRenderers as aurelia components. You have two options that are described below:

  1. Templates
  2. cellRenderer Functions or cellRenderer Components
We only mention Templates here - using functions or regular components is discussed above in earlier sections.

cellRenderers from Templates

// create your cellRenderer as an Aurelia template
<ag-grid-aurelia #agGrid style="width: 100%; height: 100%;" class="ag-fresh"
                 grid-options.bind="gridOptions">
  <ag-grid-column header-name="Mood" field="mood" width.bind="150" editable.bind="true">
    <ag-cell-template>
      <img width="20px" if.bind="params.value === 'Happy'" src="images/smiley.png"/>
      <img width="20px" if.bind="params.value !== 'Happy'" src="images/smiley-sad.png"/>
    </ag-cell-template>
  </ag-grid-column>
</ag-grid-aurelia>

The advantage of using Templates for your renderers is that you have the ability to use Aurelia's dynamic data binding facilties.

Example: Rendering using Templates

Using Templates in the Cell Renderers - here we're using a Template (ag-cell-template) to render the Mood column depending on the underlying value of the "mood" field.

Example: Rendering using regular cellRenderer Components

A Rich Grid leveraging regular Cell Renderer Components


The full ag-grid-aurelia-example repo shows many more examples for rendering, including grouped rows, full width renderers and filters.

React Cell Rendering

This section explains how to utilise ag-Grid cellRenders using React. You should read about how Cell Rendering works in ag-Grid first before trying to understand this section.

It is possible to provide a React cellRenderer for ag-Grid to use. All of the information above is relevant to React cellRenderers. This section explains how to apply this logic to your React component.

For examples on React cellRendering, see the ag-grid-react-example on Github. In the example, both 'Skills' and 'Proficiency' columns use React cellRenderers. The Country column uses a standard ag-Grid cellRenderer, to demonstrate both working side by side.

Specifying a React cellRenderer

If you are using the ag-grid-react component to create the ag-Grid instance, then you will have the option of additionally specifying the cellRenderers as React components.

// create your cellRenderer as a React component
class NameCellRenderer extends React.Component {
    render() {
    // put in render logic
        return <span>{this.props.value}</span>;
    }
}

// then reference the Component in your colDef like this
colDef = {

    // instead of cellRenderer we use cellRendererFramework
    cellRendererFramework: NameCellRenderer

    // specify all the other fields as normal
    headerName: 'Name',
    field: 'firstName',
    ...
}

By using colDef.cellRendererFramework (instead of colDef.cellRenderer) the grid will know it's a React component, based on the fact that you are using the React version of ag-Grid.

This same mechanism can be to use a React Component in the following locations:

  • colDef.cellRendererFramework
  • colDef.floatingCellRendererFramework
  • gridOptions.fullWidthCellRendererFramework
  • gridOptions.groupRowRendererFramework
  • gridOptions.groupRowInnerRendererFramework
In other words, wherever you specify a normal cellRenderer, you can now specify a React cellRenderer in the property of the same name excepting ending 'Framework'. As long as you are using the React ag-Grid component, the grid will know the framework to use is React.

React Props

The React component will get the 'cellRenderer Params' as described above as it's React Props. Therefore you can access all the parameters as React Props.

// React cellRenderer Component
class NameCellRenderer extends React.Component {

    // did you know that React passes props to your component constructor??
    constructor(props) {
        super(props);
        // from here you can access any of the props!
        console.log('The value is ' + props.value);
        // we can even call grid API functions, if that was useful
        props.api.selectAll();
    }

    render() {
        // or access props using 'this'
        return <span>{this.props.value}</span>;
    }
}

React Methods / Lifecycle

All of the methods in the ICellRenderer interface described above are applicable to the React Component with the following exceptions:

  • init() is not used. Instead use the React props passed to your Component.
  • destroy() is not used. Instead use the React componentWillUnmount() method for any cleanup you need to do.
  • getGui() is not used. Instead do normal React magic in your render() method..

Handling Refresh

You have the option of handling refresh or not by either providing a refresh() method on your React component or not. If not present, then the grid will destroy your component and create a new one if it tries to refresh the cell. If you do implement it, then it's up to your React components refresh() method to update the state of your component.

VueJS Cell Rendering

This section explains how to utilise ag-Grid cellRenders using VueJS. You should read about how Cell Rendering works in ag-Grid first before trying to understand this section.

It is possible to provide a VueJS cellRenderers for ag-Grid to use. All of the information above is relevant to VueJS cellRenderers. This section explains how to apply this logic to your VueJS component.

For examples on VueJS cellRendering, see the ag-grid-vue-example on Github. VueJS Renderers are used on all but the first Grid on this example page (the first grid uses plain JavaScript Renderers)

Specifying a VueJS cellRenderer

If you are using the ag-grid-vue component to create the ag-Grid instance, then you will have the option of additionally specifying the cellRenderers as VueJS components.

A VueJS component can be defined in a few different ways (please see Defining VueJS Components for all the options), but in this example we're going to define our renderer as a Single File Component:

// create your cellRenderer as a VueJS component
<template>
    <span class="currency">{{ params.value | currency('EUR') }}</span>
</template>

<script>
    import Vue from "vue";

    export default Vue.extend({
        filters: {
            currency(value, symbol) {
                let result = value;
                if (!isNaN(value)) {
                    result = value.toFixed(2);
                }
                return symbol ? symbol + result : result;
            }
        }
    });
</script>

<style scoped>
    .currency {
        color: blue;
    }
</style>

// then reference the Component in your colDef like this
{
    // instead of cellRenderer we use cellRendererFramework
    cellRendererFramework: CurrencyComponent,

    // specify all the other fields as normal
    headerName: "Currency (Filter)",
    field: "currency",
    colId: "params",
    width: 150
}

The Grid cell's value will be made available implicitly in a data value names params. This value will be available to you from the created VueJS lifecycle hook.

You can think of this as you having defined the following:

export default {
    data () {
        return {
            params: null
        }
    },
    ...

but you do not need to do this - this is made available to you behind the scenes, and contains the cells value.

By using colDef.cellRendererFramework (instead of colDef.cellRenderer) the grid will know it's a VueJS component, based on the fact that you are using the VueJS version of ag-Grid.

This same mechanism can be to use a VueJS Component in the following locations:

  • colDef.cellRendererFramework
  • colDef.floatingCellRendererFramework
  • gridOptions.fullWidthCellRendererFramework
  • gridOptions.groupRowRendererFramework
  • gridOptions.groupRowInnerRendererFramework
In other words, wherever you specify a normal cellRenderer, you can now specify a VueJS cellRenderer in the property of the same name excepting ending 'Framework'. As long as you are using the VueJS ag-Grid component, the grid will know the framework to use is VueJS.

Example: Rendering using VueJS Components

Using VueJS Components in the Cell Renderers

VueJS Methods / Lifecycle

All of the methods in the ICellRenderer interface described above are applicable to the VueJS Component with the following exceptions:

  • init() is not used. The cells value is made available implicitly via a data field called params.
  • getGui() is not used. Instead do normal VueJS magic in your Component via the VueJS template.

Handling Refresh

To receive update (for example, after an edit) you should implement the optional refresh method on the AgRendererComponent interface.

Example: Rendering using more complex VueJS Components

Using more complex VueJS Components in the Cell Renderers

The full ag-grid-vue-example repo shows many more examples for rendering, including grouped rows, full width renderers and so on, as well as examples on using VueJS Components with both CellEditors and Filters