Select 行点击反应 - table
Select row on click react-table
我正在努力寻找与我的 React 应用程序一起使用的最佳 table,目前,react-table 提供了我需要的一切(分页、服务器端控制、过滤、排序、页脚行)。
话虽如此,我似乎无法 select 连续。没有 examples 表明这一点。
我尝试过的一些事情包括尝试在单击该行时设置 class名称。但我似乎无法在 e
和 t
中找到调用元素。另外,我不喜欢这种方法,因为这不是 React 应用程序应该做的事情。
<ReactTable
...
getTrProps={(state, rowInfo, column, instance) => {
return {
onClick: (e, t) => {
t.srcElement.classList.add('active')
},
style: {
}
}
}}
/>
一些可能的解决方法是将复选框呈现为第一列,但这不是最佳选择,因为它限制了单击区域到 'activate' 行。此外,视觉反馈的表现力也会降低。
我想念房间里的大象吗?如果没有,您是否知道另一个支持我之前描述的内容的库?
谢谢!
编辑:
另一种选择,这是开源的,是建议编辑。也许这是正确的做法。
编辑 2
Davorin Ruševljan 在评论中提出的另一件事是:
onRowClick(e, t, rowInfo) {
this.setState((oldState) => {
let data = oldState.data.slice();
let copy = Object.assign({}, data[rowInfo.index]);
copy.selected = true;
copy.FirstName = "selected";
data[rowInfo.index] = copy;
return {
data: data,
}
})
}
....
getTrProps={(state, rowInfo, column) => {
return {
onClick: (e, t) => { this.onRowClick(e, t, rowInfo) },
style: {
background: rowInfo && rowInfo.row.selected ? 'green' : 'red'
}
}
}}
这会将 'FirstName' 列设置为 'selected',但不会将 class 设置为 'green'
我不熟悉,react-table,所以我不知道它是否直接支持选择和取消选择(如果有就好了)。
如果没有,您可以使用已有的代码安装 onCLick 处理程序。现在,您可以修改状态,而不是尝试将样式直接附加到行,例如将 selected: true 添加到行数据。那会触发重新渲染。现在您只需要覆盖带有 selected === true 的行是如何呈现的。符合以下内容:
// Any Tr element will be green if its (row.age > 20)
<ReactTable
getTrProps={(state, rowInfo, column) => {
return {
style: {
background: rowInfo.row.selected ? 'green' : 'red'
}
}
}}
/>
经过几次尝试,我找到了解决方案,希望这对您有所帮助。将以下内容添加到您的 <ReactTable>
组件中:
getTrProps={(state, rowInfo) => {
if (rowInfo && rowInfo.row) {
return {
onClick: (e) => {
this.setState({
selected: rowInfo.index
})
},
style: {
background: rowInfo.index === this.state.selected ? '#00afec' : 'white',
color: rowInfo.index === this.state.selected ? 'white' : 'black'
}
}
}else{
return {}
}
}
在您的 state
中不要忘记添加空 selected
值,例如:
state = { selected: null }
动态样式的另一种机制是在组件的 JSX 中定义它。例如,以下内容可用于选择性地设置 React tic-tac-toe 教程中当前步骤的样式(建议的额外信用增强之一:
return (
<li key={move}>
<button style={{fontWeight:(move === this.state.stepNumber ? 'bold' : '')}} onClick={() => this.jumpTo(move)}>{desc}</button>
</li>
);
当然,更简洁的方法是 add/remove a 'selected' CSS class,但这种直接方法在某些情况下可能会有所帮助。
如果你想在 select 行上有多个 selection..
import React from 'react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
import { ReactTableDefaults } from 'react-table';
import matchSorter from 'match-sorter';
class ThreatReportTable extends React.Component{
constructor(props){
super(props);
this.state = {
selected: [],
row: []
}
}
render(){
const columns = this.props.label;
const data = this.props.data;
Object.assign(ReactTableDefaults, {
defaultPageSize: 10,
pageText: false,
previousText: '<',
nextText: '>',
showPageJump: false,
showPagination: true,
defaultSortMethod: (a, b, desc) => {
return b - a;
},
})
return(
<ReactTable className='threatReportTable'
data= {data}
columns={columns}
getTrProps={(state, rowInfo, column) => {
return {
onClick: (e) => {
var a = this.state.selected.indexOf(rowInfo.index);
if (a == -1) {
// this.setState({selected: array.concat(this.state.selected, [rowInfo.index])});
this.setState({selected: [...this.state.selected, rowInfo.index]});
// Pass props to the React component
}
var array = this.state.selected;
if(a != -1){
array.splice(a, 1);
this.setState({selected: array});
}
},
// #393740 - Lighter, selected row
// #302f36 - Darker, not selected row
style: {background: this.state.selected.indexOf(rowInfo.index) != -1 ? '#393740': '#302f36'},
}
}}
noDataText = "No available threats"
/>
)
}
}
export default ThreatReportTable;
您选择的答案是正确的,但是如果您使用排序 table 它会崩溃,因为 rowInfo 在您搜索时会变得未定义,建议改用此函数
getTrGroupProps={(state, rowInfo, column, instance) => {
if (rowInfo !== undefined) {
return {
onClick: (e, handleOriginal) => {
console.log('It was in this row:', rowInfo)
this.setState({
firstNameState: rowInfo.row.firstName,
lastNameState: rowInfo.row.lastName,
selectedIndex: rowInfo.original.id
})
},
style: {
cursor: 'pointer',
background: rowInfo.original.id === this.state.selectedIndex ? '#00afec' : 'white',
color: rowInfo.original.id === this.state.selectedIndex ? 'white' : 'black'
}
}
}}
}
React-Table 包含一个允许选择的 HOC,即使在过滤和分页 table 时,设置也比基本 table 稍微高级一些,所以首先通读下面 link 中的信息。
导入 HOC 后,您可以通过必要的方法像这样使用它:
/**
* Toggle a single checkbox for select table
*/
toggleSelection(key: number, shift: string, row: string) {
// start off with the existing state
let selection = [...this.state.selection];
const keyIndex = selection.indexOf(key);
// check to see if the key exists
if (keyIndex >= 0) {
// it does exist so we will remove it using destructing
selection = [
...selection.slice(0, keyIndex),
...selection.slice(keyIndex + 1)
];
} else {
// it does not exist so add it
selection.push(key);
}
// update the state
this.setState({ selection });
}
/**
* Toggle all checkboxes for select table
*/
toggleAll() {
const selectAll = !this.state.selectAll;
const selection = [];
if (selectAll) {
// we need to get at the internals of ReactTable
const wrappedInstance = this.checkboxTable.getWrappedInstance();
// the 'sortedData' property contains the currently accessible records based on the filter and sort
const currentRecords = wrappedInstance.getResolvedState().sortedData;
// we just push all the IDs onto the selection array
currentRecords.forEach(item => {
selection.push(item._original._id);
});
}
this.setState({ selectAll, selection });
}
/**
* Whether or not a row is selected for select table
*/
isSelected(key: number) {
return this.state.selection.includes(key);
}
<CheckboxTable
ref={r => (this.checkboxTable = r)}
toggleSelection={this.toggleSelection}
selectAll={this.state.selectAll}
toggleAll={this.toggleAll}
selectType="checkbox"
isSelected={this.isSelected}
data={data}
columns={columns}
/>
更多信息请看这里:
https://github.com/tannerlinsley/react-table/tree/v6#selecttable
带有复选框的多行和 select 全部使用 useState()
挂钩。需要少量实施以适应自己的项目。
const data;
const [ allToggled, setAllToggled ] = useState(false);
const [ toggled, setToggled ] = useState(Array.from(new Array(data.length), () => false));
const [ selected, setSelected ] = useState([]);
const handleToggleAll = allToggled => {
let selectAll = !allToggled;
setAllToggled(selectAll);
let toggledCopy = [];
let selectedCopy = [];
data.forEach(function (e, index) {
toggledCopy.push(selectAll);
if(selectAll) {
selectedCopy.push(index);
}
});
setToggled(toggledCopy);
setSelected(selectedCopy);
};
const handleToggle = index => {
let toggledCopy = [...toggled];
toggledCopy[index] = !toggledCopy[index];
setToggled(toggledCopy);
if( toggledCopy[index] === false ){
setAllToggled(false);
}
else if (allToggled) {
setAllToggled(false);
}
};
....
Header: state => (
<input
type="checkbox"
checked={allToggled}
onChange={() => handleToggleAll(allToggled)}
/>
),
Cell: row => (
<input
type="checkbox"
checked={toggled[row.index]}
onChange={() => handleToggle(row.index)}
/>
),
....
<ReactTable
...
getTrProps={(state, rowInfo, column, instance) => {
if (rowInfo && rowInfo.row) {
return {
onClick: (e, handleOriginal) => {
let present = selected.indexOf(rowInfo.index);
let selectedCopy = selected;
if (present === -1){
selected.push(rowInfo.index);
setSelected(selected);
}
if (present > -1){
selectedCopy.splice(present, 1);
setSelected(selectedCopy);
}
handleToggle(rowInfo.index);
},
style: {
background: selected.indexOf(rowInfo.index) > -1 ? '#00afec' : 'white',
color: selected.indexOf(rowInfo.index) > -1 ? 'white' : 'black'
},
}
}
else {
return {}
}
}}
/>
# react-table with edit button #
const [rowIndexState, setRowIndexState] = useState(null);
const [rowBackGroundColor, setRowBackGroundColor] = useState('')
{...row.getRowProps({
onClick: (e) => {
if (!e.target.cellIndex) {
setRowIndexState(row.index);
setRowBackGroundColor('#f4f4f4')
}
},
style: {
background: row.index === rowIndexState ? rowBackGroundColor : '',
},
})}
如果您使用的是最新版本(当时是 7.7),则可以使用 toggleRoWSelected()
select 行查看完整示例;
<tr
{...row.getRowProps()}
className="odd:bg-white even:bg-gray-100"
onClick={() => row.toggleRowSelected()}
>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()} className="p-2">
{cell.render("Cell")}
</td>
);
})}
</tr>;
我正在努力寻找与我的 React 应用程序一起使用的最佳 table,目前,react-table 提供了我需要的一切(分页、服务器端控制、过滤、排序、页脚行)。
话虽如此,我似乎无法 select 连续。没有 examples 表明这一点。
我尝试过的一些事情包括尝试在单击该行时设置 class名称。但我似乎无法在 e
和 t
中找到调用元素。另外,我不喜欢这种方法,因为这不是 React 应用程序应该做的事情。
<ReactTable
...
getTrProps={(state, rowInfo, column, instance) => {
return {
onClick: (e, t) => {
t.srcElement.classList.add('active')
},
style: {
}
}
}}
/>
一些可能的解决方法是将复选框呈现为第一列,但这不是最佳选择,因为它限制了单击区域到 'activate' 行。此外,视觉反馈的表现力也会降低。
我想念房间里的大象吗?如果没有,您是否知道另一个支持我之前描述的内容的库?
谢谢!
编辑: 另一种选择,这是开源的,是建议编辑。也许这是正确的做法。
编辑 2
Davorin Ruševljan 在评论中提出的另一件事是:
onRowClick(e, t, rowInfo) {
this.setState((oldState) => {
let data = oldState.data.slice();
let copy = Object.assign({}, data[rowInfo.index]);
copy.selected = true;
copy.FirstName = "selected";
data[rowInfo.index] = copy;
return {
data: data,
}
})
}
....
getTrProps={(state, rowInfo, column) => {
return {
onClick: (e, t) => { this.onRowClick(e, t, rowInfo) },
style: {
background: rowInfo && rowInfo.row.selected ? 'green' : 'red'
}
}
}}
这会将 'FirstName' 列设置为 'selected',但不会将 class 设置为 'green'
我不熟悉,react-table,所以我不知道它是否直接支持选择和取消选择(如果有就好了)。
如果没有,您可以使用已有的代码安装 onCLick 处理程序。现在,您可以修改状态,而不是尝试将样式直接附加到行,例如将 selected: true 添加到行数据。那会触发重新渲染。现在您只需要覆盖带有 selected === true 的行是如何呈现的。符合以下内容:
// Any Tr element will be green if its (row.age > 20)
<ReactTable
getTrProps={(state, rowInfo, column) => {
return {
style: {
background: rowInfo.row.selected ? 'green' : 'red'
}
}
}}
/>
经过几次尝试,我找到了解决方案,希望这对您有所帮助。将以下内容添加到您的 <ReactTable>
组件中:
getTrProps={(state, rowInfo) => {
if (rowInfo && rowInfo.row) {
return {
onClick: (e) => {
this.setState({
selected: rowInfo.index
})
},
style: {
background: rowInfo.index === this.state.selected ? '#00afec' : 'white',
color: rowInfo.index === this.state.selected ? 'white' : 'black'
}
}
}else{
return {}
}
}
在您的 state
中不要忘记添加空 selected
值,例如:
state = { selected: null }
动态样式的另一种机制是在组件的 JSX 中定义它。例如,以下内容可用于选择性地设置 React tic-tac-toe 教程中当前步骤的样式(建议的额外信用增强之一:
return (
<li key={move}>
<button style={{fontWeight:(move === this.state.stepNumber ? 'bold' : '')}} onClick={() => this.jumpTo(move)}>{desc}</button>
</li>
);
当然,更简洁的方法是 add/remove a 'selected' CSS class,但这种直接方法在某些情况下可能会有所帮助。
如果你想在 select 行上有多个 selection..
import React from 'react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
import { ReactTableDefaults } from 'react-table';
import matchSorter from 'match-sorter';
class ThreatReportTable extends React.Component{
constructor(props){
super(props);
this.state = {
selected: [],
row: []
}
}
render(){
const columns = this.props.label;
const data = this.props.data;
Object.assign(ReactTableDefaults, {
defaultPageSize: 10,
pageText: false,
previousText: '<',
nextText: '>',
showPageJump: false,
showPagination: true,
defaultSortMethod: (a, b, desc) => {
return b - a;
},
})
return(
<ReactTable className='threatReportTable'
data= {data}
columns={columns}
getTrProps={(state, rowInfo, column) => {
return {
onClick: (e) => {
var a = this.state.selected.indexOf(rowInfo.index);
if (a == -1) {
// this.setState({selected: array.concat(this.state.selected, [rowInfo.index])});
this.setState({selected: [...this.state.selected, rowInfo.index]});
// Pass props to the React component
}
var array = this.state.selected;
if(a != -1){
array.splice(a, 1);
this.setState({selected: array});
}
},
// #393740 - Lighter, selected row
// #302f36 - Darker, not selected row
style: {background: this.state.selected.indexOf(rowInfo.index) != -1 ? '#393740': '#302f36'},
}
}}
noDataText = "No available threats"
/>
)
}
}
export default ThreatReportTable;
您选择的答案是正确的,但是如果您使用排序 table 它会崩溃,因为 rowInfo 在您搜索时会变得未定义,建议改用此函数
getTrGroupProps={(state, rowInfo, column, instance) => {
if (rowInfo !== undefined) {
return {
onClick: (e, handleOriginal) => {
console.log('It was in this row:', rowInfo)
this.setState({
firstNameState: rowInfo.row.firstName,
lastNameState: rowInfo.row.lastName,
selectedIndex: rowInfo.original.id
})
},
style: {
cursor: 'pointer',
background: rowInfo.original.id === this.state.selectedIndex ? '#00afec' : 'white',
color: rowInfo.original.id === this.state.selectedIndex ? 'white' : 'black'
}
}
}}
}
React-Table 包含一个允许选择的 HOC,即使在过滤和分页 table 时,设置也比基本 table 稍微高级一些,所以首先通读下面 link 中的信息。
导入 HOC 后,您可以通过必要的方法像这样使用它:
/**
* Toggle a single checkbox for select table
*/
toggleSelection(key: number, shift: string, row: string) {
// start off with the existing state
let selection = [...this.state.selection];
const keyIndex = selection.indexOf(key);
// check to see if the key exists
if (keyIndex >= 0) {
// it does exist so we will remove it using destructing
selection = [
...selection.slice(0, keyIndex),
...selection.slice(keyIndex + 1)
];
} else {
// it does not exist so add it
selection.push(key);
}
// update the state
this.setState({ selection });
}
/**
* Toggle all checkboxes for select table
*/
toggleAll() {
const selectAll = !this.state.selectAll;
const selection = [];
if (selectAll) {
// we need to get at the internals of ReactTable
const wrappedInstance = this.checkboxTable.getWrappedInstance();
// the 'sortedData' property contains the currently accessible records based on the filter and sort
const currentRecords = wrappedInstance.getResolvedState().sortedData;
// we just push all the IDs onto the selection array
currentRecords.forEach(item => {
selection.push(item._original._id);
});
}
this.setState({ selectAll, selection });
}
/**
* Whether or not a row is selected for select table
*/
isSelected(key: number) {
return this.state.selection.includes(key);
}
<CheckboxTable
ref={r => (this.checkboxTable = r)}
toggleSelection={this.toggleSelection}
selectAll={this.state.selectAll}
toggleAll={this.toggleAll}
selectType="checkbox"
isSelected={this.isSelected}
data={data}
columns={columns}
/>
更多信息请看这里:
https://github.com/tannerlinsley/react-table/tree/v6#selecttable
带有复选框的多行和 select 全部使用 useState()
挂钩。需要少量实施以适应自己的项目。
const data;
const [ allToggled, setAllToggled ] = useState(false);
const [ toggled, setToggled ] = useState(Array.from(new Array(data.length), () => false));
const [ selected, setSelected ] = useState([]);
const handleToggleAll = allToggled => {
let selectAll = !allToggled;
setAllToggled(selectAll);
let toggledCopy = [];
let selectedCopy = [];
data.forEach(function (e, index) {
toggledCopy.push(selectAll);
if(selectAll) {
selectedCopy.push(index);
}
});
setToggled(toggledCopy);
setSelected(selectedCopy);
};
const handleToggle = index => {
let toggledCopy = [...toggled];
toggledCopy[index] = !toggledCopy[index];
setToggled(toggledCopy);
if( toggledCopy[index] === false ){
setAllToggled(false);
}
else if (allToggled) {
setAllToggled(false);
}
};
....
Header: state => (
<input
type="checkbox"
checked={allToggled}
onChange={() => handleToggleAll(allToggled)}
/>
),
Cell: row => (
<input
type="checkbox"
checked={toggled[row.index]}
onChange={() => handleToggle(row.index)}
/>
),
....
<ReactTable
...
getTrProps={(state, rowInfo, column, instance) => {
if (rowInfo && rowInfo.row) {
return {
onClick: (e, handleOriginal) => {
let present = selected.indexOf(rowInfo.index);
let selectedCopy = selected;
if (present === -1){
selected.push(rowInfo.index);
setSelected(selected);
}
if (present > -1){
selectedCopy.splice(present, 1);
setSelected(selectedCopy);
}
handleToggle(rowInfo.index);
},
style: {
background: selected.indexOf(rowInfo.index) > -1 ? '#00afec' : 'white',
color: selected.indexOf(rowInfo.index) > -1 ? 'white' : 'black'
},
}
}
else {
return {}
}
}}
/>
# react-table with edit button #
const [rowIndexState, setRowIndexState] = useState(null);
const [rowBackGroundColor, setRowBackGroundColor] = useState('')
{...row.getRowProps({
onClick: (e) => {
if (!e.target.cellIndex) {
setRowIndexState(row.index);
setRowBackGroundColor('#f4f4f4')
}
},
style: {
background: row.index === rowIndexState ? rowBackGroundColor : '',
},
})}
如果您使用的是最新版本(当时是 7.7),则可以使用 toggleRoWSelected()
select 行查看完整示例;
<tr
{...row.getRowProps()}
className="odd:bg-white even:bg-gray-100"
onClick={() => row.toggleRowSelected()}
>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()} className="p-2">
{cell.render("Cell")}
</td>
);
})}
</tr>;