Skip to main content
Version: 2.xx.xx

List Search

We will examine how to make an extensive search and filtering with the useSimpleList hook that works with the Ant Design's <List> component.

To do this, let's list posts using the posts resource.

pages/posts/list.tsx
import {
List,
useSimpleList,
useMany,
AntdList,
Typography,
Space,
NumberField,
} from "@pankod/refine";

const { Text } = Typography;

export const PostList: React.FC = () => {
const { listProps } = useSimpleList<IPost>();

const categoryIds =
listProps?.dataSource?.map((item) => item.category.id) ?? [];
const { data } = useMany<ICategory>({
resource: "categories",
ids: categoryIds,
queryOptions: {
enabled: categoryIds.length > 0,
},
});

const renderItem = (item: IPost) => {
const { title, hit, content } = item;

const categoryTitle = data?.data.find(
(category: ICategory) => category.id === item.category.id,
)?.title;

return (
<AntdList.Item
actions={[
<Space key={item.id} direction="vertical" align="end">
<NumberField
value={hit}
options={{
notation: "compact",
}}
/>
<Text>{categoryTitle}</Text>
</Space>,
]}
>
<AntdList.Item.Meta title={title} description={content} />
</AntdList.Item>
);
};

return (
<List>
<AntdList {...listProps} renderItem={renderItem} />
</List>
);
};

interface ICategory {
id: string;
title: string;
}

interface IPost {
id: string;
title: string;
content: string;
hit: number;
category: ICategory;
}

After creating the <PostList> component, add it to resource with list prop:

import { Refine, Resource } from "@pankod/refine";
import routerProvider from "@pankod/refine-react-router";
import dataProvider from "@pankod/refine-simple-rest";

import "@pankod/refine/dist/styles.min.css";

import { PostList } from "pages/posts";

const API_URL = "https://api.fake-rest.refine.dev";

const App: React.FC = () => {
return (
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider(API_URL)}
resources={[{ name: "posts", list: PostList }]}
/>
);
};

export default App;
basic list

We will create a form by extracting searchFormProps from useSimpleList. We will use this form for search/filtering. We will also create an interface to determine the types of values from the form.

pages/posts/list.tsx
...

import {
...
CrudFilters,
} from "@pankod/refine";

export const PostList: React.FC = () => {
const { listProps, searchFormProps } = useSimpleList<
IPost,
IPostFilterVariables
>({
onSearch: (params) => {
const filters: CrudFilters = [];
const { category, createdAt } = params;

filters.push(
{
field: "category.id",
operator: "eq",
value: category,
},
{
field: "createdAt",
operator: "gte",
value: createdAt ? createdAt[0].toISOString() : undefined,
},
{
field: "createdAt",
operator: "lte",
value: createdAt ? createdAt[1].toISOString() : undefined,
},
);

return filters;
},
});

// ...

const { selectProps: categorySelectProps } = useSelect<ICategory>({
resource: "categories",
});

return (
<List>
<Form
{...searchFormProps}
layout="vertical"
onValuesChange={() => searchFormProps.form?.submit()}
>
<Space wrap>
<Form.Item label="Category" name="category">
<Select
{...categorySelectProps}
allowClear
placeholder="Search Categories"
/>
</Form.Item>
<Form.Item label="Created At" name="createdAt">
<RangePicker />
</Form.Item>
</Space>
</Form>
<AntdList {...listProps} renderItem={renderItem} />
</List>
);
};

interface IPostFilterVariables {
category: string;
createdAt: [Dayjs, Dayjs];
}

When the form is submitted, the onSearch method runs and we get the search form values. Then the listProps is refreshed according to the criteria.

form list

info

CrudFilters type object has field, operator and value properties. These properties help us to filter in which field, with which operator, and with which data.

Live Codesandbox Example​