Open bytemtek opened 1 year ago
Please support live search across cols and rows
Is there any update about search ?
@bytemtek I have achieved desired functionality using another lib https://www.npmjs.com/package/react-data-table-component-extensions
@bytemtek I have achieved desired functionality using another lib https://www.npmjs.com/package/react-data-table-component-extensions
Thank you so much !
Just picking this Feature Request up because it might help someone. I ended up creating a Helper-Component (customTable.tsx) so really only need to pass the most basic Info inside the actual pages.
"use client"
import CustomTable from "@/components/customTable"
const ExamplePage = () => {
const columns = [
{
name: "Vorname",
columnName: "firstName",
sortable: true,
},
{
name: "Nachname",
columnName: "lastName",
sortable: true,
},
{
name: "Adresse",
columnName: "address",
sortable: true,
},
{
name: "Tel",
columnName: "phone",
sortable: false,
searchable: false,
},
{
name: "Password",
columnName: "password",
sortable: true,
},
{
name: "Domain",
columnName: "domain",
sortable: true,
},
{
name: "Price",
columnName: "price",
sortable: true,
},
]
const data = [
{
id: "8c5e932d-486c-4518-9844-16ea95d953ed",
firstName: "Sasha",
lastName: "Armstrong",
address: "53155 Dortha Landing 1, 30003-6945 Estonia",
phone: "1-412-368-8275 x7224",
password: "V3Ib3it5gyIKDYf",
domain: "weak-trim.biz",
price: "942.00",
},
{
id: "dd5c1ba6-b205-4e4e-b6c9-4685c4a188c2",
firstName: "Piper",
lastName: "Nicolas",
address: "99080 Abbey Islands 1, 30051 Faroe Islands",
phone: "1-499-890-1017",
password: "25EokNu2NxQoXHi",
domain: "hideous-dart.biz",
price: "542.00",
},
{
id: "c701cb3a-a0bb-4ed6-a0cd-c56cec696155",
firstName: "Michale",
lastName: "Blick",
address: "7000 Hessel Groves 1, 23758-6810 Saint Pierre and Miquelon",
phone: "1-403-512-7971 x476",
password: "niZRpgXuHRdihe6",
domain: "affectionate-history.biz",
price: "603.00",
},
]
return <CustomTable columns={columns} data={data} />
}
export default ExamplePage
the columns themself are just passing sortable
and searchable
as well as the Label and actual data-value:
{
name: "Vorname", <-- the Label that get's displayed on the frontend
columnName: "firstName", <-- the name of the data-column
sortable: true, <-- sortable active by default
searchable: true <-- searchable active by default
},
this custom component has my default settings hardcoded, CSV and Live-Search enabled while maintaining a minimal and easy to use page. Overall it's used like this:
"use client"
import { Button } from "@/components/ui/button"
import { ArrowUp, FileDown, TrashIcon } from "lucide-react"
import { useMemo, useState } from "react"
import DataTable, { TableColumn } from "react-data-table-component"
import { Input } from "./ui/input"
interface CustomColumn {
name: string
columnName: string
sortable?: boolean
searchable?: boolean
}
type CustomTableProps<T> = {
columns: CustomColumn[]
data: T[]
}
const CustomTable = <T extends Record<string, unknown>>({
columns,
data,
}: CustomTableProps<T>) => {
const [filterText, setFilterText] = useState("")
const searchableColumns = columns.filter((col) => col.searchable !== false)
const filteredData = useMemo(() => {
return data.filter((item) =>
searchableColumns.some((col) =>
String(item[col.columnName] || "")
.toLowerCase()
.includes(filterText.toLowerCase()),
),
)
}, [data, filterText, searchableColumns])
const tableColumns: TableColumn<T>[] = columns.map((col) => ({
name: col.name,
selector: (row: T) => row[col.columnName as keyof T] as unknown as string,
sortable: col.sortable !== false
}))
function downloadCSV(array: T[]) {
const link = document.createElement("a")
const csv = array
.map((row) =>
searchableColumns.map((col) => String(row[col.columnName])).join(";"),
)
.join("\n")
link.setAttribute("href", `data:text/csv;charset=utf-8,${csv}`)
link.setAttribute("download", "export.csv")
link.click()
}
const Export = ({ onExport }: { onExport: () => void }) => (
<Button onClick={() => onExport()}>
<FileDown className="h-4 w-4 mr-4" /> Export (CSV)
</Button>
)
const actionsMemo = useMemo(
() => <Export onExport={() => downloadCSV(filteredData)} />,
[filteredData],
)
const subHeaderComponentMemo = useMemo(() => {
const handleClear = () => setFilterText("")
return (
<div className="flex justify-center items-center">
<Input
type="text"
placeholder="Search"
value={filterText}
onChange={(e) => setFilterText(e.target.value)}
/>
<Button onClick={handleClear} variant="outline">
<TrashIcon className="h-4 w-4" />
</Button>
</div>
)
}, [filterText])
return (
<div>
<DataTable
pagination
columns={tableColumns}
data={filteredData}
responsive
highlightOnHover
sortIcon={<ArrowUp />}
paginationRowsPerPageOptions={[10, 25, 50, 100]}
actions={actionsMemo}
noDataComponent="Keine Daten vorhanden"
progressComponent="Daten werden geladen..."
paginationComponentOptions={{
rowsPerPageText: "Einträge pro Seite",
rangeSeparatorText: "von",
}}
customStyles={{
header: { style: { padding: "0px" } },
subHeader: { style: { padding: "0px" } },
}}
subHeader
subHeaderComponent={subHeaderComponentMemo}
/>
</div>
)
}
export default CustomTable
Is this component supported or will it support live search? Thank you.