inc-lavender
inc-lavender•2y ago

How to use generic search with strapi-v4 and useTable

Hi 👋 I am listing the customers from my database with useTable hook from AntD and Strapi-v4 as data provider. I would like to implement a single search field to filter over the name, surname, email, ... I could use the onSearch property, but it only works on a single field and the API URL is always in the following format http://apiurl/customers?filters[$field][$operator]=$value. With Strapi, one could use the "_q" URL parameters to search over all table fields, e.g., http://apiurl/customers?_q=mySeachString . Any idea if and how I could implement this with useTable? Cheers
6 Replies
fascinating-indigo
fascinating-indigo•2y ago
Hey @npanti I think this document can help you. https://refine.dev/docs/advanced-tutorials/search/table-search/
Table Search | refine
We can make extensive search / filter operations using the useTable hook on the listing pages.
inc-lavender
inc-lavender•2y ago
Thanks @yildirayunlu, but it seems there is no way to make a search with the _q parameter of Strapi. Without reinventing the wheel and rewriting a new useTable hook. The easiest way seems to use the "or" crud operator over all elements of my table one by one, like this.
const { tableProps, searchFormProps } = useTable<ICustomer, HttpError, ICustomerFilterVariables>({
onSearch: (params) => {
const filters: CrudFilters = [];
const { q } = params;

filters.push({
operator: "or",
value: [
{
field: "name",
operator: "contains",
value: q
},
{
field: "surname",
operator: "contains",
value: q
},
{
field: "email",
operator: "contains",
value: q
}
]
})

return filters

}
});
const { tableProps, searchFormProps } = useTable<ICustomer, HttpError, ICustomerFilterVariables>({
onSearch: (params) => {
const filters: CrudFilters = [];
const { q } = params;

filters.push({
operator: "or",
value: [
{
field: "name",
operator: "contains",
value: q
},
{
field: "surname",
operator: "contains",
value: q
},
{
field: "email",
operator: "contains",
value: q
}
]
})

return filters

}
});
fascinating-indigo
fascinating-indigo•2y ago
Hey @npanti I think you dont need to write the fields one by one. list.tsx
export const PostList: React.FC<IResourceComponentsProps> = () => {
const { tableProps, sorter, filters, searchFormProps } = useTable<
IPost,
HttpError,
{ title: string; q: string }
>({
...
onSearch: (params) => {
const filters: CrudFilters = [];
const { q } = params;

filters.push({
field: "_q",
operator: "eq",
value: q,
});

return filters;
},
});

const { selectProps } = useSelect({
resource: "categories",
optionLabel: "title",
optionValue: "id",
defaultValue: getDefaultFilter("category.id", filters),
});

return (
<>
<Form layout="vertical" {...searchFormProps}>
<Form.Item label="Search" name="q">
<Input placeholder="ID, Title, Content, etc." />
</Form.Item>

<Form.Item>
<Button htmlType="submit" type="primary">
Filter
</Button>
</Form.Item>
</Form>

<List>
<Table
...
</Table>
</List>
</>
);
};
export const PostList: React.FC<IResourceComponentsProps> = () => {
const { tableProps, sorter, filters, searchFormProps } = useTable<
IPost,
HttpError,
{ title: string; q: string }
>({
...
onSearch: (params) => {
const filters: CrudFilters = [];
const { q } = params;

filters.push({
field: "_q",
operator: "eq",
value: q,
});

return filters;
},
});

const { selectProps } = useSelect({
resource: "categories",
optionLabel: "title",
optionValue: "id",
defaultValue: getDefaultFilter("category.id", filters),
});

return (
<>
<Form layout="vertical" {...searchFormProps}>
<Form.Item label="Search" name="q">
<Input placeholder="ID, Title, Content, etc." />
</Form.Item>

<Form.Item>
<Button htmlType="submit" type="primary">
Filter
</Button>
</Form.Item>
</Form>

<List>
<Table
...
</Table>
</List>
</>
);
};
Request: https://api.strapi.refine.dev/posts?_limit=10&_sort=id:desc&_start=0&=&_q=test
inc-lavender
inc-lavender•2y ago
This would work with Strapi version 3 but not with Strapi version 4, for which the request would be something like this, following your example:
http://APIURL/API/posts?pagination[page]=1&pagination[pageSize]=10&filters[_q][$eq]=test
http://APIURL/API/posts?pagination[page]=1&pagination[pageSize]=10&filters[_q][$eq]=test
Unless there is some configuration, I am missing.
fascinating-indigo
fascinating-indigo•2y ago
Yes, I haven't tested it for v4 😦 The best use for now seems to be to write all the fields.
inc-lavender
inc-lavender•2y ago
Thanks for confirming. Happy holidays! 🎄 🎆