Payne
Payne

Reputation: 543

Creating Search functionality in reactJs for Table content

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

Answers (1)

Abdulkabir Ojulari
Abdulkabir Ojulari

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

Related Questions