I am trying to avoid an onClick
event that is on each particular row, whenever show/less is being clicked under one column's data. I have a grid that basically has select, and multi select features. Also there is show more/show less for one of the column. Whenever I click on Show More/Less
, the row selection is triggered. I want to avoid this. Can someone tell what is wrong here. say If a have multiple instances of similar grids, I would want the row select functionality to that grid which has prop in it
Sandbox: https://codesandbox.io/s/react-table-row-table-alternate-single-row-working-5fr81
import * as React from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";
export default class DataGrid extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedRows: []
};
}
rowClick = (state, rowInfo) => {
if (rowInfo) {
let selectedRows = new Set();
return {
onClick: e => {
e.stopPropagation();
if (e.ctrlKey) {
selectedRows = this.state.selectedRows;
rowInfo._index = rowInfo.index;
if (
selectedRows.filter(row => row._index === rowInfo._index)
.length === 0
)
selectedRows.push(rowInfo);
else
selectedRows = selectedRows.filter(
row => row._index !== rowInfo._index
);
this.setState({
selectedRows
});
} else {
selectedRows = [];
rowInfo._index = rowInfo.index;
selectedRows.push(rowInfo);
}
this.setState(
{
selectedRows
},
() => {
console.log("final values", this.state.selectedRows);
this.props.rowClicked(this.state.selectedRows);
}
);
},
style: {
background:
this.state.selectedRows.some(e => e._index === rowInfo.index) &&
"#9bdfff"
}
};
} else {
return "";
}
};
render() {
return (
<ReactTable
data={this.props.data}
columns={this.props.columns}
getTrProps={this.rowClick}
/>
);
}
}
On your ShowMore component, you can modify your onClick
event handler to call event.stopPropagation()
. This will stop further propagation of the current event in the capturing and bubbling phases, and allow you to click on Show More/Less without triggering row selection.
const toggleTruncate = (e) => {
e.stopPropagation();
setShowMore(!isShowMore);
}
React actually defines the synthetic event, which will be available on your click event handler, without the need to call document.addEventListener()
. You may read more about event handling in React over here.
And answering your second part of the question, given that the rowClicked
event is an optional props of the DataGrid
component, you will need to manually check it on the DataGrid
component to ensure that it will only be called if it is defined. This is how it can be done:
if (rowClicked) {
// do the rest
}
And this is how your rowClick
method should look like. Do take note that I have destructured the props object on the second line. This will ensure that row selection logic will be carried out only if rowClicked
is defined.
rowClick = (state, rowInfo) => {
const { rowClicked } = this.props;
if (rowInfo && rowClicked) {
let selectedRows = new Set();
return {
onClick: e => {
e.stopPropagation();
if (e.ctrlKey) {
selectedRows = this.state.selectedRows;
rowInfo._index = rowInfo.index;
if (
selectedRows.filter(row => row._index === rowInfo._index)
.length === 0
)
selectedRows.push(rowInfo);
else
selectedRows = selectedRows.filter(
row => row._index !== rowInfo._index
);
this.setState({
selectedRows
});
} else {
selectedRows = [];
rowInfo._index = rowInfo.index;
selectedRows.push(rowInfo);
}
this.setState(
{
selectedRows
},
() => {
rowClicked(this.state.selectedRows);
}
);
},
style: {
background:
this.state.selectedRows.some(e => e._index === rowInfo.index) &&
"#9bdfff"
}
};
} else {
return "";
}
};