AG-Grid: show certain "action" buttons in grid depending on condition

marc_s picture marc_s · Oct 11, 2018 · Viewed 8.1k times · Source

I'm using the community edition of "AG Grid" in my Angular 6 application.

My challenge right now is this: I have a fairly simple data structure, a list of which gets bound to the grid for display. Based on its values, I'd like to add an "Actions" column to the grid, to give the user access to certain actions, e.g. delete an entry, "promote" it etc.

For individual data-bound column, I get the corresponding data value of each row as it's being bound, and I can e.g. format the display using a cell renderer. I was hoping I'd be able to do soemthing similar with my "Actions" column (which isn't bound to a specific data element of the class) - but it seems my "action cell renderer" doesn't get anything to base its decisions on.

I have a data structure something like this:

export interface Indicator {
    Id: string;
    Name: string;
    IsGlobal: boolean;
}

An array of these Indicators is being bound to the AG-grid in the OnInit function of my Angular component.

I define my column of the AG-grid to be:

columnDefs = [
    { headerName: 'Name', field: 'Name', width: 200, editable: true },
    { headerName: 'Global', field: 'IsGlobal', editable: false, width: 100,
      cellRenderer: (data) => { 
        // here, "data" refers to the "IsGlobal" value of the row being displayed
        if (data.value === true) {
          return 'Ja';
        } else {
          return 'Nein';
        }
      },
    },
    { headerName: 'Actions', width: 125,
        cellRenderer: (data) => {
            // here, I was hoping the "data" would refer to the entire
            // row / object being bound, so that I could check for 
            // certain conditions to be true (or false)
            if (data.IsGlobal.value === true) 
            {
                return '<span class="far fa-trash-alt mr-2" title="Delete entry"></span>' +
                       '<span class="fab fa-nintendo-switch" title="Promote entry"></span>';
            }      
            else
            {
                return '<span class="far fa-trash-alt mr-2" title="Delete"></span>';
            }
        }
    }
  ];

I'd like to be able to define in my column definitions that my action column shows a "promote entry" button only IF the data of the row currently in question has IsGlobal = false. I was hoping the data being passed into the cell renderer would be the whole row data object (of type Indicator) - but that doesn't seem to be the case.

How can I decide which icons to show, in the "Actions" column, in my column definitions?

Answer

un.spike picture un.spike · Oct 11, 2018

on cellRenderer - you will get params value which represents an object :

interface ICellRendererParams {
    value: any, // value to be rendered
    valueFormatted: any, // value to be rendered formatted
    getValue: ()=> any, // convenience function to get most recent up to date value
    setValue: (value: any) => void, // convenience to set the value
    formatValue: (value: any) => any, // convenience to format a value using the columns formatter
    data: any, // the rows data
    node: RowNode, // row rows row node
    colDef: ColDef, // the cells column definition
    column: Column, // the cells column
    rowIndex: number, // the current index of the row (this changes after filter and sort)
    api: GridApi, // the grid API
    eGridCell: HTMLElement, // the grid's cell, a DOM div element
    eParentOfValue: HTMLElement, // the parent DOM item for the cell renderer, same as eGridCell unless using checkbox selection
    columnApi: ColumnApi, // grid column API
    context: any, // the grid's context
    refreshCell: ()=>void // convenience function to refresh the cell
}

So to get access to row-data you need to use params.data or params.node.data

cellRenderer: (params) => {
    if (params.data.IsGlobal.value === true) 
    {
        ...
    }      
    else
    {
        ...
    }
}

But remember, when you will use inline cellRenderer - you can implement just HTML template (no logic), for logic handling you need to create custom cellRenderer which will contain needed functions and so on.

you wouldn't be able to execute component functions through cellRenderer inline implementation