Framework:Javascript Data GridAngular Data GridReact Data GridVue Data Grid

Vue Data Grid: Cell Renderer

By default the grid will create the cell values using simple text. If you want more complex HTML inside the cells you can achieve this using Cell Renderers.

Simple Cell Renderer

Below is a simple example of cell renderer component:

export default {
   template: `<span>{{ displayValue }}</span>`,
   data: function () {
       return {
           displayValue: ''
       };
   },
   beforeMount() {
       this.displayValue = new Array(this.params.value).fill('#').join('');
   },
};

And below is the example using Vue 3's Composition API::

export default {
   template: `<span>{{ displayValue }}</span>`,
   setup(props) {
       const displayValue = new Array(props.params.value).fill('#').join('');
       return {
           displayValue
       }
   }
};

Simple Cell Renderer Example

The example below shows a simple Cell Renderer in action. It uses a Cell Renderer to render a hash (#) symbol for each medal won (instead of the medal count), and the MedalCellRenderer defined in the code snippet above for the Total column:

Cell Renderer Component

When a Vue component is instantiated the grid will make the grid APIs, a number of utility methods as well as the cell and row values available to you via a params object.

With Vue 2 and Vue 3 you can access the params object via this.params in the usual methods (lifecycle hooks, methods etc), and with Vue 3's setup via props.params.

The interface for both the initial params value, as well as the argument passed in subsequent refresh calls (see below for details on refresh) are as follows:

ICellRendererParams

Properties available on the ICellRendererParams interface.

value
any
Value to be rendered.
valueFormatted
any
Formatted value to be rendered.
fullWidth
boolean
True if this is a full width row.
pinned
string | null
Pinned state of the cell.
data
any
The row's data.
node
The row node.
rowIndex
number
The current index of the row (this changes after filter and sort).
colDef
The cell's column definition.
column
The cell's column.
eGridCell
The grid's cell, a DOM div element.
eParentOfValue
The parent DOM item for the cell renderer, same as eGridCell unless using checkbox selection.
getValue
Function
Convenience function to get most recent up to date value.
getValue = () => any;
setValue
Function
Convenience function to set the value.
setValue = (value: any) => void;
formatValue
Function
Convenience function to format a value using the column's formatter.
formatValue = (value: any) => any;
refreshCell
Function
Convenience function to refresh the cell.
refreshCell = () => void;
registerRowDragger
Function
registerRowDragger:
rowDraggerElement The HTMLElement to be used as Row Dragger
dragStartPixels The amount of pixels required to start the drag (Default: 4)
value The value to be displayed while dragging. Note: Only relevant with Full Width Rows.
suppressVisibilityChange Set to true to prevent the Grid from hiding the Row Dragger when it is disabled.
registerRowDragger = (
    rowDraggerElement: HTMLElement,
    dragStartPixels?: number,
    value?: string,
    suppressVisibilityChange?: boolean
) => void;
api
The grid api.
columnApi
The column api.
context
any
Application context as set on gridOptions.context.

Vue 3 - Class Based Components & Typed Components

If you're using a Class Based Component (i.e. you're using vue-property-decorator/vue-class-component), or if you're using a vanilla Vue 3 component with lang='ts' then you'll need to specify the params object as a prop.

For example:

<script lang="ts">
   import {defineComponent} from "vue";

   export default defineComponent({
       name: "MyComponent",
       props: ['params'],  // required for TypeScript ...

Registering Cell Renderers with Columns

See the section registering custom components for details on registering and using custom Cell Renderers.

Component Refresh

Component Refresh needs a bit more explanation. Here we go through some of the finer details.

Events Causing Refresh

The grid can refresh the data in the browser, but not every refresh / redraw of the grid results in the refresh method of your cell renderer getting called. The following items are those that do cause refresh to be called:

  • Calling rowNode.setDataValue(colKey, value) to set a value directly onto the rowNode. This is the preferred API way to change one value from outside of the grid.
  • When editing a cell and editing is stopped, so that cell displays new value after editing.
  • Calling api.refreshCells() to inform grid data has changed (see Refresh).

If any of the above occur and the grid confirms the data has changed via Change Detection, then the refresh() method will be called.

The following will not result in the cell renderer's refresh method being called:

  • Calling rowNode.setData(data) to set new data into a rowNode. When you set the data for the whole row, the whole row in the DOM is recreated again from scratch.
  • Scrolling the grid vertically causes columns (and their containing cells) to be removed and inserted due to column virtualisation.

All of the above will result in the component being destroyed and recreated.

Grid vs Component Refresh

The refresh method returns back a boolean value. If you do not want to handle the refresh in the cell renderer, just return back false from an otherwise empty method. This will indicate to the grid that you did not refresh and the grid will instead destroy the component and create another instance of your component from scratch instead.

Change Detection

As mentioned in the section on Change Detection, the refresh of the Cell will not take place if the value getting rendered has not changed.

Cell Renderer Component Lifecycle

The lifecycle of the cell renderer is as follows:

  • The component will be instantiated.
  • The component's GUI will be inserted into the grid 0 or 1 times (the component could get destroyed first, i.e. when scrolling quickly).
  • refresh() is called 0...n times (i.e. it may never be called, or called multiple times).
  • The component is destroyed once.

In other words, component instantiation and destruction are always called exactly once. The component's GUI will typically get rendered once unless the component is destroyed first. refresh() is optionally called multiple times.

Cell Rendering Flow

The diagram below (which is taken from the section Cell Content) summarises the steps the grid takes while working out what to render and how to render.

In short, a value is prepared. The value comes using either the colDef.field or the colDef.valueGetter. The value is also optionally passed through a colDef.valueFormatter if it exists. Then the value is finally placed into the DOM, either directly, or by using the chosen colDef.cellRenderer.

Value Getter Flow

Complementing Cell Renderer 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 Cell Renderer. For example, you might have a Cell Renderer for formatting currency but you need to provide what currency for your cell renderer to use.

Provide params to a cell renderer using the colDef option cellRendererParams.

<template>
    <ag-grid-vue :columnDefs="columnDefs" ...other properties>
    </ag-grid-vue>
</template>

<script>
//...other imports
import {AgGridVue} from "@ag-grid-community/vue";

// define cellRenderer to be reused
const ColourComponent = {
  template: '<span :style="{color: params.color}">{{params.value}}</span>'
};

export default {
 components: {
     AgGridVue,
     ColourComponent
 },
 data() {
     return {
         columnDefs: [
             {
                 headerName: "Colour 1",
                 field: "value",
                 cellRenderer: 'ColourComponent',
                 cellRendererParams: {
                      color: 'guinnessBlack'
                 }
             },
             {
                 headerName: "Colour 2",
                 field: "value",
                 cellRenderer: 'ColourComponent',     
                 cellRendererParams: {
                      color: 'irishGreen'
                 }
             }
         ]
     }
 }
 //...other properties & methods
}
</script>

Data in Cell Renderers

Sometimes the data property in the parameters given to a cell renderer might not be populated. This can happen for example when using row grouping (where the row node has aggData and groupData instead of data), or when rows are being loaded in the Infinite Row Model and do not yet have data. It is best to check that data does exist before accessing it in your cell renderer, for example:

// define cellRenderer to be reused
const ColourComponent = {
  template: '<span>{{params.data ? params.data.theBoldValue : null}}</span>'
};

Cell Renderer Function

Instead of using a Vue component, it's possible to use a simple function for a cell renderer.

This is probably most useful if you have a simple String value to render and want to avoid the overhead of an actual Vue component.

In the example below we're outputting a simple string value that depends on the cell value:

<template>
    <ag-grid-vue :columnDefs="columnDefs" ...other properties>
    </ag-grid-vue>
</template>

<script>
//...other imports
import {AgGridVue} from "@ag-grid-community/vue";

export default {
 components: {
     AgGridVue
 },
 data() {
     return {
         columnDefs: [
             {
                 headerName: "Value",
                 field: "value",
                 cellRenderer: params => params.value > 1000 ? "LARGE VALUE" : "SMALL VALUE"
             }
         ]
     }
 }
 //...other properties & methods
}
</script>

It is also possible to write a JavaScript-based cell renderer function - refer to the docs here for more information

Complex Cell Renderer Example

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.

Accessing Cell Renderer Instances

After the grid has created an instance of a cell renderer for a cell it is possible to access that instance. This is useful if you want to call a method that you provide on the cell renderer that has nothing to do with the operation of the grid. Accessing cell renderers is done using the grid API getCellRendererInstances(params).

getCellRendererInstances
Function
Returns the list of active cell renderer instances.
getCellRendererInstances = (
    params: GetCellRendererInstancesParams = {}
) => ICellRenderer[];

interface GetCellRendererInstancesParams {
  // Optional list of row nodes to restrict operation to 
  rowNodes?: RowNode[];
  // Optional list of columns to restrict operation to 
  columns?: (string | Column)[];
}

interface ICellRenderer {
  // Get the cell to refresh. Return true if successful. Return false if not (or you don't have refresh logic),
  // then the grid will refresh the cell for you. 
  refresh(params: ICellRendererParams): boolean;
}

An example of getting the cell renderer for exactly one cell is as follows:

// example - get cell renderer for first row and column 'gold'
const firstRowNode = gridOptions.api.getDisplayedRowAtIndex(0);
const params = { columns: ['gold'], rowNodes: [firstRowNode] };
const instances = gridOptions.api.getCellRendererInstances(params);

if (instances.length > 0) {
    // got it, user must be scrolled so that it exists
    const instance = instances[0];
}

Note that this method will only return instances of the cell renderer that exists. Due to row and column virtualisation, renderers will only exist for cells that the user can actually see due to horizontal and vertical scrolling.

The example below demonstrates custom methods on cell renderers called by the application. The following can be noted:

  • The medal columns are all using the user defined MedalCellRenderer. The cell renderer has an arbitrary method medalUserFunction() which prints some data to the console.
  • The Gold method executes a method on all instances of the cell renderer in the gold column.
  • The First Row Gold method executes a method on the gold cell of the first row only. Note that the getCellRendererInstances() method will return nothing if the grid is scrolled far past the first row showing row virtualisation in action.
  • The All Cells method executes a method on all instances of all cell renderers.

Example: Rendering using more complex Components

This example illustrates a few different ideas:

  • Custom Cell Renderers
  • Parent/Child Communication using context
  • Storing the Grid API via the "Grid Ready" event, and using it later