I have the following example
Stackblitz Live Working Example
If you press the delete button on the red bin icon, it doesn't fire my onClick
event handler (instead sorting starts straight away).
If you press the delete button background of the button (circle around the bin icon), it fires the button onClick
handler and acts accordingly.
I have tried putting different onClick (including xxxxCapture
versions and e.preventDefault()
) but not having any success.
Questions
Therefore I have 2 questions:
- Is there a good way to figure out where in the tree the click is being first handled?
- How can I make my button
onClick
consistent across the background as well as theicon
itself?
Code
For those who can't open the Stackblitz, the code is:
import React from 'react';
import { Button, IconButton, Tooltip, Typography } from "@material-ui/core";
import { Add, DeleteForever } from "@material-ui/icons";
import { AutoSizer, Column, Index, Table, TableCellProps, TableProps, TableRowProps, WindowScroller, defaultTableRowRenderer } from "react-virtualized";
import { SortableContainer, SortableElement, SortEnd, SortEndHandler, SortEvent } from "react-sortable-hoc";
import 'react-virtualized/styles.css';
const SortableTable = SortableContainer<TableProps>((props: TableProps) => (
<Table {...props} />
));
const SortableRow = SortableElement<TableRowProps>(
(props: TableRowProps) => defaultTableRowRenderer(props) as any
);
const sortableRowRenderer = (props: TableRowProps) => {
return <SortableRow {...props} />;
};
interface IRow {
value: string;
}
class Grid extends React.Component<any, { items: IRow[] }> {
remove(rowData: any): any {
const items = this.state.items;
if (!items) {
return;
}
const index = items.indexOf(rowData);
const newItems = [...items.slice(0, index), ...items.slice(index + 1)];
this.setState({ items: newItems });
}
constructor(props: any) {
super(props);
this.state = {
items: this.getDefaultItems()
};
}
private getDefaultItems = () => {
return [
{ value: "one" },
{ value: "two" },
{ value: "three" },
{ value: "four" },
{ value: "five" }
]
}
private rowRenderer = (props: TableRowProps) => {
return defaultTableRowRenderer(props);
};
public render() {
return (
<div>
<WindowScroller>
{({ height, isScrolling, onChildScroll, scrollTop }) => (
<AutoSizer disableHeight={true}>
{size => (
<SortableTable
headerHeight={38}
autoHeight={true}
height={height}
rowCount={this.state.items.length}
scrollTop={scrollTop}
rowGetter={this.getItem}
rowHeight={37}
width={size.width}
rowRenderer={sortableRowRenderer}
>
<Column label={"value"} dataKey={"value"} width={160} />
<Column
dataKey={"buttons"}
cellRenderer={this.buttonsCellRenderer}
width={48}
minWidth={48}
maxWidth={48}
/>
</SortableTable>
)}
</AutoSizer>
)}
</WindowScroller>
<Button onClick={this.reset}>Reset</Button>
</div>
);
}
private reset = () => {
this.setState({ items: this.getDefaultItems() });
}
private buttonsCellRenderer = (props: TableCellProps) => {
const remove = (event: any) => {
console.log("remove");
console.log(event);
this.remove(props.rowData);
};
const removeWithPrevent = (event: any) => {
console.log("removeWithPrevent");
console.log(event);
this.remove(props.rowData);
};
return (
<Tooltip title="Delete Line Item" enterDelay={500}>
<IconButton onClick={remove}>
<DeleteForever fontSize="small" color="error" onClick={remove} />
</IconButton>
</Tooltip>
);
};
private getItem = (info: Index) => {
const rows = this.state.items;
const row = rows[info.index];
return row;
};
}
export default Grid;