Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have own custom Context Menu in ag-Grid-community

Tags:

ag-grid

Can't find the exact answer. If i decide to opt-in for vanilla JavaScript (non-Angular & Co) ag-Grid-community edition, can i have easy to add my own custom context menu an other custom extensions? As i seen their docs, context menu is only enterprise level feature. I seen some treads that there is some caveats, but i personally did not dig deeper. In general, how easy is to implement self-built features in ag-Grid-community. Or it is better to write own grid?

like image 759
Dzintars Avatar asked Oct 19 '25 21:10

Dzintars


1 Answers

We have a custom context menu component in our Angular project with ag-grid community, so it's definitely possible.

How it works:

We define all grid columns in templates. If you want a context menu, you put an empty column into the column set and put a special directive on it. The directive accepts a context menu template, which is passed into a custom cellRendererFramework (a menu trigger button, basically). The directive also configures the column to ensure consistent look across grid instances.

This might be not what you've been looking for if you require for menu to open with right mouse click anywhere in a row, but I suppose it shouldn't be that hard to trigger the menu from a different event (check out ag-grid events, there might something suitable).

The snippets below should be straightforward to adapt for your framework of choice. Given you opted into vanilla JS, you'll have to use regular functions to do the same, something like this:

const grid = withContextMenu(new Grid(element, gridOptions), menuOptions).

Here's an example of how we use it:

<ag-grid-angular>
  <ag-grid-column headerName='ID' field='id'></ag-grid-column>
  <ag-grid-column [contextMenu]='menu'>
    <mat-menu #menu='matMenu'>
      <ng-template matMenuContent let-item='data'>
        <button mat-menu-item (click)='restoreSnapshot(item.id)'>Restore From Snapshot</button>
        <a mat-menu-item [routerLink]='[item.id, "remove"]'>Remove</a>
      </ng-template>
    </mat-menu>
  </ag-grid-column>
</ag-grid-angular>

The directive that applies the menu:

const WIDTH = 42;
export const CONTEXT_MENU_COLID = 'context-menu';

@Directive({
  selector: '[agGridContextMenu]'
})
export class AgGridContextMenuDirective implements AfterViewInit {
  constructor(private gridComponent: AgGridAngular) {}

  @Input()
  agGridContextMenu!: ElementRef<MatMenu>;

  ngAfterViewInit() {
    if (!this.agGridContextMenu) return;
    setTimeout(() => {
      this.gridComponent.api.setColumnDefs([
        ...this.gridComponent.columnDefs,
        {
          colId: CONTEXT_MENU_COLID,
          cellRendererFramework: CellRendererContextMenuComponent,
          width: WIDTH,
          maxWidth: WIDTH,
          minWidth: WIDTH,
          cellStyle: {padding: 0},
          pinned: 'right',
          resizable: false,
          cellRendererParams: {
            suppressHide: true,
            contextMenu: {
              menu: this.agGridContextMenu
            }
          }
        }
      ]);
    });
  }
}

The cell renderer component:

@Component({
  selector: 'cell-renderer-context-menu',
  template: `
    <ng-container *ngIf='params.data && params.colDef.cellRendererParams.contextMenu.menu'>
      <button
        type='button'
        mat-icon-button
        [matMenuTriggerFor]='params.colDef.cellRendererParams.contextMenu.menu'
        [matMenuTriggerData]='{data: params.data}'
      >
        <mat-icon svgIcon='fas:ellipsis-v'></mat-icon>
      </button>
    </ng-container>
  `,
  styleUrls: ['./cell-renderer-context-menu.component.scss']
})
export class CellRendererContextMenuComponent implements ICellRendererAngularComp {
  params!: ICellRendererParams;
  agInit(params: ICellRendererParams) {
    this.params = params;
  }
  refresh() {
    return false;
  }
}

A screenshot:

enter image description here

like image 165
Klaster_1 Avatar answered Oct 24 '25 06:10

Klaster_1



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!