How to deselect row when clicked outside the table? [used: Material-UI DataGrid]

Viewed 1865

I'm using Material-UI tables for showing my data, and I'm stuck when it comes to deselecting selected row.

So when user clicks outside the table, row should be deselected.

This is my code

const showData2 = (e,data) => {
        console.log('selection',e)
    }

<div style={{ height: 180, width: "100%", backgroundColor:'white' }}>
                        <DataGrid
                            rows={cases}
                            density='compact'
                            columns={columnsCases}
                            pageSize={3}
                            hideFooterSelectedRowCount={true}
                            rowHeight={40}
                            onRowSelected = {(e)=>{showData(e)}}
                            onSelectionChange= {(e)=>{showData2(e)}}
                        />
                    </div>

Selection works perfectly but it seems impossible to deselect row when clicked outside the table

I would appreciate any idea and help.

Thank you!!

4 Answers

Good Day,

Like @Omar EL KHAL said a ClickAwayListener works perfectly.

Step One: Define your onSelectionModelChange and handleClickAway function.

const handleSelection = (newSelection) => {
    if (newSelection)
    {
        setSelectionModel(newSelection.selectionModel);
    }
    else
    {
        setSelectionModel(null);
    }
}
const handleClickAway = () => {
  handleSelection(null);
};


Step Two: Define your selectionModel as State
For this step I chose to set selectionModel in the component state to allow for other functions to set values.

const [selectionModel, setSelectionModel] = React.useState([]);


Step Three: Set the onSelectionModelChange and selectionModel props
Set the props props in the Data Grid as follows.

<ClickAwayListener onClickAway={handleClickAway}>
    <DataGrid 
    onSelectionModelChange={handleSelection}
    selectionModel={eventSelectionModel}
    />
</ClickAwayListener>

Once you save and let NPM do its thing you it should work.
I personally tested this on a single selection model but it should work with multiple as well.

P.S. I also did this with functional components and not classed components. The theory would be the same just instead of using useState you would use this.setState.

Happy Coding!
Gunny

Deselect Row Example using the ClickAwayListener with Typescript

  1. Import GridRowId type in addition to whatever other types or components you need from data-grid

    import { DataGrid, GridColDef, GridRowId } from '@material-ui/data-grid';

  2. Set local state for the selectionModel prop on the DataGrid and init as an empty array.

    const [selectionModel, setSelectionModel] = useState<GridRowId[]>([]);

  3. Add DataGrid component as child of ClickAwayListener... plus your other DataGrid props.

     <ClickAwayListener onClickAway={() => setSelectionModel([])}>
               <DataGrid
                 {...otherProps}
                 checkboxSelection // <= works with or without checkbox selection
                 selectionModel={selectionModel}
                 onSelectionModelChange={({ selectionModel }) =>
                   setSelectionModel(selectionModel)
                 }
               />
     </ClickAwayListener>
    

Of course you can just remove the types if you're not using Typescript.

There is no need for extra state. You could simply call the setSelectionModel function on the ClickAwayListener like so:

<ClickAwayListener onClickAway={() => apiRef.current.setSelectionModel([])}>
// your Data Grid 
</ClickAwayListener>
Related