Skip to content

Commit e45ff30

Browse files
committed
docs: add DataTableInput page and cross references
1 parent 0228b71 commit e45ff30

File tree

10 files changed

+281
-4
lines changed

10 files changed

+281
-4
lines changed

docs/AutocompleteInput.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ The form value for the source must be the selected value, e.g.
5252

5353
**Tip**: If you need to let users select more than one item in the list, check out the [`<AutocompleteArrayInput>`](./AutocompleteArrayInput.md) component.
5454

55+
**Tip**: If users need to compare multiple fields before choosing (e.g. team, region, SLA, status), use [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" />.
56+
5557
## Props
5658

5759
| Prop | Required | Type | Default | Description |

docs/DataTable.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Each `<DataTable.Col>` defines one column of the table: its `source` (used for s
4545
- [`<SingleFieldList>`](./SingleFieldList.md) renders a single field for each record
4646
- [`<DatagridAG>`](./DatagridAG.md)<img class="icon" src="./img/premium.svg" /> is a more advanced spreadsheet component with support for aggregation, pivoting, row grouping, infinite scroll, etc.
4747

48+
**Tip**: If you need to let users select records through a table in a form, use [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" />.
49+
4850
## Props
4951

5052
| Prop | Required | Type | Default | Description |

docs/DataTableInput.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
---
2+
layout: default
3+
title: "The DataTableInput Component"
4+
---
5+
6+
# `<DataTableInput>`
7+
8+
`<DataTableInput>` is an [Enterprise Edition](https://react-admin-ee.marmelab.com)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" /> input from `@react-admin/ra-form-layout` that lets users select one or many choices in a dialog containing a [`<DataTable>`](./DataTable.md).
9+
10+
It combines:
11+
12+
- an input showing the current selection(s),
13+
- and a dialog with sorting, filtering, and pagination to pick records.
14+
15+
![DataTableInput selection](./img/DataTableInput-select.png)
16+
17+
![DataTableInput dialog](./img/DataTableInput-dialog.png)
18+
19+
`<DataTableInput>` is a good alternative to [`<SelectInput>`](./SelectInput.md), [`<AutocompleteInput>`](./AutocompleteInput.md), and [`<AutocompleteArrayInput>`](./AutocompleteArrayInput.md) when you have many choices, or when users need more than one field to identify each choice.
20+
21+
First, install the `@react-admin/ra-form-layout` package:
22+
23+
```sh
24+
npm install --save @react-admin/ra-form-layout
25+
# or
26+
yarn add @react-admin/ra-form-layout
27+
```
28+
29+
**Tip**: `@react-admin/ra-form-layout` is hosted in a private npm registry. You need an [Enterprise Edition](https://react-admin-ee.marmelab.com/) subscription to access it.
30+
31+
Test it live in [the Enterprise Storybook](https://react-admin.github.io/ra-enterprise/?path=/story/ra-form-layout-listinputs-datatableinput--basic).
32+
33+
## Usage
34+
35+
Like `<SelectInput>`, `<DataTableInput>` can be used with a `choices` array. The difference is that you define table columns as children with `<DataTable.Col>`.
36+
37+
```tsx
38+
import { Edit, SimpleForm, DataTable, TextInput } from 'react-admin';
39+
import { DataTableInput } from '@react-admin/ra-form-layout';
40+
41+
const suppliers = [
42+
{
43+
id: 101,
44+
company_name: 'Acme Industrial',
45+
category: 'Machining',
46+
city: 'Detroit',
47+
country: 'US',
48+
lead_time_days: 7,
49+
reliability_score: 98,
50+
},
51+
{
52+
id: 102,
53+
company_name: 'Nordic Components',
54+
category: 'Electronics',
55+
city: 'Stockholm',
56+
country: 'SE',
57+
lead_time_days: 11,
58+
reliability_score: 95,
59+
},
60+
];
61+
62+
export const ProductEdit = () => (
63+
<Edit>
64+
<SimpleForm>
65+
<TextInput source="sku" />
66+
<TextInput source="name" />
67+
<DataTableInput
68+
source="preferred_supplier_id"
69+
resource="suppliers"
70+
choices={suppliers}
71+
optionText="company_name"
72+
>
73+
<DataTable.Col source="company_name" />
74+
<DataTable.Col source="category" />
75+
<DataTable.Col source="city" />
76+
<DataTable.Col source="country" />
77+
<DataTable.NumberCol source="lead_time_days" label="Lead Time (days)" />
78+
<DataTable.NumberCol source="reliability_score" label="Reliability %" />
79+
</DataTableInput>
80+
</SimpleForm>
81+
</Edit>
82+
);
83+
```
84+
85+
## With Reference Inputs
86+
87+
You can use `<DataTableInput>` as a child of:
88+
89+
- [`<ReferenceInput>`](./ReferenceInput.md)
90+
- [`<ReferenceArrayInput>`](./ReferenceArrayInput.md)
91+
- [`<ReferenceManyToManyInput>`](./ReferenceManyToManyInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" />
92+
93+
In that case, choices are fetched automatically from the reference resource.
94+
95+
```tsx
96+
import {
97+
DataTable,
98+
Edit,
99+
ReferenceArrayInput,
100+
SimpleForm,
101+
TextInput,
102+
} from 'react-admin';
103+
import { DataTableInput } from '@react-admin/ra-form-layout';
104+
105+
export const ReleaseEdit = () => (
106+
<Edit>
107+
<SimpleForm>
108+
<TextInput source="version" />
109+
<ReferenceArrayInput source="reviewer_ids" reference="users">
110+
<DataTableInput multiple>
111+
<DataTable.Col source="full_name" />
112+
<DataTable.Col source="team" />
113+
<DataTable.Col source="role" />
114+
<DataTable.Col source="timezone" />
115+
<DataTable.Col source="location" />
116+
</DataTableInput>
117+
</ReferenceArrayInput>
118+
</SimpleForm>
119+
</Edit>
120+
);
121+
```
122+
123+
## Multiple Selection
124+
125+
Set `multiple` to `true` when the field stores an array of identifiers.
126+
127+
```tsx
128+
import { Create, DataTable, SimpleForm } from 'react-admin';
129+
import { DataTableInput } from '@react-admin/ra-form-layout';
130+
131+
const tags = [
132+
{ id: 'backend', name: 'Backend', group: 'Engineering' },
133+
{ id: 'frontend', name: 'Frontend', group: 'Engineering' },
134+
{ id: 'design', name: 'Design', group: 'Product' },
135+
];
136+
137+
export const ArticleCreate = () => (
138+
<Create>
139+
<SimpleForm>
140+
<DataTableInput source="tag_ids" choices={tags} multiple>
141+
<DataTable.Col source="name" />
142+
<DataTable.Col source="group" />
143+
</DataTableInput>
144+
</SimpleForm>
145+
</Create>
146+
);
147+
```
148+
149+
## Props
150+
151+
In addition to the [common input props](./Inputs.md#common-input-props), `<DataTableInput>` accepts:
152+
153+
| Prop | Required | Type | Default | Description |
154+
| ---------------- | -------- | ----------------------------------------- | --------------------------------------------------- | ----------- |
155+
| `actions` | Optional | `ReactElement` &#124; `false` | auto (`false` when no filters) | Actions toolbar displayed in the dialog |
156+
| `children` | Required | `ReactNode` | - | `<DataTable.Col>` elements defining displayed columns |
157+
| `choices` | Optional | `RaRecord[]` | - | Choices for standalone usage (not needed inside reference inputs) |
158+
| `dataTableProps` | Optional | `DataTableProps` | - | Props forwarded to the inner [`<DataTable>`](./DataTable.md) |
159+
| `dialogProps` | Optional | `DialogProps` | - | Props forwarded to the selection dialog |
160+
| `filters` | Optional | `ReactElement` &#124; `ReactElement[]` &#124; `false` | - | Filters displayed in the dialog toolbar |
161+
| `multiple` | Optional | `boolean` | `false` | Enables multiple selection (value becomes an array of ids) |
162+
| `optionText` | Optional | `OptionText` | resource `recordRepresentation` or `name` | Label used for selected chips in standalone mode |
163+
| `optionValue` | Optional | `string` | `id` | Field used as choice value in standalone mode |
164+
| `pagination` | Optional | `ReactNode` | [`<Pagination />`](./Pagination.md) | Pagination element rendered below the table |
165+
| `title` | Optional | `string` | `ra-form-layout.inputs.datatable_input.dialog_title` | Dialog title (translation key or plain string) |
166+
| `translateChoice`| Optional | `boolean` | `true` | Whether to translate `optionText` values |
167+
168+
## `filters` and `actions`
169+
170+
Use `filters` and `actions` to provide list-style controls in the dialog toolbar:
171+
172+
```tsx
173+
import {
174+
DataTable,
175+
FilterButton,
176+
ReferenceInput,
177+
TextInput,
178+
TopToolbar,
179+
} from 'react-admin';
180+
import { DataTableInput } from '@react-admin/ra-form-layout';
181+
182+
const supplierFilters = [
183+
<TextInput key="q" source="q" label="Search" alwaysOn />,
184+
<TextInput key="country" source="country" />,
185+
<TextInput key="category" source="category" />,
186+
];
187+
188+
const SupplierActions = () => (
189+
<TopToolbar>
190+
<FilterButton />
191+
</TopToolbar>
192+
);
193+
194+
<ReferenceInput source="preferred_supplier_id" reference="suppliers">
195+
<DataTableInput filters={supplierFilters} actions={<SupplierActions />}>
196+
<DataTable.Col source="company_name" />
197+
<DataTable.Col source="category" />
198+
<DataTable.Col source="country" />
199+
<DataTable.NumberCol source="lead_time_days" />
200+
</DataTableInput>
201+
</ReferenceInput>;
202+
```
203+
204+
## `dataTableProps`
205+
206+
Use `dataTableProps` to customize table behavior (hidden columns, row selectability, etc.):
207+
208+
```tsx
209+
<ReferenceInput source="preferred_supplier_id" reference="suppliers">
210+
<DataTableInput
211+
dataTableProps={{
212+
hiddenColumns: ['city'],
213+
isRowSelectable: record => record.reliability_score >= 90,
214+
}}
215+
>
216+
<DataTable.Col source="company_name" />
217+
<DataTable.Col source="category" />
218+
<DataTable.Col source="city" />
219+
<DataTable.NumberCol source="reliability_score" />
220+
</DataTableInput>
221+
</ReferenceInput>
222+
```
223+
224+
## `dialogProps`
225+
226+
Use `dialogProps` to customize the underlying Material UI dialog:
227+
228+
```tsx
229+
<ReferenceInput source="preferred_supplier_id" reference="suppliers">
230+
<DataTableInput
231+
title="Select a supplier"
232+
dialogProps={{ maxWidth: 'lg', fullWidth: true }}
233+
>
234+
<DataTable.Col source="company_name" />
235+
<DataTable.Col source="country" />
236+
<DataTable.Col source="city" />
237+
</DataTableInput>
238+
</ReferenceInput>
239+
```

docs/Inputs.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ React-admin provides a set of Input components, each one designed for a specific
7575
| Time | `'14:30:00'` | [`<TimeInput>`](./TimeInput.md) |
7676
| Date & time | `'2022-10-24T19:40:28.003Z'` | [`<DateTimeInput>`](./DateTimeInput.md) |
7777
| Object | `{ foo: 'bar' }` | All inputs (see [ `source`](#source)) |
78-
| Enum | `'foo'` | [`<SelectInput>`](./SelectInput.md), [`<AutocompleteInput>`](./AutocompleteInput.md), [`<RadioButtonGroupInput>`](./RadioButtonGroupInput.md) |
78+
| Enum | `'foo'` | [`<SelectInput>`](./SelectInput.md), [`<AutocompleteInput>`](./AutocompleteInput.md), [`<RadioButtonGroupInput>`](./RadioButtonGroupInput.md), [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" /> |
7979
| Tree node | `42` | [`<TreeInput>`](./TreeInput.md) |
80-
| Foreign key | `42` | [`<ReferenceInput>`](./ReferenceInput.md) |
80+
| Foreign key | `42` | [`<ReferenceInput>`](./ReferenceInput.md), [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" /> |
8181
| Array of objects | `[{ item: 'jeans', qty: 3 }, { item: 'shirt', qty: 1 }]` | [`<ArrayInput>`](./ArrayInput.md) |
8282
| Array of Enums | `['foo', 'bar']` | [`<TextArrayInput>`](./TextArrayInput.md), [`<SelectArrayInput>`](./SelectArrayInput.md), [`<AutocompleteArrayInput>`](./AutocompleteArrayInput.md), [`<CheckboxGroupInput>`](./CheckboxGroupInput.md), [`<DualListInput>`](./DualListInput.md) |
83-
| Array of foreign keys | `[42, 43]` | [`<ReferenceArrayInput>`](./ReferenceArrayInput.md) |
83+
| Array of foreign keys | `[42, 43]` | [`<ReferenceArrayInput>`](./ReferenceArrayInput.md), [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" /> |
8484
| Translations | `{ en: 'Hello', fr: 'Bonjour' }` | [`<TranslatableInputs>`](./TranslatableInputs.md) |
8585
| Related records | `[{ id: 42, title: 'Hello' }, { id: 43, title: 'World' }]` | [`<ReferenceManyInput>`](./ReferenceManyInput.md), [`<ReferenceManyToManyInput>`](./ReferenceManyToManyInput.md), [`<ReferenceNodeInput>`](./ReferenceNodeInput.md), [`<ReferenceOneInput>`](./ReferenceOneInput.md) |
8686

docs/ReferenceArrayInput.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ The child can be:
134134
- [`<SelectArrayInput>`](./SelectArrayInput.md)
135135
- [`<AutocompleteArrayInput>`](./AutocompleteArrayInput.md)
136136
- [`<DualListInput>`](./DualListInput.md)
137-
- [`<CheckboxGroupInput>`](./CheckboxGroupInput.md),
137+
- [`<CheckboxGroupInput>`](./CheckboxGroupInput.md)
138+
- [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" /> from `@react-admin/ra-form-layout`
138139

139140
```jsx
140141
import { ReferenceArrayInput, SelectInput } from 'react-admin';
@@ -144,6 +145,20 @@ import { ReferenceArrayInput, SelectInput } from 'react-admin';
144145
</ReferenceArrayInput>
145146
```
146147

148+
```jsx
149+
import { DataTableInput } from '@react-admin/ra-form-layout';
150+
import { DataTable, ReferenceArrayInput } from 'react-admin';
151+
152+
<ReferenceArrayInput source="reviewer_ids" reference="users">
153+
<DataTableInput multiple>
154+
<DataTable.Col source="full_name" />
155+
<DataTable.Col source="team" />
156+
<DataTable.Col source="timezone" />
157+
<DataTable.Col source="location" />
158+
</DataTableInput>
159+
</ReferenceArrayInput>
160+
```
161+
147162
You can even use a component of your own as child, provided it detects a `ChoicesContext` is available and gets their choices from it.
148163

149164
The choices context value can be accessed with the [`useChoicesContext`](./useChoicesContext.md) hook.

docs/ReferenceInput.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ import { ReferenceInput, SelectInput } from 'react-admin';
142142
</ReferenceInput>
143143
```
144144

145+
If your users need to compare multiple fields before selecting a record, you can use [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" /> from `@react-admin/ra-form-layout`:
146+
147+
```jsx
148+
import { DataTableInput } from '@react-admin/ra-form-layout';
149+
import { DataTable, ReferenceInput } from 'react-admin';
150+
151+
<ReferenceInput source="company_id" reference="companies">
152+
<DataTableInput>
153+
<DataTable.Col source="company_name" />
154+
<DataTable.Col source="country" />
155+
<DataTable.Col source="city" />
156+
<DataTable.Col source="industry" />
157+
</DataTableInput>
158+
</ReferenceInput>
159+
```
160+
145161
You can even use a component of your own as child, provided it detects a `ChoicesContext` is available and gets their choices from it.
146162

147163
The choices context value can be accessed with the [`useChoicesContext`](./useChoicesContext.md) hook.

docs/SelectInput.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ The form value for the source must be the selected value, e.g.
5454

5555
**Tip**: If you need to let users select multiple items in the list, check out the [`<SelectArrayInput>`](./SelectArrayInput.md) component.
5656

57+
**Tip**: If your options are numerous or require several columns to disambiguate choices, use [`<DataTableInput>`](./DataTableInput.md)<img class="icon" src="./img/premium.svg" alt="React Admin Enterprise Edition icon" />.
58+
5759
## Props
5860

5961
| Prop | Required | Type | Default | Description |

docs/img/DataTableInput-dialog.png

119 KB
Loading

docs/img/DataTableInput-select.png

104 KB
Loading

docs/navigation.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@
217217
<li {% if page.path == 'DateInput.md' %} class="active beginner" {% else %} class="beginner" {% endif %}><a class="nav-link" href="./DateInput.html"><code>&lt;DateInput></code></a></li>
218218
<li {% if page.path == 'DateRangeInput.md' %} class="active" {% endif %}><a class="nav-link" href="./DateRangeInput.html"><code>&lt;DateRangeInput&gt;</code><img class="premium" src="./img/premium.svg" /></a></li>
219219
<li {% if page.path == 'DateTimeInput.md' %} class="active" {% endif %}><a class="nav-link" href="./DateTimeInput.html"><code>&lt;DateTimeInput&gt;</code></a></li>
220+
<li {% if page.path == 'DataTableInput.md' %} class="active" {% endif %}><a class="nav-link" href="./DataTableInput.html"><code>&lt;DataTableInput&gt;</code><img class="premium" src="./img/premium.svg" /></a></li>
220221
<li {% if page.path == 'DualListInput.md' %} class="active" {% endif %}><a class="nav-link" href="./DualListInput.html"><code>&lt;DualListInput&gt;</code><img class="premium" src="./img/premium.svg" /></a></li>
221222
<li {% if page.path == 'FileInput.md' %} class="active" {% endif %}><a class="nav-link" href="./FileInput.html"><code>&lt;FileInput&gt;</code></a></li>
222223
<li {% if page.path == 'ImageInput.md' %} class="active" {% endif %}><a class="nav-link" href="./ImageInput.html"><code>&lt;ImageInput&gt;</code></a></li>

0 commit comments

Comments
 (0)