Mike Cantor
Mike Cantor

Reputation: 185

AgGridReact - Grid does not update when isRowSelectable changes

I am trying to pass isRowSelectable dynamically as a prop to an AgGridReact. In the following toy example, You expect that clicking the "Switch criteria" button will change the set of items in the grid that have checkboxes. Instead, the grid is unchanged.

Screenshots:

interface Item { name: string, age: number, height: number}
const data: Item[] = [
    {name: "old and tall", age: 80, height: 80}, 
    {name: "old and short", age: 80, height: 20},
    {name: "young and tall", age: 10, height: 80}, 
    {name: "young and short", age: 10, height: 20}, 
]
const colDefs: ColDef[] = [
    {
        headerName: "",
        checkboxSelection: true,
        headerCheckboxSelection: true,
        headerCheckboxSelectionFilteredOnly: true,
        width: 60,
        sortable: false
    },
    { field: "name"},
    { field: "age"},
    { field: "height"}
]

const criteria1 = (node: RowNode) => node.data.age > 50
const criteria2 = (node: RowNode) => node.data.height > 50

export const DevPage: FunctionComponent = () => {

    const [isCriteria1, setIsCriteria1] = useState<boolean>(false)

    return ( <Fragment>
    
        <h2> {isCriteria1 ? "By Age" : "By Height"} </h2>
        <Button onClick = { () => setIsCriteria1(!isCriteria1) }> 
            Switch criteria
        </Button> 
        
        <div className="ag-theme-alpine" style={{height:"800px"}}>
            <AgGridReact
                rowSelection="multiple"
                columnDefs = {colDefs}
                rowData={data}
                isRowSelectable = {isCriteria1 ? criteria1 : criteria2}
                suppressRowClickSelection={true}
            />
        </div>
        
    </Fragment> )
}

Upvotes: 8

Views: 2629

Answers (4)

ewulff
ewulff

Reputation: 2259

This was fixed in November 2023 as part of [email protected]. Check the changelog under https://github.com/ag-grid/ag-grid/releases/tag/v31.0.0, issue AG-7980.

Upvotes: 0

KARTHIKEYAN.A
KARTHIKEYAN.A

Reputation: 20088

we can use gridParams.api.forEachNode() to get each row node and then we can able to set checkbox select enable/disable option using setRowSelectable() method in the following way.

gridParams.api.forEachNode(node => {
    node.setRowSelectable(true) // this will enable checkbox select option 
    node.setRowSelectable(false) // this will disable checkbox select option
})

Upvotes: 0

Tomasz Fijałkowski
Tomasz Fijałkowski

Reputation: 799

This is the AG Grid issue. The AG Grid (tested with 28.2.1) is not refreshing state when an isRowSelectable function is changed.

You can force set row selectable by the setRowSelectable function

apiRef.current?.grid?.forEachNode(
  (rowNode: RowNode) => rowNode.setRowSelectable(isSelectable(rowNode))
)

Below a fork of the NearHuscarl approach with declared react dependencies on the useCallback and the useState functions.

const [rowData, setRowData] = React.useState<Athlete[]>([]);
const [criterial, setCriteria] = React.useState(true);
const isSelectable = React.useCallback((rowNode: RowNode) => {
  const result = rowNode.data.age > 25;
  const selectable = result === criterial;
  return selectable;
}, [criterial]);
const toggleCriteria = React.useCallback(() => {
  setCriteria((c) => !c);
}, []);
React.useEffect(() => {
  apiRef.current?.grid?.deselectAll();
  apiRef.current?.grid?.forEachNode(
    (rowNode: RowNode) => rowNode.setRowSelectable(isSelectable(rowNode))
  )
}, [apiRef, isSelectable]);

return (
  <>
    <button onClick={toggleCriteria}>Toggle Criteria</button>
    <AgGridReact
      rowSelection="multiple"
      suppressRowClickSelection
      columnDefs={columnDefs}
      onGridReady={onGridReady}
      isRowSelectable={isSelectable}
      rowData={rowData}
    />
  </>
);

Live Demo

enter link description here

Upvotes: 1

NearHuscarl
NearHuscarl

Reputation: 81340

As a workaround, you can force all RowNodes to re-evaluate selectable property when onClick event fires.

const [rowData, setRowData] = React.useState<RowDataType[]>([]);
const criterial = React.useRef(true);
const isSelectable = (rowNode: RowNode) => {
  const result = rowNode.data.age > 25;
  const selectable = result === criterial.current;

  return selectable;
};
const toggleCriteria = () => {
  const updateSelectable = (rowNode: RowNode) => {
    rowNode.setRowSelectable(isSelectable(rowNode));
  };

  criterial.current = !criterial.current;
  gridApi.deselectAll();
  gridApi.forEachNodeAfterFilterAndSort(updateSelectable);
};

return (
  <>
    <button onClick={toggleCriteria}>Toggle Criteria</button>
    <AgGridReact
      rowSelection="multiple"
      suppressRowClickSelection
      columnDefs={columnDefs}
      onGridReady={onGridReady}
      isRowSelectable={isSelectable}
      rowData={rowData}
    />
  </>
);

Live Demo

Edit 64014770/aggridreact-grid-does-not-update-when-isrowselectable-changes/

Upvotes: 4

Related Questions