Reputation: 1103
I'm still new in React. I get some data from a JSON file. I managed to get the search to work. But I also want to be able to click my name table header and filter my data by name. How do I make that work with filter.
import React, { PropTypes } from 'react';
// Mock Data
let MockData = require('./generated.json');
let searchValue = '';
export default class Employees extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
searchValue: '',
sortValue: null
};
this.searchInputChange = this.searchInputChange.bind(this);
this.searchSubmit = this.searchSubmit.bind(this);
}
// Sort function
sortFunction(sortValue, event) {
alert(sortValue);
this.setState({sortValue: sortValue});
}
// Update search value state function
searchInputChange(event) {
this.searchValue = event.target.value;
}
// Search function
searchSubmit(event) {
this.setState({searchValue: this.searchValue});
}
render() {
let sortedEmployeesBySearch = MockData.filter(
(employee) => {
// If state searchValue is not null
if (this.state.searchValue) {
return employee.name.indexOf(this.state.searchValue) !== -1 || employee.gender.indexOf(this.state.searchValue) !== -1 || employee.company.indexOf(this.state.searchValue) !== -1 || employee.email.indexOf(this.state.searchValue) !== -1;
}
else {
return employee;
}
}
);
return (
<div className="container">
<input className="search" type="text" name="search" placeholder="Search table" onChange={this.searchInputChange} />
<input className="searchButton" type="button" value="Search" onClick={this.searchSubmit} />
<table className="employeesList">
<thead>
<tr>
<th onClick={this.sortFunction.bind(this,'name')}>Name</th>
<th onClick={this.sortFunction.bind(this,'gender')}>Gender</th>
<th onClick={this.sortFunction.bind(this,'company')}>Company</th>
<th onClick={this.sortFunction.bind(this,'email')}>E-mail</th>
</tr>
</thead>
<tbody>
{ sortedEmployeesBySearch.map((employee) => (
<tr key={employee.id}>
<td>{employee.name}</td>
<td>{employee.gender}</td>
<td>{employee.company}</td>
<td>{employee.email}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
Upvotes: 1
Views: 5815
Reputation: 181
You can sort the data by: 1) Storing in state the property to sort on, which you are already doing 2) Chaining a sort function after the filter of your MockData
The second task can be accomplished by:
MockData.filter(...).sort((a, b) => {
aVal = a[this.state.sortValue];
bVal = b[this.state.sortValue];
switch(typeof aVal) {
case 'string':
return aVal.localeCompare(bVal);
case 'number':
return aVal - bVal;
default:
throw new Error("Unsupported value to sort by");
}
});
You can even pass a custom function into the sort method that takes the two values and does custom sorting logic based on the sortValue property.
Upvotes: 3