在 React 中搜索和排序 table
Searching and sorting in react table
我尝试在 table 中实现搜索和排序功能。我的搜索功能运行良好。但是,当我尝试将排序功能添加到 table 中时,整个功能就会融合在一起。对于搜索,我使用搜索文本框,而对于排序,我使用 select 下拉列表。根据保存在 JSON 文件中的 "answerStatus" 键进行排序。
实时代码示例(https://x1juu.csb.app/)。 CSS 不包括在内。
这是我的 table 组件代码
import InquiresList from '../dashboard/inquiries/InquiriesList.json';
class Inquiry extends React.Component{
constructor(props)
{
super(props);
this.state={
searchInquiries:null,
answerStatus:'all'
}
}
handleSearch=(event) =>
{
this.setState({searchInquiries:event.target.value});
}
handleAnswer=(event) =>
{
this.setState({answerStatus:event.target.value});
}
render()
{
const inquiries = InquiresList.filter((data)=>{
if(this.state.searchInquiries == null)
{
return data;
}
else if(data.user_code.toLowerCase().includes(this.state.searchInquiries.toLowerCase())){
if(this.state.answerStatus === 'all')
{
return data;
}
else{
if(this.state.answerStatus === data.answerStatus)
{
return data;
}
}
}
return null;
})
return(
<div className="col-md-12 bg-gray" style={{padding:'30px'}}>
<div className="row" style={row}>
<h3 className="roboto paragraph mgb-30">Inquiries List</h3>
</div>
<div className="row border-radius-10 default-shadow" style={row}>
<div className="col-md-12 bg-white border-radius-10" style={padding}>
<div className="row">
<div className="col-md-6 flex all-center">
<i className="i fa fa-search table-search-icon"></i>
<input type="text" onChange={this.handleSearch} className="form-control" style={{borderRadius:'30px'}} placeholder="Search" />
</div>
<div className="col-md-6 flex flex-end" style={row}>
<select name="inquiry-filter" onChange={this.handleAnswer} className="inquiry-filter">
<option value="all">All</option>
<option value="answered">Answered</option>
<option value="unanswered">Unanswered</option>
</select>
</div>
</div>
</div>
<div className="col-md-12 bg-white" style={{padding:'0px'}}>
<table className="table table-striped table-hover table-bordered">
<thead>
<tr>
<td><p className="paragraph" style={marginBottom}>Created</p></td>
<td><p className="paragraph" style={marginBottom}>User Code</p></td>
<td><p className="paragraph" style={marginBottom}>Email</p></td>
<td><p className="paragraph" style={marginBottom}>Subject</p></td>
<td><p className="paragraph" style={marginBottom}>Answer</p></td>
</tr>
</thead>
<tbody>
{
inquiries.map(inquiry =>(
<tr>
<td>
<h3 className="paragraph">{inquiry.created_date}</h3>
</td>
<td>
<h3 className="paragraph" style={marginBottom}>{inquiry.user_code}</h3>
</td>
<td>
<p className="paragraph" style={marginBottom}>{inquiry.email}</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>{inquiry.subject}</p>
</td>
<td>
<div className="custom-control custom-checkbox">
{
inquiry.answered ? <input type="checkbox" checked className="custom-control-input" id={"answer-status-"+inquiry.id} name={"answer-status-"+inquiry.id} />
: <input type="checkbox" className="custom-control-input" id={"answer-status-"+inquiry.id} name={"answer-status-"+inquiry.id} />
}
<label className="custom-control-label" for={"answer-status-"+inquiry.id}></label>
</div>
</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
</div>
)
}
}
export default Inquiry;
请帮忙。
你可以这样试试
import InquiresList from '../dashboard/inquiries/InquiriesList.json';
export default class index extends Component {
constructor(props) {
super(props);
this.state = {
searchInquiries: null,
answerStatus: "all",
inquiries: InquiresList,
copyInquiries: InquiresList,
};
}
onSearchHandler = (value) => {
const searchResult = this.state.copyInquiries
.filter(function (item) {
const itemData = item.user_code.toLowerCase();
const textData = value.toLowerCase();
return itemData.indexOf(textData) > -1;
})
.sort((a, b) => a.answerStatus - b.answerStatus);
this.setState({ searchInquiries: value, inquiries: searchResult });
};
render() {
return (
<div className="col-md-12 bg-gray" style={{ padding: "30px" }}>
<div className="row" style={row}>
<h3 className="roboto paragraph mgb-30">Inquiries List</h3>
</div>
<div className="row border-radius-10 default-shadow" style={row}>
<div className="col-md-12 bg-white border-radius-10" style={padding}>
<div className="row">
<div className="col-md-6 flex all-center">
<i className="i fa fa-search table-search-icon"></i>
<input
type="text"
onChange={this.handleSearch}
className="form-control"
style={{ borderRadius: "30px" }}
placeholder="Search"
/>
</div>
<div className="col-md-6 flex flex-end" style={row}>
<select
name="inquiry-filter"
onChange={this.handleAnswer}
className="inquiry-filter"
>
<option value="all">All</option>
<option value="answered">Answered</option>
<option value="unanswered">Unanswered</option>
</select>
</div>
</div>
</div>
<div className="col-md-12 bg-white" style={{ padding: "0px" }}>
<table className="table table-striped table-hover table-bordered">
<thead>
<tr>
<td>
<p className="paragraph" style={marginBottom}>
Created
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
User Code
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
Email
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
Subject
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
Answer
</p>
</td>
</tr>
</thead>
<tbody>
{inquiries.map((inquiry) => (
<tr>
<td>
<h3 className="paragraph">{inquiry.created_date}</h3>
</td>
<td>
<h3 className="paragraph" style={marginBottom}>
{inquiry.user_code}
</h3>
</td>
<td>
<p className="paragraph" style={marginBottom}>
{inquiry.email}
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
{inquiry.subject}
</p>
</td>
<td>
<div className="custom-control custom-checkbox">
{inquiry.answered ? (
<input
type="checkbox"
checked
className="custom-control-input"
id={"answer-status-" + inquiry.id}
name={"answer-status-" + inquiry.id}
/>
) : (
<input
type="checkbox"
className="custom-control-input"
id={"answer-status-" + inquiry.id}
name={"answer-status-" + inquiry.id}
/>
)}
<label
className="custom-control-label"
for={"answer-status-" + inquiry.id}
></label>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
}
这是工作代码片段,我尽可能少地修改代码以使搜索和排序在您的 App.js
上协同工作。
import React from 'react';
import InquiresList from './InquiryList.json';
class Inquiry extends React.Component {
constructor(props) {
super(props);
this.state = {
searchInquiries: null,
answerStatus: 'all',
data: InquiresList,
};
}
handleSearch = (event) => {
this.setState({ searchInquiries: event.target.value });
};
handleAnswer = (event) => {
this.setState({ answerStatus: event.target.value });
};
render() {
const padding = {
padding: '20px',
};
const marginBottom = {
marginBottom: '0px',
};
const row = {
margin: '0px',
};
let inquiries = InquiresList.filter((data) => {
if (this.state.searchInquiries !== null) {
return data.user_code
.toLowerCase()
.includes(this.state.searchInquiries.toLowerCase());
}
return data;
});
if (this.state.answerStatus === 'answered') {
inquiries.sort((a, b) => {
if (a.answered < b.answered) return -1;
if (a.answered > b.answered) return 1;
return 0;
});
} else if (this.state.answerStatus === 'unanswered') {
inquiries.sort((a, b) => {
if (a.answered > b.answered) return -1;
if (a.answered < b.answered) return 1;
return 0;
});
}
return (
<div className='col-md-12 bg-gray' style={{ padding: '30px' }}>
<div className='row' style={row}>
<h3 className='roboto paragraph mgb-30'>Inquiries List</h3>
</div>
<div className='row border-radius-10 default-shadow' style={row}>
<div className='col-md-12 bg-white border-radius-10' style={padding}>
<div className='row'>
<div className='col-md-6 flex all-center'>
<i className='i fa fa-search table-search-icon' />
<input
type='text'
onChange={this.handleSearch}
className='form-control'
style={{ borderRadius: '30px' }}
placeholder='Search'
/>
</div>
<div className='col-md-6 flex flex-end' style={row}>
<select
name='inquiry-filter'
onChange={this.handleAnswer}
className='inquiry-filter'
>
<option value='all'>All</option>
<option value='answered'>Answered</option>
<option value='unanswered'>Unanswered</option>
</select>
</div>
</div>
</div>
<div className='col-md-12 bg-white' style={{ padding: '0px' }}>
<table className='table table-striped table-hover table-bordered'>
<thead>
<tr>
<td>
<p className='paragraph' style={marginBottom}>
Created
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
User Code
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
Email
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
Subject
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
Answer
</p>
</td>
</tr>
</thead>
<tbody>
{inquiries.map((inquiry) => (
<tr>
<td>
<h3 className='paragraph'>{inquiry.created_date}</h3>
</td>
<td>
<h3 className='paragraph' style={marginBottom}>
{inquiry.user_code}
</h3>
</td>
<td>
<p className='paragraph' style={marginBottom}>
{inquiry.email}
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
{inquiry.subject}
</p>
</td>
<td>
<div className='custom-control custom-checkbox'>
{inquiry.answered ? (
<input
type='checkbox'
checked
className='custom-control-input'
id={'answer-status-' + inquiry.id}
name={'answer-status-' + inquiry.id}
/>
) : (
<input
type='checkbox'
className='custom-control-input'
id={'answer-status-' + inquiry.id}
name={'answer-status-' + inquiry.id}
/>
)}
<label
className='custom-control-label'
for={'answer-status-' + inquiry.id}
/>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className='col-md-12 bg-white flex flex-end' style={padding}>
<ul
className='list list-inline pagination-list'
style={marginBottom}
>
<li className='list-inline-item'>
<button
type='button'
className='color-golden bg-white'
style={{
border: 'none',
boxShadow: '0px 0px 0px #ffff',
borderRight: '1px solid #d3d3d3',
}}
>
Previous
</button>
</li>
<li className='list-inline-item active bg-golden number-container'>
1
</li>
<li className='list-inline-item number-container'>2</li>
<li className='list-inline-item number-container'>3</li>
<li className='list-inline-item number-container'>4</li>
<li className='list-inline-item'>
<button
type='button'
className='color-golden bg-white'
style={{
border: 'none',
boxShadow: '0px 0px 0px #ffff',
borderLeft: '1px solid #d3d3d3',
}}
>
Next
</button>
</li>
</ul>
</div>
</div>
</div>
);
}
}
export default Inquiry;
我尝试在 table 中实现搜索和排序功能。我的搜索功能运行良好。但是,当我尝试将排序功能添加到 table 中时,整个功能就会融合在一起。对于搜索,我使用搜索文本框,而对于排序,我使用 select 下拉列表。根据保存在 JSON 文件中的 "answerStatus" 键进行排序。
实时代码示例(https://x1juu.csb.app/)。 CSS 不包括在内。
这是我的 table 组件代码
import InquiresList from '../dashboard/inquiries/InquiriesList.json';
class Inquiry extends React.Component{
constructor(props)
{
super(props);
this.state={
searchInquiries:null,
answerStatus:'all'
}
}
handleSearch=(event) =>
{
this.setState({searchInquiries:event.target.value});
}
handleAnswer=(event) =>
{
this.setState({answerStatus:event.target.value});
}
render()
{
const inquiries = InquiresList.filter((data)=>{
if(this.state.searchInquiries == null)
{
return data;
}
else if(data.user_code.toLowerCase().includes(this.state.searchInquiries.toLowerCase())){
if(this.state.answerStatus === 'all')
{
return data;
}
else{
if(this.state.answerStatus === data.answerStatus)
{
return data;
}
}
}
return null;
})
return(
<div className="col-md-12 bg-gray" style={{padding:'30px'}}>
<div className="row" style={row}>
<h3 className="roboto paragraph mgb-30">Inquiries List</h3>
</div>
<div className="row border-radius-10 default-shadow" style={row}>
<div className="col-md-12 bg-white border-radius-10" style={padding}>
<div className="row">
<div className="col-md-6 flex all-center">
<i className="i fa fa-search table-search-icon"></i>
<input type="text" onChange={this.handleSearch} className="form-control" style={{borderRadius:'30px'}} placeholder="Search" />
</div>
<div className="col-md-6 flex flex-end" style={row}>
<select name="inquiry-filter" onChange={this.handleAnswer} className="inquiry-filter">
<option value="all">All</option>
<option value="answered">Answered</option>
<option value="unanswered">Unanswered</option>
</select>
</div>
</div>
</div>
<div className="col-md-12 bg-white" style={{padding:'0px'}}>
<table className="table table-striped table-hover table-bordered">
<thead>
<tr>
<td><p className="paragraph" style={marginBottom}>Created</p></td>
<td><p className="paragraph" style={marginBottom}>User Code</p></td>
<td><p className="paragraph" style={marginBottom}>Email</p></td>
<td><p className="paragraph" style={marginBottom}>Subject</p></td>
<td><p className="paragraph" style={marginBottom}>Answer</p></td>
</tr>
</thead>
<tbody>
{
inquiries.map(inquiry =>(
<tr>
<td>
<h3 className="paragraph">{inquiry.created_date}</h3>
</td>
<td>
<h3 className="paragraph" style={marginBottom}>{inquiry.user_code}</h3>
</td>
<td>
<p className="paragraph" style={marginBottom}>{inquiry.email}</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>{inquiry.subject}</p>
</td>
<td>
<div className="custom-control custom-checkbox">
{
inquiry.answered ? <input type="checkbox" checked className="custom-control-input" id={"answer-status-"+inquiry.id} name={"answer-status-"+inquiry.id} />
: <input type="checkbox" className="custom-control-input" id={"answer-status-"+inquiry.id} name={"answer-status-"+inquiry.id} />
}
<label className="custom-control-label" for={"answer-status-"+inquiry.id}></label>
</div>
</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
</div>
)
}
}
export default Inquiry;
请帮忙。
你可以这样试试
import InquiresList from '../dashboard/inquiries/InquiriesList.json';
export default class index extends Component {
constructor(props) {
super(props);
this.state = {
searchInquiries: null,
answerStatus: "all",
inquiries: InquiresList,
copyInquiries: InquiresList,
};
}
onSearchHandler = (value) => {
const searchResult = this.state.copyInquiries
.filter(function (item) {
const itemData = item.user_code.toLowerCase();
const textData = value.toLowerCase();
return itemData.indexOf(textData) > -1;
})
.sort((a, b) => a.answerStatus - b.answerStatus);
this.setState({ searchInquiries: value, inquiries: searchResult });
};
render() {
return (
<div className="col-md-12 bg-gray" style={{ padding: "30px" }}>
<div className="row" style={row}>
<h3 className="roboto paragraph mgb-30">Inquiries List</h3>
</div>
<div className="row border-radius-10 default-shadow" style={row}>
<div className="col-md-12 bg-white border-radius-10" style={padding}>
<div className="row">
<div className="col-md-6 flex all-center">
<i className="i fa fa-search table-search-icon"></i>
<input
type="text"
onChange={this.handleSearch}
className="form-control"
style={{ borderRadius: "30px" }}
placeholder="Search"
/>
</div>
<div className="col-md-6 flex flex-end" style={row}>
<select
name="inquiry-filter"
onChange={this.handleAnswer}
className="inquiry-filter"
>
<option value="all">All</option>
<option value="answered">Answered</option>
<option value="unanswered">Unanswered</option>
</select>
</div>
</div>
</div>
<div className="col-md-12 bg-white" style={{ padding: "0px" }}>
<table className="table table-striped table-hover table-bordered">
<thead>
<tr>
<td>
<p className="paragraph" style={marginBottom}>
Created
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
User Code
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
Email
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
Subject
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
Answer
</p>
</td>
</tr>
</thead>
<tbody>
{inquiries.map((inquiry) => (
<tr>
<td>
<h3 className="paragraph">{inquiry.created_date}</h3>
</td>
<td>
<h3 className="paragraph" style={marginBottom}>
{inquiry.user_code}
</h3>
</td>
<td>
<p className="paragraph" style={marginBottom}>
{inquiry.email}
</p>
</td>
<td>
<p className="paragraph" style={marginBottom}>
{inquiry.subject}
</p>
</td>
<td>
<div className="custom-control custom-checkbox">
{inquiry.answered ? (
<input
type="checkbox"
checked
className="custom-control-input"
id={"answer-status-" + inquiry.id}
name={"answer-status-" + inquiry.id}
/>
) : (
<input
type="checkbox"
className="custom-control-input"
id={"answer-status-" + inquiry.id}
name={"answer-status-" + inquiry.id}
/>
)}
<label
className="custom-control-label"
for={"answer-status-" + inquiry.id}
></label>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
}
这是工作代码片段,我尽可能少地修改代码以使搜索和排序在您的 App.js
上协同工作。
import React from 'react';
import InquiresList from './InquiryList.json';
class Inquiry extends React.Component {
constructor(props) {
super(props);
this.state = {
searchInquiries: null,
answerStatus: 'all',
data: InquiresList,
};
}
handleSearch = (event) => {
this.setState({ searchInquiries: event.target.value });
};
handleAnswer = (event) => {
this.setState({ answerStatus: event.target.value });
};
render() {
const padding = {
padding: '20px',
};
const marginBottom = {
marginBottom: '0px',
};
const row = {
margin: '0px',
};
let inquiries = InquiresList.filter((data) => {
if (this.state.searchInquiries !== null) {
return data.user_code
.toLowerCase()
.includes(this.state.searchInquiries.toLowerCase());
}
return data;
});
if (this.state.answerStatus === 'answered') {
inquiries.sort((a, b) => {
if (a.answered < b.answered) return -1;
if (a.answered > b.answered) return 1;
return 0;
});
} else if (this.state.answerStatus === 'unanswered') {
inquiries.sort((a, b) => {
if (a.answered > b.answered) return -1;
if (a.answered < b.answered) return 1;
return 0;
});
}
return (
<div className='col-md-12 bg-gray' style={{ padding: '30px' }}>
<div className='row' style={row}>
<h3 className='roboto paragraph mgb-30'>Inquiries List</h3>
</div>
<div className='row border-radius-10 default-shadow' style={row}>
<div className='col-md-12 bg-white border-radius-10' style={padding}>
<div className='row'>
<div className='col-md-6 flex all-center'>
<i className='i fa fa-search table-search-icon' />
<input
type='text'
onChange={this.handleSearch}
className='form-control'
style={{ borderRadius: '30px' }}
placeholder='Search'
/>
</div>
<div className='col-md-6 flex flex-end' style={row}>
<select
name='inquiry-filter'
onChange={this.handleAnswer}
className='inquiry-filter'
>
<option value='all'>All</option>
<option value='answered'>Answered</option>
<option value='unanswered'>Unanswered</option>
</select>
</div>
</div>
</div>
<div className='col-md-12 bg-white' style={{ padding: '0px' }}>
<table className='table table-striped table-hover table-bordered'>
<thead>
<tr>
<td>
<p className='paragraph' style={marginBottom}>
Created
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
User Code
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
Email
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
Subject
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
Answer
</p>
</td>
</tr>
</thead>
<tbody>
{inquiries.map((inquiry) => (
<tr>
<td>
<h3 className='paragraph'>{inquiry.created_date}</h3>
</td>
<td>
<h3 className='paragraph' style={marginBottom}>
{inquiry.user_code}
</h3>
</td>
<td>
<p className='paragraph' style={marginBottom}>
{inquiry.email}
</p>
</td>
<td>
<p className='paragraph' style={marginBottom}>
{inquiry.subject}
</p>
</td>
<td>
<div className='custom-control custom-checkbox'>
{inquiry.answered ? (
<input
type='checkbox'
checked
className='custom-control-input'
id={'answer-status-' + inquiry.id}
name={'answer-status-' + inquiry.id}
/>
) : (
<input
type='checkbox'
className='custom-control-input'
id={'answer-status-' + inquiry.id}
name={'answer-status-' + inquiry.id}
/>
)}
<label
className='custom-control-label'
for={'answer-status-' + inquiry.id}
/>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className='col-md-12 bg-white flex flex-end' style={padding}>
<ul
className='list list-inline pagination-list'
style={marginBottom}
>
<li className='list-inline-item'>
<button
type='button'
className='color-golden bg-white'
style={{
border: 'none',
boxShadow: '0px 0px 0px #ffff',
borderRight: '1px solid #d3d3d3',
}}
>
Previous
</button>
</li>
<li className='list-inline-item active bg-golden number-container'>
1
</li>
<li className='list-inline-item number-container'>2</li>
<li className='list-inline-item number-container'>3</li>
<li className='list-inline-item number-container'>4</li>
<li className='list-inline-item'>
<button
type='button'
className='color-golden bg-white'
style={{
border: 'none',
boxShadow: '0px 0px 0px #ffff',
borderLeft: '1px solid #d3d3d3',
}}
>
Next
</button>
</li>
</ul>
</div>
</div>
</div>
);
}
}
export default Inquiry;