Search code examples
javascriptangularag-gridag-grid-angular

AG-Grid (Enterprise) Column Menu Listener


Is there a way to set a listener to column-menu, so that an event is fired when I open and close the menu?

Feature description: https://www.ag-grid.com/javascript-grid-column-menu/

I already searched in the official documentation, but didn't find an answer.

Background is: I want to store the table state with displayed cols, sorting, position of cols, filter etc. in a database. Of course I could use the listeners like onFilterChanged, onDisplayedColumnsChanged or onSortChanged. Problem is, that it will be fired every time when something changes and so there are produced a lot of unwanted api-calls.

Thats why I want to perform one call when the column-menu is closed.


Update

As Viqas said in his Answer, there is no official way to do it. I tried to avoid the solution with postProcessPopup and tried to find a cleaner solution for my problem - to store the table state.

For a workaround with a callback when ColumnMenu is closed Viqas Answer is more appropriate.

Notice that this is no workaround for the callback itself - it is just a (possible) solution to store the table state and perform ONE API Call

I used the ngOnDestory() function of Angular.

ngOnDestory(): void {
  const tableState = {
    columnState: this.gridOptions.columnApi.getColumnState(),
    columnGroupState: this.gridOptions.columnApi.getColumnGroupState(),
    sortState: this.gridOptions.api.getSortModel(),
    filterState: this.gridOptions.api.getFilterModel(),
    displayedColumns: this.gridOptions.columnApi.getAllDisplayedColumns()
  };

  // submit it to API
}


Solution

  • You're right, there's no official way to do it. A workaround could be to detect when the menu is closed yourself. Ag-grid does provide you the postProcessPopup callback (see here) which provides the parameter of type PostProcessPopupParams; this contains the column menu popup element that is displayed, so you could check when the menu is no longer visible.

    Create a variable to store the columnMenu element in:

    columnMenu: any = null;
    

    Store the columnMenu in this variable using the ag-grid event postProcessPopup:

    <ag-grid-angular [postProcessPopup]="postProcessPopup"></ag-grid-angular>
    
    this.postProcessPopup = function(params) {
      this.columnMenu = params.ePopup;
    }.bind(this);
    

    Then create a listener to detect when the column menu is no longer visible in the dom:

    this.renderer.listen('window', 'click',(e:Event)=>{
          console.log(this.columnMenu)
            const columnMenuIsInDom = document.body.contains(this.columnMenu);
    
            if (!columnMenuIsInDom && this.columnMenu != null)
            {
              this.columnMenu = null;
            }
        });
    

    This is slightly hacky and a workaround, but I can't think of a better way at the moment.

    Take a look at this Plunker for illustration.