Custom or GenericSearch search in React Typescript
Published: 2024-03-14 11:26:11

Here is the generic code where user needs to pass the actualdata and data (where both are the same array) so that we do not loose the actual data when user erases the search parameters.

Here I used tailwindcss in className

```
import React from 'react'

type Props<T extends { [key: string]: any }> = {
    data: T[];
    actualData: T[];
    onchange: (value: T[]) => void;
}

function GenericSearch<T extends { [key: string]: any }>({ onchange, data, actualData }: Props<T>) {

    const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
        const query = event.target.value.toLowerCase();
        if (!query.length) {
            return onchange(actualData)
        }
        const searchedValue = data.filter((property, i) => {
            return Object.values(property).some(value =>
                value.toString().toLowerCase().includes(query)
            );
        });
        searchedValue.length !== 0 ? onchange(searchedValue) : onchange(actualData)
    }

    return (
        <label className="relative block">
            <span className="sr-only">Search</span>
            <span className="absolute inset-y-0 left-0 flex items-center pl-2">
                <svg
                    className="h-5 w-5 fill-slate-300"
                    viewBox="0 0 20 20"
                ></svg>
            </span>
            <input
                className="placeholder:italic text-gray-800 placeholder:text-slate-400 block bg-gray-100 w-full"
                placeholder="Search here..."
                type="text"
                name="search"
                onChange={handleSearch}
            />
        </label>
    )
}

export default GenericSearch
```

in App.ts 

let's take the this sample json data form ([here](https://docshield.tungstenautomation.com/KTA/en_US/7.11.0-h49vd5omev/help/Designer/All_Shared/SystemData/c_dmjsonexamples.html)

` "data": [
     {
      "id": 1,
      "name": "cerulean",
      "year": 2000,
      "color": "#98B2D1",
      "pantone_value": "15-4020"
     },
     {
      "id": 2,
      "name": "fuchsia rose", 
      "year": 2001, 
      "color": "#C74375",
      "pantone_value": "17-2031"
     },
     {
      "id": 3, 
      "name": "true red", 
      "year": 2002, 
      "color": "#BF1932", 
      "pantone_value": "19-1664" 
     }, 
     {
      "id": 4, 
      "name": "aqua sky",
      "year": 2003,
      "color": "#7BC4C4",
      "pantone_value": "14-4811"
     },
     { 
      "id": 5,
      "name": "red turquoise", 
      "year": 2004, 
      "color": "#E2583E", 
      "pantone_value": "17-1456" 
     },
     {  
      "id": 6, 
      "name": "blue turquoise", 
      "year": 2005,            
      "color": "#53B0AE",
      "pantone_value": "15-5217"
     }
      ]
`




`const handleSearch = (value: objectType[]) => {
    setFilterData(assignValuesObject(value));
  };
`

`
   <GenericSearch
            data={filterData}
            actualData={data}
            onchange={handleSearch}
          />
`
for checking if our filter is working or not
`<div>
        {filterData.length && (
          filterData.map((d: filterDataTypes) => {
            return (
              <div key={d.id + d.name}>{d.name}</div>
            );
          })
        )
        }
      </div>`

in utils.ts

`import { objectType } from "./types";

export const assignValuesObject = (values: objectType[]) =>
  values.map((d, index: number) => {
    return { ...d, id: index + d.description, isOpen: false };
  });`