[英]How to to filter the same data with 2 search bars - ReactJS
I want some help here.我在这里需要一些帮助。 I want to filter the same data with 2 search bars, one to filter the names and the other one to filter the array of notes.我想用 2 个搜索栏过滤相同的数据,一个用于过滤名称,另一个用于过滤笔记数组。
IF: I am only filtering by names => get Results (length > 0) OR length = 0.如果:我只按名称过滤 => 获取结果(长度 > 0)或长度 = 0。
ELSE IF: I am only filtering by names => get Results (length > 0) OR length = 0. ELSE IF:我只按名称过滤 => 获取结果(长度 > 0)或长度 = 0。
ELSE IF: I am filtering by both of them names & notes => get Results (length > 0) OR length = 0. ELSE IF:我正在按他们两个名称和注释进行过滤 => 得到结果(长度 > 0)或长度 = 0。
ELSE: Do nothing.其他:什么都不做。
The interface looks like this:界面如下所示:
interface StudentInterface {
email: string;
firstName: string;
notes: string [];
id: string;
lastName: string;
}
Below is the screen-shot of the 2 search bars.以下是 2 个搜索栏的屏幕截图。
Any help is appreciated.任何帮助表示赞赏。 Thanks in advance.提前致谢。
Here's an example of how to utilize client-side dual filters:以下是如何使用客户端双重过滤器的示例:
Code (with notes):代码(带注释):
App.tsx应用程序.tsx
import { ChangeEvent, FormEvent, ReactElement, useState } from "react";
import { studentData, Student } from "./studentsData";
import "./styles.css";
type Filters = {
name: string;
note: string;
};
const initialFilters = {
name: "",
note: ""
};
export default function App(): ReactElement {
const [students, setStudents] = useState<Array<Student>>(studentData);
const [filters, setFilters] = useState<Filters>(initialFilters);
const { name, note } = filters;
// on input change, update the corresponding field (event.target.name) with the field's value (event.target.value)
const handleFilterChange = (event: ChangeEvent<HTMLInputElement>): void => {
setFilters((prevState) => ({
...prevState,
[event.target.name]: event.target.value
}));
};
// on form reset, reset field filters and students state
const handleResetFilters = (): void => {
setFilters(initialFilters);
setStudents(studentData);
};
// on form submit, filter data according to field filters values
const handleSubmit = (event: FormEvent): void => {
event.preventDefault();
// prevent an empty form from filtering data
if (!name && !note) {
alert("Please fill out at least one filter before submitting the form!");
return;
}
const filteredStudents = studentData.filter((student) => {
// combine the student's first and last name
// and check if the student's name contains the "name" filter value
const containsStudentName = `${student.firstName} ${student.lastName}`
.toLowerCase()
.includes(name.toLowerCase());
// check if the student's notes contain a partial match to the "note" filter value
const containsStudentNote = student.notes.some(
(studentNote) => studentNote.indexOf(note) > 0
);
// true = keep, false = discard
if (name && note) {
// if name and note filters are used, return the result of the above boolean values
return containsStudentName && containsStudentNote;
} else if (
(name && containsStudentName) ||
(note && containsStudentNote)
) {
// else if name and containsStudentName are a match or if note and containsStudentNote are a match, keep record
return true;
} else {
// else, discard record
return false;
}
});
setStudents(filteredStudents);
};
return (
<main className="app">
<h1>Filter Student Form</h1>
<form onSubmit={handleSubmit}>
<input
className="filter"
name="name"
onChange={handleFilterChange}
placeholder="Filter by student name..."
value={name}
/>
<input
className="filter"
name="note"
onChange={handleFilterChange}
placeholder="Filter by student note..."
value={note}
/>
<div className="btn-container">
<button
className="btn btn-danger"
type="button"
onClick={handleResetFilters}
>
Reset
</button>
<button className="btn btn-primary" type="submit">
Submit
</button>
</div>
</form>
<h1>Student List</h1>
{students.length > 0 ? (
students.map(({ id, email, firstName, lastName, notes }) => (
<div className="card" key={id}>
<h3>
{firstName} {lastName} ({email})
</h3>
<p>{notes.join(", ")}</p>
</div>
))
) : (
<div>No results were found matching those filters...</div>
)}
</main>
);
}
studentsData.ts学生数据.ts
export type Student = {
email: string;
firstName: string;
notes: string[];
id: string;
lastName: string;
};
export const studentData: Array<Student> = [
{
id: "1",
email: "ervinh@hotmail.com",
firstName: "Ervin",
lastName: "Howell",
notes: [
"I manage enterprise e-tailers",
"I aggregate real-time technologies"
]
},
{
id: "2",
email: "patricia@kory.org",
firstName: "Patricia",
lastName: "Lebsack",
notes: ["I revolutionize enterprise end-to-end systems"]
},
{
id: "3",
email: "lg@gmail.com",
firstName: "Leanne",
lastName: "Graham",
notes: ["I transition cutting-edge web services"]
},
{
id: "4",
email: "denSchu@jasper.info",
firstName: "Dennis",
lastName: "Schulist",
notes: ["I synergize scalable supply-chains"]
},
{
id: "5",
email: "kw@aol.com",
firstName: "Kurtis",
lastName: "Weissnat",
notes: ["I enable strategic applications"]
},
{
id: "6",
email: "patricia@patriciareichert.com",
firstName: "Patricia",
lastName: "Reichert",
notes: ["I target end-to-end models"]
}
];
index.tsx索引.tsx
import { render } from "react-dom";
import App from "./App";
render(<App />, document.getElementById("root"));
styles.css styles.css
body,
html {
height: 100vh;
width: 100%;
margin: 0;
padding: 0;
-ms-overflow-style: none;
scrollbar-width: none;
}
::-webkit-scrollbar {
display: none;
}
.app {
font-family: sans-serif;
text-align: center;
margin: 0 auto;
width: 600px;
padding: 20px;
}
.filter {
width: 100%;
height: 40px;
padding: 0 10px;
background: #fff;
color: #666;
border: 1px solid #e5e5e5;
transition: all 0.2s ease-in-out;
margin: 5px 0;
}
.btn {
cursor: pointer;
margin-right: 20px;
border: 1px solid transparent;
text-transform: none;
border-radius: 4px;
display: inline-block;
padding: 0 30px;
font-size: 14px;
line-height: 38px;
text-align: center;
text-transform: uppercase;
transition: all 0.2s ease-in-out;
}
.btn-container {
margin: 20px 0;
}
.btn-primary {
background-color: #1e87f0;
color: #fff;
}
.btn-primary:hover {
background-color: #0f7ae5;
}
.btn-danger {
background-color: #f0506e;
color: #fff;
}
.btn-danger:hover {
background-color: #ee395b;
}
.card {
background-color: rgb(255, 255, 255);
padding: 10px;
margin: 10px;
color: rgb(18, 18, 18);
transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
border-radius: 4px;
box-shadow: rgba(0, 0, 0, 0.2) 0px 3px 3px -2px,
rgba(0, 0, 0, 0.14) 0px 3px 4px 0px, rgba(0, 0, 0, 0.12) 0px 1px 8px 0px;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.