2

I have an Ionic application where I use inline edit using Angular slick-grid for editing the gird. In my case, the user will make all the necessary changes and finally on the "save all" button click all the edited have to be updated in the DB. I want to know if there's any way of pulling the edited records from the grid/dataset by default rather than maintaining an external variable for storing the edited records IDs.

//I use this method to update the dataset.    
onCellChanged(e, args) {
        this.angularGrid.gridService.updateDataGridItemById(args.item['id'], args.item);
    }

1 Answers1

1

You can use the Edit Command Queue to know what item(s) got changed, this queue is useful to do an "Undo" when there's any error or when you just want to undo. The Queue keeps track of all the item row/cell indexes and their value before/after that got modified, you can get all item(s) from there and once you "Save All" you can just reset that queue.

export class MyComponent {
  private angularGrid: AngularGridInstance;
  private dataViewObj: any;
  private gridObj: any;
  private editQueue = [];

  angularGridReady(angularGrid: AngularGridInstance) {
    this.angularGrid = angularGrid;
    this.gridObj = angularGrid.slickGrid;
    this.dataViewObj = angularGrid.dataView;
  }

  prepareGrid() {
    this.columnDefinitions = [ /*...*/ ];

    this.gridOptions = {
      autoEdit: true,
      editable: true,
      enableCellNavigation: true,
      editCommandHandler: (item, column, editCommand) => {
        this.editQueue.push(editCommand); // <-- last edit command
        editCommand.execute();
      },
    };
  }

  handleOnErrorCallback(error, gridObj) {
     // undo last edit in the grid
     const lastEdit = this.editQueue.pop();
     if (lastEdit && lastEdit.command) {
        lastEdit.command.undo();
        gridObj.gotoCell(lastEdit.command.row, lastEdit.command.cell, false);
     }
     return false;
  }

  saveAll() {
     // for example, to get the last Edit, you could type get it this way
     // const lastEdit = this.editQueue[this.editQueue.length - 1];
     // const lastEditField = lastEdit && lastEdit.column && lastEdit.column.field;

     const editItems = [];

     // in your case, you would want to loop through the entire queue
     this.editQueue.forEach((editObj) => {
       const previousValue = editObj.prevSerializedValue;
       const newValue = editObj.serializedValue;
       const rowIndex = editObj.row; // from the row index, you can get the item
       const item = this.angularGrid.dataView.getItem(rowIndex);

       // do what you want with the value or item
       editItems.push(item);
     });

     // call your save all method
     // this.saveInDb(editItems);

     // don't forget to reset your edit queue to restart with a new batch of edits
     this.editQueue = [];     
  }
}

Actually after writing this, I just saw that it might be easier to just get an array of items directly from the editCommandHandler

export class MyComponent {
  private editItems = [];

  prepareGrid() {
    this.columnDefinitions = [ /*...*/ ];

    this.gridOptions = {
      autoEdit: true,
      editable: true,
      enableCellNavigation: true,
      editCommandHandler: (item, column, editCommand) => {
        this.editItems.push(item);
        this.editQueue.push(editCommand); // <-- last edit command
        editCommand.execute();
      },
    };
  }

  saveAll() {
    // call your save all method
    // this.saveInDb(editItems);

    // don't forget to reset your edit queue to restart with a new batch of edits
    this.editQueue = [];   
    this.editItems = [];
  }
}
ghiscoding
  • 12,308
  • 6
  • 69
  • 112