T
TanStack16mo ago
fascinating-indigo

How to create a filter that filters the data instead of column

Hello I'm trying to have a filter that will filter data and not by column. currently i have 2 filters, one is tied to the 'name' column while the other is tied to the dataset for the table.
5 Replies
fascinating-indigo
fascinating-indigoOP16mo ago
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [fondtypFilter, setFondtypFilter] = React.useState<string[]>([]);
const table = useReactTable({
renderFallbackValue: undefined,
data,
columns,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getFilteredRowModel: getFilteredRowModel(),
// getSubRows: (row) => row.subRows,
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
filterFns: {
nameIsin: (rows: Row<Screener>, columnIds, filterValue) => {
return (
(rows
.getValue('name')
?.toString()
?.toLowerCase()
.includes(filterValue.toLowerCase()) ||
rows
.getValue('isin')
?.toString()
?.toLowerCase()
.includes(filterValue.toLowerCase())) ??
false
);
},
fundType: (rows: Row<Screener>, columnIds, filterValue) => {
return (
filterValue?.includes(rows.getValue('administratorCompanyId')) ??
false
);
},
},
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
expanded,
},
initialState: {
pagination: {
pageIndex: 0,
pageSize: 25,
},
},
});

const handleFondtypFilterChange = (id: string, checked: boolean) => {
setFondtypFilter((prev) =>
checked ? [...prev, id] : prev.filter((item) => item !== id)
);
setColumnFilters((prev) => [
...prev.filter((filter) => filter.id !== 'fondtype'),
{
id: 'fondtype',
value: checked
? [...fondtypFilter, id]
: fondtypFilter.filter((item) => item !== id),
},
]);
};
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [fondtypFilter, setFondtypFilter] = React.useState<string[]>([]);
const table = useReactTable({
renderFallbackValue: undefined,
data,
columns,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getFilteredRowModel: getFilteredRowModel(),
// getSubRows: (row) => row.subRows,
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
filterFns: {
nameIsin: (rows: Row<Screener>, columnIds, filterValue) => {
return (
(rows
.getValue('name')
?.toString()
?.toLowerCase()
.includes(filterValue.toLowerCase()) ||
rows
.getValue('isin')
?.toString()
?.toLowerCase()
.includes(filterValue.toLowerCase())) ??
false
);
},
fundType: (rows: Row<Screener>, columnIds, filterValue) => {
return (
filterValue?.includes(rows.getValue('administratorCompanyId')) ??
false
);
},
},
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
expanded,
},
initialState: {
pagination: {
pageIndex: 0,
pageSize: 25,
},
},
});

const handleFondtypFilterChange = (id: string, checked: boolean) => {
setFondtypFilter((prev) =>
checked ? [...prev, id] : prev.filter((item) => item !== id)
);
setColumnFilters((prev) => [
...prev.filter((filter) => filter.id !== 'fondtype'),
{
id: 'fondtype',
value: checked
? [...fondtypFilter, id]
: fondtypFilter.filter((item) => item !== id),
},
]);
};
filter component:
'use client';
import { Input } from '@component/ui/input';
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@component/ui/dropdown-menu';
import { Button } from '@component/ui/Button';
import { ChevronDown } from 'lucide-react';
import * as React from 'react';
import { type Table } from '@tanstack/table-core';
interface Props {
table: Table<Screener>;
data: Screener[];
handleFondtypFilterChange: (id: string, checked: boolean) => void;
}
const FilterRetail = ({ table, data, handleFondtypFilterChange }: Props) => {
const fundType = [
{
id: '$BCG$EQUTY',
name: 'Aktier',
},
{
id: '$BCG$ALLOC',
name: 'Blandfonder',
},
{
id: '$BCG$FXINC',
name: 'Långa räntefonder',
},
];

return (
<div className="flex items-center gap-4 py-4">
<Input
placeholder="Seach by Name or ISIN"
value={(table.getColumn('name')?.getFilterValue() as string) ?? ''}
onChange={(event: any) => {
table.getColumn('name')?.setFilterValue(event.target.value);
}}
search={true}
className="max-w-sm"
/>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
Fondtyp <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{fundType.map((type) => {
return (
<DropdownMenuCheckboxItem
key={type.id}
className="capitalize"
onCheckedChange={(value) =>
handleFondtypFilterChange(type.id, value)
}
>
{type.name}
</DropdownMenuCheckboxItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
</div>
);
};

export default FilterRetail;
'use client';
import { Input } from '@component/ui/input';
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@component/ui/dropdown-menu';
import { Button } from '@component/ui/Button';
import { ChevronDown } from 'lucide-react';
import * as React from 'react';
import { type Table } from '@tanstack/table-core';
interface Props {
table: Table<Screener>;
data: Screener[];
handleFondtypFilterChange: (id: string, checked: boolean) => void;
}
const FilterRetail = ({ table, data, handleFondtypFilterChange }: Props) => {
const fundType = [
{
id: '$BCG$EQUTY',
name: 'Aktier',
},
{
id: '$BCG$ALLOC',
name: 'Blandfonder',
},
{
id: '$BCG$FXINC',
name: 'Långa räntefonder',
},
];

return (
<div className="flex items-center gap-4 py-4">
<Input
placeholder="Seach by Name or ISIN"
value={(table.getColumn('name')?.getFilterValue() as string) ?? ''}
onChange={(event: any) => {
table.getColumn('name')?.setFilterValue(event.target.value);
}}
search={true}
className="max-w-sm"
/>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
Fondtyp <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{fundType.map((type) => {
return (
<DropdownMenuCheckboxItem
key={type.id}
className="capitalize"
onCheckedChange={(value) =>
handleFondtypFilterChange(type.id, value)
}
>
{type.name}
</DropdownMenuCheckboxItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
</div>
);
};

export default FilterRetail;
fascinating-indigo
fascinating-indigoOP16mo ago
No description
No description
ratty-blush
ratty-blush16mo ago
what you are looking for is the globalFilterFn and globalFilter. https://tanstack.com/table/latest/docs/api/features/global-filtering
Global Filtering APIs | TanStack Table Docs
Can-Filter The ability for a column to be globally filtered is determined by the following:
fascinating-indigo
fascinating-indigoOP16mo ago
I dont understand the documentation, also the examples i;ve found all have the datapoint they want to filter within the columns :/ when i use a filter for which i have a column there is no issue in filtering, but when i want to filter something by another datapoint from the dataset that is not displayed via column thats where i have issues. also im working with a dataset of 900 objects, is there anything i can do regading this to have less of a delay when filtering/sorting?
ratty-blush
ratty-blush16mo ago
globalFilter is the value, I would assume this would be the filter string in your setup. globalFilterFn would be the function that takes (row: Row, columnId: string, filterValue: string) => boolean. You will need to control the value of globalFilter to trigger the filtering of the table. Remember that you will want to memoize all of these values before putting them into useReactTable if you are using react, not doing that could cause performance problems.

Did you find this page helpful?