Reputation: 543
I am trying to build a search and sorting functionality for the table content. I don't want to use package as I am trying to learn and see how the react search work. I have the following that loads the content from payloads
import React, {useState, useEffect} from 'react'
import '../css/about.css';
import Pagination from '../components/Pagination'
function About() {
const [userData, setUserData] = useState([]);
const [loading , setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage, setPostsPerPage] = useState(5);
const [search, setSearch] = useState("");
async function getData()
{
let response = await fetch('https://api.github.com/users');
let data = await response.json();
// setUserData(data)
return data;
}
//call getData function
getData()
.then(data => console.log(data)
);//
useEffect(() => {
setLoading(true)
getData()
.then(
data => {
setUserData(data) }
)
.catch(error => {
console.log(error);
})
}, [])
// Get current posts
const indexOfLastPost = currentPage * postsPerPage;
const indexOfFirstPost = indexOfLastPost - postsPerPage;
const currentPosts = userData.slice(indexOfFirstPost, indexOfLastPost);
// changw page
const paginate = (pageNumber) => setCurrentPage(pageNumber);
// Search Table
const handleFilterChange = e => {
const value = e.target.value || undefined;
if( search !== "" && userData.login.indexOf(search.toLowerCase()) === -1 ) {
return null;
}
setSearch(value)
}
return (
<div className="container">
<div>
<input value={search}
onChange={handleFilterChange}
placeholder={"Search"}
/>
<table>
<thead>
<tr>
<td>id</td>
<td>avatar_url</td>
<td>events_url</td>
<td>followers_url</td>
<td>following_url</td>
<td>gists_url</td>
<td>gravatar_id</td>
<td>html_url</td>
<td>login</td>
<td>node_id</td>
<td>organizations_url</td>
<td>received_events_url</td>
<td>repos_url</td>
<td>site_admin</td>
<td>starred_url</td>
<td>subscriptions_url</td>
<td>type</td>
<td>url</td>
</tr>
</thead>
<tbody>
{
currentPosts.map((item, index) => (
<tr key={index}>
<td>{item.id}</td>
<td>{item.avatar_url}</td>
<td>{item.events_url}</td>
<td>{item.followers_url}</td>
<td>{item.following_url}</td>
<td>{item.gists_url}</td>
<td>{item.gravatar_id}</td>
<td>{item.html_url}</td>
<td>{item.login}</td>
<td>{item.node_id}</td>
<td>{item.organizations_url}</td>
<td>{item.received_events_url}</td>
<td>{item.repos_url}</td>
<td>{item.site_admin}</td>
<td>{item.starred_url}</td>
<td>{item.subscriptions_url}</td>
<td>{item.type}</td>
<td>{item.url}</td>
</tr>
))
}
</tbody>
</table>
<Pagination postsPerPage={postsPerPage} totalPosts={userData.length} paginate={paginate} />
</div>
</div>
)
}
export default About
The pagination code is listed below.
import React from 'react'
const Pagination = ({ postsPerPage, totalPosts, paginate }) => {
const pageNumbers = [];
for(let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pageNumbers.push(i);
}
return (
<div>
<ul className="pagination">
{pageNumbers.map(number => (
<li key={number} className="page-item">
<a onClick={() => paginate(number)}
href="#" className="page-link">
{number}
</a>
</li>
))}
</ul>
</div>
)
}
export default Pagination
I am think because I used .map within the tbody and the search isn't affecting the content. Though I have no error, only that nothing is displaying from search parameters.
Upvotes: 0
Views: 47
Reputation: 1467
I noticed you didn't create the function to handle the searching. You can use this generic approach which will search across the rows and the column and will match the cases.
function DataSearch(rows) {
const columns = rows[0] && Object.keys(rows[0]);
return rows.filter((row) =>
columns.some((column) => row[column].toString().toLowerCase().indexOf(search.toLowerCase()) > -1)
);
}
instantiate the function
const searchPosts = DataSearch(currentPosts);
Use the searchPosts on your .map function in tbody.
Upvotes: 1