Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ag Grid stops editing cells when any other cell on the grid is clicked. How to prevent this?

I have an Ag Grid with fullRow edit functionality. The row enters edit mode when an Edit button is clicked (using the startEditing() method of the grid).

On edit mode, I display two buttons, Save and Cancel. I've found ways to suppress Keyboard events (Enter, Esc etc). But I can't find any way to stop the grid from exiting edit mode when another cell is clicked. I want the row to still be on edit mode even when another part of the grid is clicked.

How can I achieve this functionlity? Thanks

N:B: I'm using ag-grid (latest version) with Angular 9

like image 988
Jahir Avatar asked May 14 '20 18:05

Jahir


3 Answers

The AG-Grid docs state the following:

The grid will stop editing when any of the following happen:

Other Cell Focus: If focus in the grid goes to another cell, the editing will stop.

This is the functionality that seems to cause most of the problems. As was stated in another answer, there is no way to disable this functionality out of the box with ag-grid which is unfortunate. The event handlers that ag-grid provides all run after ag-grid has processed a cell-focus so none of them are helpful. There are also options to disable clicks on rows but none of these stop the cell from gaining focus.

As a result, the solution posed by Pratik Bhat is the best option if you're using the built in editors and don't have to deal with losing the editor state.

If you are using a custom editor component, losing the state every time ag-grid closes the editor is huge problem. I was able to come up with the following workaround to prevent the focus of a cell from triggering the stopEditing event. This workaround is ugly and I only recommend it as a last resort.

Workaround:

The AG-Grid source code defines a prototype for onCellFocused. You can overwrite this function in your applications source code and remove the code that calls stopRowOrCellEdit() which will prevent focus of other rows from stopping edit mode. Below is an example of the code snippet you would need to include in your application source code(be sure to remove the lines below the comment).

If you decide to go this route, be sure to copy the function prototype from the source code of the version of AG grid you are using and not from this example. This example is from ag-grid 22.0.1 so the function may differ in your ag-grid source. Keep in mind, if you update AG grid, you may need to update your function overwrite so that it matches the new ag-grid source. If you use a package manager make sure your locking the version of ag-grid so the overwritten prototype in your application source code will match.

import { CellComp, _ } from 'ag-grid-community';

CellComp.prototype.onCellFocused = function(event) {
      var cellFocused = this.beans.focusedCellController.isCellFocused(
        this.cellPosition
      );
      
      if (cellFocused !== this.cellFocused) {
        var doingFocusCss = !this.beans.gridOptionsWrapper.isSuppressCellSelection();
        if (doingFocusCss) {
          _.addOrRemoveCssClass(this.getGui(), 'ag-cell-focus', cellFocused);
        }
        this.cellFocused = cellFocused;
      }
      
      if (cellFocused && event && event.forceBrowserFocus) {
        this.getGui().focus();
        if (
          !document.activeElement ||
          document.activeElement === document.body
        ) {
          this.getGui().focus();
        }
      }

      // remove these lines to prevent editing from being stopped on focus
      var fullRowEdit = this.beans.gridOptionsWrapper.isFullRowEdit();
      if (!cellFocused && !fullRowEdit && this.editingCell) {
        this.stopRowOrCellEdit();
      }
    };
like image 179
Vellith Avatar answered Oct 26 '22 03:10

Vellith


Unfortunately, this is not supported out of the box in ag-grid.

However there is a work around I implemented.

Basically you need to track if save and cancel was clicked anytime after editing started. And then show the popup again if Save was not clicked.

In template

(rowEditingStopped)="onRowEditingStopped($event)"
(rowEditingStarted)="onRowEditingStarted($event)"  

In component

  onRowEditingStarted(params) {
       isSaveClicked = false;
       isCancelClicked = false;
  }

  onRowEditingStopped(params) {

   if (!isSaveClicked || !isCancelClicked ) {
    this.gridApi.setFocusedCell(2, 'columnName');
    this.gridApi.startEditingCell({
      rowIndex: 2,
      colKey: 'columnName',
    });}
  }

More in docs - https://www.ag-grid.com/javascript-grid-events/#editing

like image 43
Pratik Bhat Avatar answered Oct 26 '22 02:10

Pratik Bhat


Ag-grid have an example here which has this feature in the 'numeric-editor.component.ts' file main code which is doing this is

export class NumericEditor implements ICellEditorAngularComp, AfterViewInit {


private params: any;
  public value: number;
  public highlightAllOnFocus: boolean = true;
  private cancelBeforeStart: boolean = false;

  @ViewChild('input', { read: ViewContainerRef }) public input: any;

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

    // only start edit if key pressed is a number, not a letter
    this.cancelBeforeStart =
      params.charPress && '1234567890'.indexOf(params.charPress) < 0;
--------- if this condition return true cell will exit from edit state if it return false cell will enter in edit state
  }

  isCancelBeforeStart(): boolean {
    return this.cancelBeforeStart;
  }
}
like image 20
Maaz Anzar Avatar answered Oct 26 '22 04:10

Maaz Anzar