javascriptslickgridangular-slickgrid

Angular Slickgrid | How to disable the row selection of checkboxSelector of selectableOverride dynamically


Want to disable the selected row items by updating the gridOptions after some button clicks.

initGridOptions() {
   this.gridOptions = {
      enableSorting: true,
      enableFiltering: true,
      enablePagination: true,
      enableAutoResize: true,
      autoResize: {
        containerId: 'grid-wrapper',
        sidePadding: 5
      },
      alwaysShowVerticalScroll: false,
      enableCheckboxSelector: true,
      enableRowSelection: true,
      checkboxSelector: {
          hideInFilterHeaderRow: false,
          hideInColumnTitleRow: true,
      },
      rowSelectionOptions: {
          // True (Single Selection), False (Multiple Selections)
          selectActiveRow: false
      }
   }
}

//prepareGrid() { ...... }

disableButtonClick() {
    this.gridObj.setOptions({
        checkboxSelector: {
            selectableOverride: (row: number, dataContext: any, grid: any) => {
               // validate each row and disable the selected rows
               return false;
            }
        }
    });
}

Stackblitz Demo


Solution

  • I'm not sure if you can toggle the checkbox column without removing it (maybe with grid.setColumns() but it's probably better to just use the selectableOverride callback. It will allow you to dynamically change its usability on the fly (see the Wiki) and in your case just use your boolean flag to have the callback return true or false (the later will disable/remove all checkboxes)

    export class Example1 implements OnInit {
      prepareGrid() {
        this.gridOptions = {
          enableRowSelection: true,
          enableCheckboxSelector: true,
          checkboxSelector: {
            // you can override the logic for showing (or not) the expand icon
            // for example, display the expand icon only on every 2nd row
            selectableOverride: (row: number, dataContext: any, grid: any) => (dataContext.id % 2 === 1)
          },
          multiSelect: false,
          rowSelectionOptions: {
            // True (Single Selection), False (Multiple Selections)
            selectActiveRow: true,
          },
        };
      }
    }
    

    As per the new comments and the stachblitz, you need to have only 1 common method and in that method you do different logic depending on what button is clicked outside. For example, if I take some code from your demo, let's use a new flag showOnlyOddRows = false and let say that when you click your external button it will turn that flag to true and as we can expect it will re-render the grid and only show the row selection on odd rows

    export class AppComponent implements OnInit {
      showOnlyOddRows = true;
    
      ngOnInit(): void {
        this.gridOptions = {
          checkboxSelector: {
            hideInFilterHeaderRow: true,
            hideInColumnTitleRow: false,
            selectableOverride: this.validateRowSelection.bind(this)
            // or
            // selectableOverride: (row: number, dataContext: any) => this.validateRowSelection(row, dataContext),
          },
          // ...
        };
      }
    
      validateRowSelection(row: number, dataContext: any, grid: any) {
        return this.showOnlyOddRows ? dataContext.id % 2 === 1 : true; // returning true means that we want to show the row selection
      }
    
      // change flag when external button is clicked and re-render grid with new row selection set
      disableOddRows() {
        this.showOnlyOddRows = true;
        this.gridObj.invalidate(); // this will re-execute the validateRowSelection method
      }
    

    So again, do not change the override with setOptions, it will completely break the code, so don't do that. If you really need to change options of the plugin, you should use the plugin setOptions not the grid.setOptions. Something like this.angularGrid.extensionService.getSlickgridAddonInstance(ExtensionName.checkboxSelector).setOptions({ /* ... */ }) or this.angularGrid.extensionService.getSlickgridAddonInstance(ExtensionName.checkboxSelector).selectableOverride = newOverrideFn ... but again I probably wouldn't do that, it's easier to just keep 1 method with different logic inside it (like validateRowSelection shown earlier)