我正在使用React Table-Demo。我正在尝试创建一个自定义框,该框只能过滤第一列-firstName。基于第一列搜索,将显示其他列的相应行。我有很多代码,为简单起见,我使用注释标记了哪些代码块与搜索功能相关。
这是我的父组件
import React from "react";
import { render } from "react-dom";
import TypeChecker from 'typeco';
// import matchSorter from "match-sorter";
import SearchField from './SearchField';
import './App.css';
import Child from './Child/Child'
import jsondata from './sample'
// Import React Table
import ReactTable from "react-table";
import "react-table/react-table.css";
class App extends React.Component {
constructor() {
super();
this.state = {
// data: makeData(),
data: jsondata,
dataDefault: jsondata,
basicExampleList: jsondata, // this field is related to search
filtered: [],
select2: null,
select3: null,
childOpen: false
};
this.openChild = this.openChild.bind(this);
this.applyFilter = this.applyFilter.bind(this);
this.showDefaultView = this.showDefaultView.bind(this);
this.onBasicExampleChange = this.onBasicExampleChange.bind(this); // this field is related to search
this.onEnterExample = this.onEnterExample.bind(this); // this field is related to search
this.onSearchClickExample = this.onSearchClickExample.bind(this); // this field is related to search
this.getMatchedList = this.getMatchedList.bind(this); // this field is related to search
}
getMatchedList(searchText) { // this method is related to search
if (TypeChecker.isEmpty(searchText)) return this.state.basicExampleList;
return this.state.basicExampleList.filter(item => item.firstName.includes(searchText) ||
item.firstName.includes(searchText));
};
onBasicExampleChange(value) { // this method is related to search
this.setState({
basicExampleList: this.getMatchedList(value),
});
}
onEnterExample(value) { // this method is related to search
this.setState({
basicExampleList: this.getMatchedList(value),
});
}
onSearchClickExample(value) { // this methods is related to search
this.setState({
basicExampleList: this.getMatchedList(value),
});
}
applyFilter(filtered) {
console.log('Entering Apply Filter Function of Parent');
console.log('The filtered data in parent ' + JSON.stringify(filtered));
const currentStateChild = this.state.childOpen;
this.setState({
childOpen: !currentStateChild
}, () => {
console.log('Child is opened ' + this.state.childOpen);
});
const filterArray = filtered;
const apidata = this.state.data;
let filteredData = apidata.filter(item => // filter jsondata
filterArray.every( f => // so every member of filter array
f.value.includes(item[f.id])) ) // has a corresponding item[id] in value
console.log('The filtered rows are ' + JSON.stringify(filteredData));
this.setState({
data: filteredData
}, () => {
console.log('Manipulated rows ' + this.state.data);
});
}
openChild() {
const currentStateChild = this.state.childOpen;
this.setState({
childOpen: !currentStateChild
}, () => {
console.log('Child is opened ' + this.state.childOpen);
});
}
showDefaultView() {
const defaultDataParent = this.state.dataDefault;
this.setState({
data: defaultDataParent
}, () => {
console.log('Default rows ' + this.state.data);
});
}
render() {
const { data } = this.state;
return (
<div>
<div className='clickMeToOpenChild' onClick={this.openChild} > Click Me to Open Child</div>
<div className='clickMeToGetDefaultView' onClick={this.showDefaultView} > Click Me to show Default View</div>
<br />
<SearchField
placeholder="Search item" // this block is related to search
onChange={this.onBasicExampleChange}
onEnter={this.onEnterExample}
onSearchClick={this.onSearchClickExample}
/>
<br />
<br />
<ReactTable
data={data}
filterable
filtered={this.state.filtered}
onFilteredChange={(filtered, column, value) => {
this.onFilteredChangeCustom(value, column.id || column.accessor);
}}
defaultFilterMethod={(filter, row, column) => {
const id = filter.pivotId || filter.id;
if (typeof filter.value === "object") {
return row[id] !== undefined
? filter.value.indexOf(row[id]) > -1
: true;
} else {
return row[id] !== undefined
? String(row[id]).indexOf(filter.value) > -1
: true;
}
}}
columns={[
{
Header: "Name",
columns: [
{
Header: "First Name",
accessor: "firstName"
},
{
Header: "Last Name",
id: "lastName",
accessor: d => d.lastName
}
]
},
{
Header: "Info",
columns: [
{
Header: "Age",
accessor: "age"
},
]
}
]}
defaultPageSize={10}
className="-striped -highlight"
/>
{this.state.childOpen &&
<Child
data={data}
applyFilter={this.applyFilter}
/>}
<br />
</div>
);
}
}
render(<App />, document.getElementById("root"));
这是我的SearchField页面
import React from 'react';
import PropTypes from 'prop-types';
import TypeChecker from 'typeco';
const ENTER_KEY = 13;
const SEARCH_BUTTON_EDGE = 35;
const searchFieldStyle = {
border: '1px #ddd solid',
display: 'inline-flex',
justifyContent: 'space-between',
height: SEARCH_BUTTON_EDGE,
};
const searchFieldButtonStyle = {
height: SEARCH_BUTTON_EDGE - 2, // reduces 2px because of top and bottom border
width: SEARCH_BUTTON_EDGE - 2,
outline: 'none',
backgroundColor: 'white',
cursor: 'pointer',
padding: 5,
boxSizing: 'border-box',
appearance: 'none',
border: 'none',
borderLeft: '1px #ddd solid',
};
const searchFieldInputStyle = {
outline: 'none',
border: 'none',
fontSize: 14,
padding: 10,
flex: 1,
color: '#5a5a5a',
fontWeight: 100,
height: SEARCH_BUTTON_EDGE - 2,
};
const SearchIcon = () => {
const iconEdge = Math.ceil(SEARCH_BUTTON_EDGE * 0.60);
const searchIconStyle = {
fill: '#727272',
};
return (
<svg
version="1.1"
x="0px"
y="0px"
width={iconEdge}
height={iconEdge}
viewBox="0 0 635 635"
style={searchIconStyle}
>
<g>
<path d="M255.108,0C119.863,0,10.204,109.66,10.204,244.904c0,135.245,109.659,244.905,244.904,244.905
c52.006,0,100.238-16.223,139.883-43.854l185.205,185.176c1.671,1.672,4.379,1.672,5.964,0.115l34.892-34.891
c1.613-1.613,1.47-4.379-0.115-5.965L438.151,407.605c38.493-43.246,61.86-100.237,61.86-162.702
C500.012,109.66,390.353,0,255.108,0z M255.108,460.996c-119.34,0-216.092-96.752-216.092-216.092
c0-119.34,96.751-216.091,216.092-216.091s216.091,96.751,216.091,216.091C471.199,364.244,374.448,460.996,255.108,460.996z"
/>
</g>
</svg>
);
};
class SearchField extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.searchText,
};
this.onChangeBound = this.onChangeBound.bind(this);
this.onEnterBound = this.onEnterBound.bind(this);
this.onSearchClick = this.onSearchClick.bind(this);
}
componentWillReceiveProps(nextProps) {
if (this.props.searchText !== nextProps.searchText) {
this.setState({
value: nextProps.searchText,
});
}
}
onChangeBound(event) {
this.setState({
value: event.target.value,
});
if (TypeChecker.isFunction(this.props.onChange)) {
this.props.onChange(event.target.value, event);
}
}
onEnterBound(event) {
const isEnterPressed = event.which === ENTER_KEY || event.keyCode === ENTER_KEY;
if (isEnterPressed && TypeChecker.isFunction(this.props.onEnter)) {
this.props.onEnter(event.target.value, event);
}
}
onSearchClick() {
if (TypeChecker.isFunction(this.props.onSearchClick)) {
this.props.onSearchClick(this.state.value);
}
}
render() {
const {
classNames,
placeholder,
} = this.props;
const className = `react-search-field ${classNames}`;
return (
<div
className={className}
style={searchFieldStyle}
>
<input
className="react-search-field-input"
style={searchFieldInputStyle}
onChange={this.onChangeBound}
onKeyPress={this.onEnterBound}
placeholder={placeholder}
type="text"
value={this.state.value}
/>
<button
className="react-search-field-button"
type="button"
style={searchFieldButtonStyle}
onClick={this.onSearchClick}
>
<SearchIcon />
</button>
</div>
);
}
}
SearchField.propTypes = {
classNames: PropTypes.string,
searchText: PropTypes.string,
placeholder: PropTypes.string,
onChange: PropTypes.func,
onEnter: PropTypes.func,
onSearchClick: PropTypes.func,
};
SearchField.defaultProps = {
classNames: '',
searchText: '',
placeholder: 'Search',
onChange: null,
onEnter: null,
onSearchClick: null,
};
export default SearchField;
这是用于填充行的json对象数据文件
const jsonData = [
{
firstName: "Sam",
lastName: "Jones",
age: "10"
},
{
firstName: "Sam",
lastName: "Jones1",
age: "10"
},
{
firstName: "Sam2",
lastName: "Jones1",
age: "12"
},
{
firstName: "Sam3",
lastName: "Jones3",
age: "13"
},
{
firstName: "Sam4",
lastName: "Jones4",
age: "14"
},
{
firstName: "Sam5",
lastName: "Jones5",
age: "15"
},
{
firstName: "Sam",
lastName: "Jones11",
age: "16"
},
{
firstName: "Sam6",
lastName: "Jones6",
age: "17"
},
{
firstName: "Sam7",
lastName: "Jones7",
age: "18"
},
{
firstName: "Sam8",
lastName: "Jones8",
age: "19"
},
{
firstName: "Sam9",
lastName: "Jones9",
age: "20"
},
{
firstName: "Sam10",
lastName: "Jones10",
age: "21"
},
{
firstName: "Sam11",
lastName: "Jones11",
age: "22"
},
{
firstName: "Sam12",
lastName: "Jones12",
age: "23"
}
];
export default jsonData;
我没有发布CSS,如果您想看到的话,请参阅Demo。我的搜索框未在搜索和过滤值。请帮助。