Reputation: 41
I have a forms with 3 select dropdowns that filter an array based on a selected value. Rather than having an onChange handler for each of these forms I was wondering if I could use a single function too handle all of them based on a parameter.
I tried passing a string into the function but it doesn't work since it is expecting an event to be passed as a parameter.
Here is the code for the react form:
const UserSearchBox = ({ handleChange, handleLocationChange, handleTeamChange, handleClientChange }) => {
return (
<form className="user-search">
<input className="user-input" placeholder="Search for Peeps" name="userSearch" onChange={handleChange} />
<div>
<select defaultValue="all" onChange={handleLocationChange}>
<option value="all">All</option>
<option value="boston">Boston</option>
<option value="chicago">Chicago</option>
<option value="tampa">Tampa</option>
</select>
<select defaultValue="all" onChange={handleTeamChange}>
<option value="all">All</option>
<option value="design">Design</option>
<option value="engineering">Engineering</option>
<option value="finance">Finance</option>
</select>
<select defaultValue="all" onChange={handleClientChange}>
<option value="all">All</option>
<option value="company">Company1</option>
<option value="company2">Company2</option>
<option value="company3">Company3</option>
</select>
</div>
</form>
)
}
And this is the code for the App:
const handleInputChange = (e) => {
e.preventDefault();
let searchTerm = e.target.value;
if(searchTerm){
let filteredUsers = users.filter((x) => x.name.toLowerCase().includes(searchTerm.toLowerCase()))
setUsers(filteredUsers)
} else{
setUsers(allUsers)
}
}
const handleLocationChange = (e) => {
e.preventDefault();
let searchTerm = e.target.value;
if(searchTerm !== "all"){
let filteredUsers = allUsers.filter((x) => x.location.toLowerCase().includes(searchTerm.toLowerCase()))
setUsers(filteredUsers)
} else{
setUsers(allUsers)
}
}
return (
<div className="container-fluid">
<Header name={loggedInUser.name} profile_photo={loggedInUser.profile_photo} />
<UserSearchBox handleLocationChange={handleLocationChange} handleChange={handleInputChange}/>
<Users users={users} />
</div>
)
Upvotes: 0
Views: 578
Reputation: 41
Another potential solution, however I believe @Darkbound had a more precise method.
Add data attributes to the options:
<select defaultValue="all" onChange={handleSelectChange}>
<option data-filter-type="location" value="all">All</option>
<option data-filter-type="location" value="boston">Boston</option>
<option data-filter-type="location" value="chicago">Chicago</option>
<option data-filter-type="location" value="tampa">Tampa</option>
</select>
Then use a switch statement:
if (searchTerm !== "all") {
switch (attr) {
case 'location':
setUsers(users.filter((x) => x.location.toLowerCase().includes(searchTerm.toLowerCase())));
break;
case 'team':
console.log('term: ', searchTerm);
setUsers(users.filter((x) => x.team.toLowerCase().includes(searchTerm.toLowerCase())));
break;
case 'client':
setUsers(users.filter((x) => x.client.toLowerCase().includes(searchTerm.toLowerCase())));
break;
default:
setUsers(allUsers)
}
} else {
setUsers(allUsers)
}
Upvotes: 0
Reputation: 3434
You can pass additional parameters with the event by changing the onChange to this:
onChange={(e) => { handleLocationChange(e, param1, param2, param3...) }}
Or if you dont need the event you can skip it:
onChange{() => { handleLocationChange(param1, param2, param3...) }}
That way you still get your event inside, and then you add whatever other arguments you want.
Would that help you?
Upvotes: 1