Global Filter for multi-data cell in react-table

537 Views Asked by At

I'm using react-table in my project and I have a table with a column named "User". The cells in this column have a card with a couple of user's information, like:

const columns = useMemo(() => ([
{
  Header: 'User',
  accessor: 'user'
  Cell: ({value}) => (
    <div className="user">
      <h3 className="user__fullname">{value.firstName} {value.lastName}</h3>
      <p className="user__email">{value.email}</p>
    </div>
  )
},
{
  Header: 'Action',
  accessor: 'action'
  Cell: ({value}) => (
    <button onClick={(value.onClick)}>{value.name}</button>
  )
},
]), [])

And my user data is:

{
  user: {
    firstName: 'John',
    lastName: 'Doe',
    email: '[email protected]',
  },
  action: {
    name: 'Edit',
    onClick: () => null,
  },
}
// rest of the data...

I've already tried a couple of different approaches but I couldn't use global filter to filter by firstName, lastName or email.

When I pass just one of those types of data (like firstName) I can filter by it. But when I pass an object containing firstName, lastName and email, I can't filter.

Any ideas?

1

There are 1 best solutions below

2
PAS On

import * as React from 'react'

const createSearch = () => {
    const [search, setSearch] = React.useState<string>('')

    const formatter = (value : string) => value.replaceAll(' ', '').toLocaleLowerCase()
    const searchDataFilter = (array = [] as any[], keys : string[]) => [...new Set(
        keys.flatMap(key => array.filter(
            (obj) => formatter(obj[key].toString()).includes(search()))
        ))
    ]
    const handleInput = (e) => setSearch(formatter(e.value))
    const searchStringFilter = (array = [] as string[]) => array.filter(value => formatter(value).includes(search()))

    return {
        search,
        setSearch,
        formatter,
        searchDataFilter,
        searchStringFilter,
        handleInput,
    }
}
const Component = () => {
    const { handleInput, searchDataFilter } = createSearch()
    return (
      <div> 
         <input onInput={handleInput} />
         {searchDataFilter(data, ['email', 'name', 'createdAt'])}
      </div>
    )
}