-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEAT] Keep filters when refresh the page with useTable #6001
Comments
Hello @dfang, thanks for the issue! we need to add more information is here: https://refine.dev/docs/ui-integrations/ant-design/hooks/use-table/#initial-filter-and-sorter Do you want to work on this? |
Also experinced this problem. Hopefully it can be added soon! const initialFilters: {[key: string]: string}[] = []
const currentUrl = new URL(location.href)
currentUrl.searchParams.forEach((value, key) => {
const matches = key.match(/filters\[(\d+)\]\[(.*?)\]/);
if (matches) {
const index = Number(matches[1]);
const field = matches[2];
// Ensure the filter object exists
if (!initialFilters[index]) {
initialFilters[index] = {};
}
// Assign the value to the appropriate field
initialFilters[index][field] = value;
}
}) <Table.Column
dataIndex="inspector"
key="inspector][id"
title="Inspector"
className="cursor-pointer"
render={(value) => value?.name}
defaultFilteredValue={initialFilters.filter(filter => filter.field === 'inspector][id').map(filter => filter.value)}
filterDropdown={(props) => (
<FilterDropdown {...props}>
<Select style={{ minWidth: 200 }} placeholder="Select inspector" {...inspectorsSelectProps} />
</FilterDropdown>
)}
/> |
Hello @dzcpy, Is this not working? import { getDefaultFilter } from "@refinedev/core";
const { filters } = useTable();
// ...
defaultFilteredValue={getDefaultFilter("inspector][id", filters, "eq")}
// ... |
It doesn't work properly. It's just a hack. But this feature should really be integrated into Refine just like other fields (sorter and pagination from URL, if syncWithLocation is set to true) Also when the field is a number or a boolean value, I need to convert the value to the respective type, otherwise filter select / checkbox will not find the default selected value. I've changed it to something like this: import { isNil } from 'lodash'
export const tableFiltersFromUrl = (url?: string) => {
if (!url) {
url = window.location.href
}
return Array.from(new URL(url).searchParams.entries()).reduce((acc, [key, value]) => {
if (key.startsWith('filters[')) {
const matches = key.match(/filters\[(?<index>\d+)\]\[(?<item>.*?)\]/)
if (matches?.groups?.index && matches?.groups?.item) {
const index = Number(matches.groups.index)
const field = matches.groups.item
// Ensure the filter object exists
if (!acc[index]) {
acc[index] = {}
}
// Assign the value to the appropriate field
acc[index][field] = value
}
}
return acc
}, [] as { [key: string]: string }[])
.filter(filter => filter.field && filter.operator && !isNil(filter.value)) as { field: string, operator: string, value: string }[]
}
export const tableFiltersGetDefaultValue = (filters: ReturnType<typeof tableFiltersFromUrl>, field: string, type: 'string' | 'number' | 'boolean' = 'string') =>
filters.filter(filter => filter.field === field).map(filter => type === 'boolean' ? /^true$/i.test(filter.value) : type === 'number' ? Number(filter.value) : filter.value) const initialFilters = useMemo(() => tableFiltersFromUrl(), []) <Table.Column
dataIndex="name"
key="name"
title="Name"
defaultFilteredValue={tableFiltersGetDefaultValue(initialFilters, 'name')}
filterDropdown={(props) => (
<FilterDropdown {...props}>
<Input style={{ minWidth: 200 }} placeholder="Please input name" />
</FilterDropdown>
)}
className="cursor-pointer"
/>
<Table.Column
dataIndex="inspector"
key="inspector][id"
title="Inspector"
className="cursor-pointer"
render={(value) => value?.name}
defaultFilteredValue={tableFiltersGetDefaultValue(initialFilters, 'inspector][id', 'number')}
filterDropdown={(props) => (
<FilterDropdown {...props}>
<Select style={{ minWidth: 200 }} placeholder="Please select inspector" {...inspectorsSelectProps} />
</FilterDropdown>
)}
/>
<Table.Column
dataIndex="finished"
key="finished"
title="Finished?"
render={(value) => (value ? locationFinishedOptions.true : locationFinishedOptions.false)}
defaultFilteredValue={tableFiltersGetDefaultValue(initialFilters, 'finished', 'boolean')}
filterDropdown={(props) => (
<FilterDropdown {...props}>
<Select
style={{ minWidth: 200 }}
placeholder="Choose if it's finished"
filterOption={false}
options={Object.entries(locationFinishedOptions).map(([value, label]) => ({ value, label }))}
/>
</FilterDropdown>
)}
className="cursor-pointer"
/> |
@dzcpy Thanks for the detailed explanation, you are right there is room for improvement. We'll think about it. |
This doesnt work if you have different filters component, e.g here, would appreciate if someone has a solution for this |
Is your feature request related to a problem? Please describe.
this is a list of customers filtered with idle status,
https://example.admin.refine.dev/customers?pageSize=10¤t=9&sorters[0][field]=isActive&sorters[0][order]=asc&filters[0][field]=fullName&filters[0][operator]=contains
when I refresh the page, the list is not filtered with idle status.
Describe alternatives you've considered
No response
Additional context
when you filter then click pagination number, it's ok. but refresh and click pagination number, it's not filtered
Describe the thing to improve
keep the filter after refreshing the page (restore filters from url)
The text was updated successfully, but these errors were encountered: