📝This blog post was inspired by a popular Stack Overflow question. Now updated for v28 of AG Grid.

AG Grid gives great flexibility in the ways you can render content in cells. A common scenario is to display a button in a column of cells to do some additional processing.

In this post, we'll show you how to render buttons within a column - you can see the final result in the screenshot below.


Vanilla JavaScript

We implement our cell renderer as a class with the required init and getGui methods. We create a DOM element in the init method, which is then returned in the getGui method. The optional destroy hook has also included to do some cleanup (removing the click listener from our component).

// btn-cell-renderer.js

class BtnCellRenderer() {
	
    init(params) {
      this.params = params;

      this.eGui = document.createElement('button');
      this.eGui.innerHTML = 'Click me!';

      this.btnClickedHandler = this.btnClickedHandler.bind(this);
      this.eGui.addEventListener('click', this.btnClickedHandler);
    }
    
    getGui() {
      return this.eGui;
    }
    
    btnClickedHandler(event) {
      this.params.clicked(this.params.value);
    }
    
    destroy() {
  		this.eGui.removeEventListener('click', this.btnClickedHandler);
	}
}

We register our BtnCellRenderer with the athlete column via the cellRenderer property. Note that we're passing the button click handler dynamically to our renderer via cellRendererParams - this makes for a more flexible and reusable renderer.

// main.js 

var gridOptions = {
  columnDefs: [
    { 
      field: 'athlete', 
      cellRenderer: BtnCellRenderer, 
      cellRendererParams: {
        clicked: function(field) {
          alert(`${field} was clicked`);
        }
      }
    }
};

Learn more about JavaScript Cell Renderers.


Angular

Here we create the button cell renderer as an Angular component that implements the ICellRendererAngularComp interface. Access to the params object can be found on the agInit hook.

// app/button-cell-renderer.component.ts

@Component({
  selector: 'btn-cell-renderer',
  template: `
    <button (click)="btnClickedHandler($event)">Click me!</button>
  `,
})
export class BtnCellRenderer implements ICellRendererAngularComp {
  private params: any;

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

  btnClickedHandler() {
    this.params.clicked(this.params.value);
  }
}

We register our BtnCellRenderer with the athlete column via the cellRenderer property. Note that we're passing the button click handler dynamically to our renderer via cellRendererParams - allowing for a more flexible and reusable renderer.

// app/app.component.ts

this.columnDefs = [
      {
        field: 'athlete',
        cellRenderer: BtnCellRenderer,
        cellRendererParams: {
          clicked: (field: any) => {
            alert(`${field} was clicked`);
          }
        },
      }
    ];

Learn more about Angular Cell Renderers


React

Here our button cell renderer is constructed as a React component. The only thing to take note of here is that cell params will be available on the component via props.

// BtnCellRenderer.jsx

class BtnCellRenderer extends Component {
  constructor(props) {
    super(props);
    this.btnClickedHandler = this.btnClickedHandler.bind(this);
  }
  btnClickedHandler() {
   this.props.clicked(this.props.value);
  }
  render() {
    return (
      <button onClick={this.btnClickedHandler}>Click Me!</button>
    )
  }
}

We register our BtnCellRenderer with the athlete column via the cellRenderer property.  The button click handler is passed to our renderer at run time via cellRendererParams - allowing for a more flexible and reusable renderer.

 // index.jsx
 
 columnDefs: [
        {
          field: 'athlete',
          cellRenderer: BtnCellRenderer,
          cellRendererParams: {
            clicked: function(field) {
              alert(`${field} was clicked`);
            },
          },
        }
      ];

Learn more about React Cell Renderers


Vue.js

We configuring the renderer in Vue.js as follows.

// btn-cell-renderer.js

export default Vue.extend({
  template: `
        <span>
            <button @click="btnClickedHandler()">Click me!</button>
        </span>
    `,
  methods: {
    btnClickedHandler() {
      this.params.clicked(this.params.value);
    }
  },
});

The renderer is registered with AG Grid via components and the button click handler is passed to our renderer at runtime via cellRendererParams - allowing for a more flexible and reusable renderer.

// main.js

components : {
	btnCellRenderer: BtnCellRenderer
}
 
this.columnDefs = [
      {
        field: 'athlete',
        cellRenderer: 'btnCellRenderer',
        cellRendererParams: {
          clicked: function(field) {
            alert(`${field} was clicked`);
          }
        },
    ]
    

Learn more about Vue.js Cell Renderers


What's next?

I hope you find this article useful when configuring buttons in the cells of AG Grid. Please check out our other blog posts and documentation for a great variety of scenarios you can implement with ag-Grid.

If you would like to try out ag-Grid check out our getting started guides (JS / React / Angular / Vue)

Happy coding!