<SelectInput>
To let users choose a value in a list using a dropdown, use <SelectInput>
. It renders using MUI’s <Select>
.
Usage
Set the choices
attribute to determine the options (with id
, name
tuples):
import { SelectInput } from 'react-admin';
<SelectInput source="category" choices={[
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' },
]} />
If, instead of showing choices as a dropdown list, you prefer to display them as a list of radio buttons, try the <RadioButtonGroupInput>
. And if the list is too big, prefer the <AutocompleteInput>
.
Props
Prop | Required | Type | Default | Description |
---|---|---|---|---|
choices |
Optional | Object[] |
- | List of items to show as options. Required if not inside a ReferenceInput. |
create |
Optional | Element |
- |
A React Element to render when users want to create a new choice |
createLabel |
Optional | string |
ra.action.create |
The label for the menu item allowing users to create a new choice. Used when the filter is empty |
disableValue |
Optional | string |
‘disabled’ | The custom field name used in choices to disable some choices |
emptyText |
Optional | string |
’’ | The text to display for the empty option |
emptyValue |
Optional | any |
’’ | The value to use for the empty option |
onCreate |
Optional | Function |
- |
A function called with the current filter value when users choose to create a new choice. |
options |
Optional | Object |
- | Props to pass to the underlying <SelectInput> element |
optionText |
Optional | string | Function |
name |
Field name of record to display in the suggestion item or function which accepts the current record as argument (record => {string} ) |
optionValue |
Optional | string |
id |
Field name of record containing the value to use as input value |
resettable |
Optional | boolean |
false |
If true , display a button to reset the changes in this input value |
translateChoice |
Optional | boolean |
true |
Whether the choices should be translated |
<SelectInput>
also accepts the common input props.
choices
An array of objects that represents the choices to show in the dropdown. The objects must have at least two fields: one to use for the option name, and the other to use for the option value. By default, <SelectInput>
will use the id
and name
fields.
const choices = [
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' },
];
<SelectInput source="category" choices={choices} />
If the choices have different keys, you can use optionText
and optionValue
to specify which fields to use for the name and value.
const choices = [
{ name: 'programming', label: 'Programming' },
{ name: 'lifestyle', label: 'Lifestyle' },
{ name: 'photography', label: 'Photography' },
];
<SelectInput
source="category"
optionValue="name"
optionText="label"
choices={choices}
/>
<SelectInput>
adds an empty option by default, to let users enter an empty value. You can disable this behavior by marking the input as required using the validate
prop:
import { SelectInput, required } from 'react-admin';
<SelectInput source="category" choices={choices} validate={required()} />
When used inside a <ReferenceInput>
, <SelectInput>
doesn’t need a choices
prop. Instead, it will use the records fetched by <ReferenceInput>
as choices, via the ChoicesContext
.
<ReferenceInput label="Author" source="author_id" reference="authors">
<SelectInput />
</ReferenceInput>
See Using in a ReferenceInput>
below for more information.
disableValue
You can use a custom field name by setting disableValue
prop:
const choices = [
{ _id: 123, full_name: 'Leo Tolstoi', sex: 'M' },
{ _id: 456, full_name: 'Jane Austen', sex: 'F' },
{ _id: 987, full_name: 'Jack Harden', sex: 'M', not_available: true },
];
<SelectInput source="contact_id" choices={choices} optionText="full_name" optionValue="_id" disableValue="not_available" />
emptyText
If the input isn’t required (using validate={required()}
), users can select an empty choice with an empty text ''
as label.
You can override that label with the emptyText
prop.
<SelectInput
source="category"
emptyText="No category selected"
choices={[
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' },
]}
/>
The emptyText
prop accepts either a string or a React Element.
And if you want to hide that empty choice, make the input required.
<SelectInput
source="category"
choices={[
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' },
]}
validate={required()}
/>
emptyValue
If the input isn’t required (using validate={required()}
), users can select an empty choice. The default value for that empty choice is the empty string (''
), or null
if the input is inside a <ReferenceInput>
.
You can override this value with the emptyValue
prop.
<SelectInput
source="category"
emptyValue={0}
choices={[
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' },
]} />
Tip: While you can set emptyValue
to a non-string value (e.g. 0
), you cannot use null
or undefined
, as it would turn the <SelectInput>
into an uncontrolled component. If you need the empty choice to be stored as null
or undefined
, use the parse
prop to convert the default empty value (‘’) to null
or undefined
, or use the sanitizeEmptyValues
prop on the Form component.
options
Use the options
attribute if you want to override any of MUI’s <SelectField>
attributes:
<SelectInput source="category" options={{
maxHeight: 200
}} />
Refer to MUI Select documentation for more details.
optionText
You can customize the choice field to use for the option name, thanks to the optionText
attribute:
// no 'name' field in the choices
const choices = [
{ id: 123, full_name: 'Leo Tolstoi', sex: 'M' },
{ id: 456, full_name: 'Jane Austen', sex: 'F' },
];
<SelectInput source="author_id" choices={choices} optionText="full_name" />
optionText
also accepts a function, so you can shape the option text at will:
const choices = [
{ id: 123, first_name: 'Leo', last_name: 'Tolstoi' },
{ id: 456, first_name: 'Jane', last_name: 'Austen' },
];
const optionRenderer = choice => `${choice.first_name} ${choice.last_name}`;
<SelectInput source="author_id" choices={choices} optionText={optionRenderer} />
optionText
also accepts a React Element, that will be cloned and receive the related choice as the record
prop. You can use Field components there.
const choices = [
{ id: 123, first_name: 'Leo', last_name: 'Tolstoi' },
{ id: 456, first_name: 'Jane', last_name: 'Austen' },
];
const FullNameField = ({ record }) => <span>{record.first_name} {record.last_name}</span>;
<SelectInput source="gender" choices={choices} optionText={<FullNameField />}/>
optionValue
You can customize the choice field to use for the option value, thanks to the optionValue
attribute:
// no 'id' field in the choices
const choices = [
{ _id: 123, name: 'Leo Tolstoi' },
{ _id: 456, name: 'Jane Austen' },
];
<SelectInput source="author_id" choices={choices} optionValue="_id" />
resettable
You can make the SelectInput
component resettable using the resettable
prop. This will add a reset button which will be displayed only when the field has a value.
You can set disabled values by setting the disabled
property of one item:
const choices = [
{ _id: 123, full_name: 'Leo Tolstoi', sex: 'M' },
{ _id: 456, full_name: 'Jane Austen', sex: 'F' },
{ _id: 1, full_name: 'System Administrator', sex: 'F', disabled: true },
];
<SelectInput source="author_id" choices={choices} optionText="full_name" optionValue="_id" />
sx
: CSS API
The <SelectInput>
component accepts the usual className
prop. You can also override many styles of the inner components thanks to the sx
property (as most MUI components, see their documentation about it). This property accepts the following subclasses:
Rule name | Description |
---|---|
& .RaSelectInput-input |
Applied to the underlying ResettableTextField component |
To override the style of all instances of <SelectInput>
using the MUI style overrides, use the RaSelectInput
key.
translateChoice
The choices are translated by default, so you can use translation identifiers as choices:
const choices = [
{ id: 'M', name: 'myroot.gender.male' },
{ id: 'F', name: 'myroot.gender.female' },
];
However, in some cases, you may not want the choice to be translated. In that case, set the translateChoice
prop to false
.
<SelectInput source="gender" choices={choices} translateChoice={false}/>
Note that translateChoice
is set to false
when <SelectInput>
is a child of <ReferenceInput>
.
Using In A ReferenceInput
If you want to populate the choices
attribute with a list of related records, you should decorate <SelectInput>
with <ReferenceInput>
, and leave the choices
empty:
import { SelectInput, ReferenceInput } from 'react-admin';
<ReferenceInput label="Author" source="author_id" reference="authors">
<SelectInput />
</ReferenceInput>
In that case, <SelectInput>
uses the recordRepresentation
to render each choice from the list of possible records. You can override this behavior by setting the optionText
prop:
import { SelectInput, ReferenceInput } from 'react-admin';
<ReferenceInput label="Author" source="author_id" reference="authors">
<SelectInput optionText="last_name" />
</ReferenceInput>
Creating New Choices
The <SelectInput>
can allow users to create a new choice if either the create
or onCreate
prop is provided.
Use the onCreate
prop when you only require users to provide a simple string and a prompt
is enough. You can return either the new choice directly or a Promise resolving to the new choice.
import { SelectInput, Create, SimpleForm, TextInput } from 'react-admin';
const PostCreate = () => {
const categories = [
{ name: 'Tech', id: 'tech' },
{ name: 'Lifestyle', id: 'lifestyle' },
];
return (
<Create>
<SimpleForm>
<TextInput source="title" />
<SelectInput
onCreate={() => {
const newCategoryName = prompt('Enter a new category');
const newCategory = { id: newCategoryName.toLowerCase(), name: newCategoryName };
categories.push(newCategory);
return newCategory;
}}
source="category"
choices={categories}
/>
</SimpleForm>
</Create>
);
}
Use the create
prop when you want a more polished or complex UI. For example an MUI <Dialog>
asking for multiple fields because the choices are from a referenced resource.
import {
SelectInput,
Create,
ReferenceInput,
SimpleForm,
TextInput,
useCreate,
useCreateSuggestionContext
} from 'react-admin';
import {
Box,
BoxProps,
Button,
Dialog,
DialogActions,
DialogContent,
TextField,
} from '@mui/material';
const PostCreate = () => {
return (
<Create>
<SimpleForm>
<TextInput source="title" />
<ReferenceInput source="category_id" reference="categories">
<SelectInput create={<CreateCategory />} />
</ReferenceInput>
</SimpleForm>
</Create>
);
}
const CreateCategory = () => {
const { filter, onCancel, onCreate } = useCreateSuggestionContext();
const [value, setValue] = React.useState(filter || '');
const [create] = useCreate();
const handleSubmit = event => {
event.preventDefault();
create(
'categories',
{
data: {
title: value,
},
},
{
onSuccess: (data) => {
setValue('');
onCreate(data);
},
}
);
};
return (
<Dialog open onClose={onCancel}>
<form onSubmit={handleSubmit}>
<DialogContent>
<TextField
label="New category name"
value={value}
onChange={event => setValue(event.target.value)}
autoFocus
/>
</DialogContent>
<DialogActions>
<Button type="submit">Save</Button>
<Button onClick={onCancel}>Cancel</Button>
</DialogActions>
</form>
</Dialog>
);
};