search filter by name in react using input

Viewed 1308

I have a table of users and I have to filter/search users by the name entered. For example, when typing John, I must list all users named John in the table.

Table code with all users

ListPatients.js

const ListPatients = ({ pacientes, setPacientes }) => {

  const removePaciente = (idToDelete) => {
    const newTasks = [...pacientes];
    newTasks.splice(idToDelete, 1);
    setPacientes(newTasks);
  };
  return (
    <div style={{ display:"flex", alignItems:"center", flexDirection:'column'}}>
      <h1>List</h1>
      <Table style={{ border:'1'}}>
        <thead>
          <tr style={{padding:'0 1rem'}}>
            <th>Name</th>
            <th>Birth date</th>
            <th>CPF</th>
            <th>Gender</th>
            <th>Addres</th>
            <th>Status</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          {pacientes.length > 0 ? (
            pacientes.map((paciente, index) => (
              <tr key={paciente.id}>
                <td>{paciente.name}</td>
                <td>{paciente.birth date}</td>
                <td>{paciente.cpf}</td>
                <td>{paciente.gender}</td>
                <td>{paciente.address}</td>
                <td>{paciente.status}</td>
                <td>
                  <Button className="button muted-button" onClick={() => removePaciente(index)}>
                    <i style={{ color: "red" }} className="fa-solid fa-trash fa-xl"></i>
                  </Button>
                  <Button className="button muted-button">
                    <i style={{ color: "orange" }} className="fa-solid fa-pen-to-square fa-xl"></i>
                  </Button>
                  {/* {condition === true ? <Cadastrar /> : <ListarPacientes />} */}
                </td>
              </tr>
            ))
          ) : (
            <tr>
              <td colSpan={3}>Sem pacientes</td>
            </tr>
          )}
        </tbody>
      </Table>
    </div>
  )
}
export default ListPatients

Result enter image description here

Note: I'm using localStorage to store the data. enter image description here

How do I do it using a search input? Help please.

2 Answers

It is pretty simple. You will need to define the state where you will keep the searchInput value

const [searchInput, setSearchInput] = useState()

Then you should create a function that will filter your patients

const getFilteredPatients = () => {
  if (!searchInput) return patients
  return patients.filter(patient => patient.name.toLowerCase() === searchInput.toLowerCase())
}

and just call it in a proper place.

Overall it should look like

const ListPatients = props => {
  const { patients, setPatients } = props

  const [searchInput, setSearchInput] = useState()

  const removePatient = patientId => {
    const newPatients = patients.filter(patient => patient.id !== patientId)
    setPatients(newPatients)
  }

  const getFilteredPatients = () => {
    if (!searchInput) return patients
    return patients.filter(
      patient => patient.name.toLowerCase() === searchInput.toLowerCase()
    )
  }

  const filteredPatients = getFilteredPatients()

  return (
    <div>
      <h1>List</h1>
      <Table style={{ border: '1' }}>
        <thead>
          <tr style={{ padding: '0 1rem' }}>
            <th>Name</th>
            <th>Birth date</th>
            <th>CPF</th>
            <th>Gender</th>
            <th>Addres</th>
            <th>Status</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          {patients.length === 0 && (
            <tr>
              <td colSpan={3}>Sem pacientes</td>
            </tr>
          )}

          {filteredPatients.map(patient => (
            <tr key={patient.id}>
              <td>{patient.name}</td>
              <td>{patient.birth_date}</td>
              <td>{patient.cpf}</td>
              <td>{patient.gender}</td>
              <td>{patient.address}</td>
              <td>{patient.status}</td>
              <td>
                <Button
                  className="button muted-button"
                  onClick={() => removePatient(patient.id)}
                >
                  <i
                    style={{ color: 'red' }}
                    className="fa-solid fa-trash fa-xl"
                  />
                </Button>
                <Button className="button muted-button">
                  <i
                    style={{ color: 'orange' }}
                    className="fa-solid fa-pen-to-square fa-xl"
                  />
                </Button>
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  )
}

export default ListPatients

There are 3 main parts I modified in your code

Firstly, you need to import these

import React, { useState, useEffect } from 'react'

After that we start the implementation

//initialise search value
const [searchValue, setSearchValue] = useState("")

//whenever search value gets updated, we will update patience list
  useEffect(() => {
    const newPacientes = pacientes.filter(value => value.name.toLowerCase().includes(searchValue.toLowerCase()))
    setPacientes(newPacientes)
  }, [searchValue])

And lastly, we need to have search input field

<input type="text" onChange={(e) => setSearchValue(e.target.value)} value={searchValue} placeholder="Search by name"/>

import React, { useState, useEffect } from 'react'

const ListPatients = ({ pacientes, setPacientes }) => {
  //initialise search value
  const [searchValue, setSearchValue] = useState("")
  
  //whenever search value gets updated, we will update patience list
  useEffect(() => {
    const newPacientes = pacientes.filter(value => value.name.toLowerCase().includes(searchValue.toLowerCase()))
    setPacientes(newPacientes)
  }, [searchValue])
  
  const removePaciente = (idToDelete) => {
    const newTasks = [...pacientes];
    newTasks.splice(idToDelete, 1);
    setPacientes(newTasks);
  };
  return (
    <div style={{ display:"flex", alignItems:"center", flexDirection:'column'}}>
      <h1>List</h1>
      <input type="text" onChange={(e) => setSearchValue(e.target.value)} value={searchValue} placeholder="Search by name"/>
      <Table style={{ border:'1'}}>
        <thead>
          <tr style={{padding:'0 1rem'}}>
            <th>Name</th>
            <th>Birth date</th>
            <th>CPF</th>
            <th>Gender</th>
            <th>Addres</th>
            <th>Status</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          {pacientes.length > 0 ? (
            pacientes.map((paciente, index) => (
              <tr key={paciente.id}>
                <td>{paciente.name}</td>
                <td>{paciente.birth date}</td>
                <td>{paciente.cpf}</td>
                <td>{paciente.gender}</td>
                <td>{paciente.address}</td>
                <td>{paciente.status}</td>
                <td>
                  <Button className="button muted-button" onClick={() => removePaciente(index)}>
                    <i style={{ color: "red" }} className="fa-solid fa-trash fa-xl"></i>
                  </Button>
                  <Button className="button muted-button">
                    <i style={{ color: "orange" }} className="fa-solid fa-pen-to-square fa-xl"></i>
                  </Button>
                  {/* {condition === true ? <Cadastrar /> : <ListarPacientes />} */}
                </td>
              </tr>
            ))
          ) : (
            <tr>
              <td colSpan={3}>Sem pacientes</td>
            </tr>
          )}
        </tbody>
      </Table>
    </div>
  )
}
export default ListPatients

Related