reflex/docs/library/forms/select-ll.md
2024-02-26 17:18:28 +01:00

297 lines
9.1 KiB
Markdown

---
components:
- rx.radix.select
- rx.radix.select.root
- rx.radix.select.trigger
- rx.radix.select.content
- rx.radix.select.group
- rx.radix.select.item
- rx.radix.select.label
- rx.radix.select.separator
---
```python exec
import random
import reflex as rx
import reflex.components.radix.primitives as rdxp
from pcweb.templates.docpage import style_grid
```
# Select
Displays a list of options for the user to pick from, triggered by a button.
## Basic Example
```python demo
rx.select.root(
rx.select.trigger(),
rx.select.content(
rx.select.group(
rx.select.label("Fruits"),
rx.select.item("Orange", value="orange"),
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape", disabled=True),
),
rx.select.separator(),
rx.select.group(
rx.select.label("Vegetables"),
rx.select.item("Carrot", value="carrot"),
rx.select.item("Potato", value="potato"),
),
),
default_value="apple",
)
```
## Usage
## Disabling
It is possible to disable individual items in a `select` using the `disabled` prop associated with the `rx.select.item`.
```python demo
rx.select.root(
rx.select.trigger(placeholder="Select a Fruit"),
rx.select.content(
rx.select.group(
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape", disabled=True),
rx.select.item("Pineapple", value="pineapple"),
),
),
)
```
To prevent the user from interacting with select entirely, set the `disabled` prop to `True` on the `rx.select.root` component.
```python demo
rx.select.root(
rx.select.trigger(placeholder="This is Disabled"),
rx.select.content(
rx.select.group(
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape"),
),
),
disabled=True,
)
```
## Setting Defaults
It is possible to set several default values when constructing a `select`.
The `placeholder` prop in the `rx.select.trigger` specifies the content that will be rendered when `value` or `default_value` is empty or not set.
```python demo
rx.select.root(
rx.select.trigger(placeholder="pick a fruit"),
rx.select.content(
rx.select.group(
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape"),
),
),
)
```
The `default_value` in the `rx.select.root` specifies the value of the `select` when initially rendered.
The `default_value` should correspond to the `value` of a child `rx.select.item`.
```python demo
rx.select.root(
rx.select.trigger(),
rx.select.content(
rx.select.group(
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape"),
),
),
default_value="apple",
)
```
## Fully controlled
The `on_change` event trigger is fired when the value of the select changes.
In this example the `rx.select_root` `value` prop specifies which item is selected, and this
can also be controlled using state and a button without direct interaction with the select component.
```python demo exec
class SelectState2(rx.State):
values: list[str] = ["apple", "grape", "pear"]
value: str = ""
def choose_randomly(self):
"""Change the select value var."""
original_value = self.value
while self.value == original_value:
self.value = random.choice(self.values)
def select_example2():
return rx.vstack(
rx.select.root(
rx.select.trigger(placeholder="No Selection"),
rx.select.content(
rx.select.group(
rx.foreach(SelectState2.values, lambda x: rx.select.item(x, value=x))
),
),
value=SelectState2.value,
on_change=SelectState2.set_value,
),
rx.button("Choose Randomly", on_click=SelectState2.choose_randomly),
rx.button("Reset", on_click=SelectState2.set_value("")),
)
```
The `open` prop and `on_open_change` event trigger work similarly to `value` and `on_change` to control the open state of the select.
If `on_open_change` handler does not alter the `open` prop, the select will not be able to be opened or closed by clicking on the
`select_trigger`.
```python demo exec
class SelectState8(rx.State):
is_open: bool = False
def select_example8():
return rx.flex(
rx.select.root(
rx.select.trigger(placeholder="No Selection"),
rx.select.content(
rx.select.group(
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape"),
),
),
open=SelectState8.is_open,
on_open_change=SelectState8.set_is_open,
),
rx.button("Toggle", on_click=SelectState8.set_is_open(~SelectState8.is_open)),
spacing="2",
)
```
### Submitting a Form with Select
When a select is part of a form, the `name` prop of the `rx.select.root` sets the key that will be submitted with the form data.
The `value` prop of `rx.select.item` provides the value to be associated with the `name` key when the form is submitted with that item selected.
When the `required` prop of the `rx.select.root` is `True`, it indicates that the user must select a value before the form may be submitted.
```python demo exec
class FormSelectState(rx.State):
form_data: dict = {}
def handle_submit(self, form_data: dict):
"""Handle the form submit."""
self.form_data = form_data
def form_select():
return rx.flex(
rx.form.root(
rx.flex(
rx.select.root(
rx.select.trigger(),
rx.select.content(
rx.select.group(
rx.select.label("Fruits"),
rx.select.item("Orange", value="orange"),
rx.select.item("Apple", value="apple"),
rx.select.item("Grape", value="grape"),
),
rx.select.separator(),
rx.select.group(
rx.select.label("Vegetables"),
rx.select.item("Carrot", value="carrot"),
rx.select.item("Potato", value="potato"),
),
),
default_value="apple",
name="select",
),
rx.button("Submit"),
width="100%",
direction="column",
spacing="2",
),
on_submit=FormSelectState.handle_submit,
reset_on_submit=True,
),
rx.divider(size="4"),
rx.heading("Results"),
rx.text(FormSelectState.form_data.to_string()),
width="100%",
direction="column",
spacing="2",
)
```
## Real World Example
```python demo
rx.card(
rx.flex(
rx.image(src="/reflex_banner.png", width="100%", height="auto"),
rx.flex(
rx.heading("Reflex Swag", size="4", margin_bottom="4px"),
rx.heading("$99", size="6", margin_bottom="4px"),
direction="row", justify="between",
width="100%",
),
rx.text("Reflex swag with a sense of nostalgia, as if they carry whispered tales of past adventures", size="2", margin_bottom="4px"),
rx.divider(size="4"),
rx.flex(
rx.flex(
rx.text("Color", size="2", margin_bottom="4px", color_scheme="gray"),
rx.select.root(
rx.select.trigger(),
rx.select.content(
rx.select.group(
rx.select.item("Light", value="light"),
rx.select.item("Dark", value="dark"),
),
),
default_value="light",
),
direction="column",
),
rx.flex(
rx.text("Size", size="2", margin_bottom="4px", color_scheme="gray"),
rx.select.root(
rx.select.trigger(),
rx.select.content(
rx.select.group(
rx.select.item("24", value="24"),
rx.select.item("26", value="26"),
rx.select.item("28", value="28", disabled=True),
rx.select.item("30", value="30"),
rx.select.item("32", value="32"),
rx.select.item("34", value="34"),
rx.select.item("36", value="36"),
),
),
default_value="30",
),
direction="column",
),
rx.button(rx.icon(tag="plus"), "Add"),
align="end",
justify="between",
spacing="2",
width="100%",
),
width="15em",
direction="column",
spacing="2",
),
)
```