Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi_select somewhat usable #1861

Merged
merged 5 commits into from
Oct 20, 2023
Merged

Conversation

masenf
Copy link
Collaborator

@masenf masenf commented Sep 24, 2023

Try to address #1791, but this component is cursed.

Because of how the component expects to get certain props (options is a list of dict rather than child components, so rx.foreach cannot be used). It's not a great candidate for wrapping in reflex because Var operations have to compile down to frontend javascript and the transformations necessary to make the component ergonomic to use are not currently implemented.

And it looks like the component was contributed without tests or documentation, which makes it even harder to use, understand and catch behavioral regressions.

I have some small tweaks in this PR that make it actually possible to work with it, although it's not the nicest component and I'm not sure if/how it works with rx.form... Basically it needs some serious love and attention from someone who deeply understands reflex internals (and might even require some refactoring of rx.foreach to emit Var in addition to Component.)

Here is some sample code that can run with this PR

pip install git+https://github.com/reflex-dev/reflex@masenf/multi-select-somewhat-usable
import reflex as rx


class State(rx.State):
    allowed_options: list[str] = ["Foo", "bar", "baz", "qux", "quux", "corge", "grault"]
    
    @rx.var
    def multi_select_options(self) -> list[dict[str, str]]:
        return [
            {"label": o, "value": o}
            for o in self.allowed_options
        ]

    def handle_multi_select(self, values: list[str]):
        print(f"Selected: {values}")


def index() -> rx.Component:
    return rx.fragment(
        rx.color_mode_button(rx.color_mode_icon(), float="right"),
        rx.vstack(
            rx.heading("Welcome to Reflex!", font_size="2em"),
            rx.multi_select(
                #options=[
                #    rx.multi_select_option(label=o, value=o)
                #    for o in ["Foo", "bar", "baz", "qux", "quux", "corge", "grault"]
                #],
                options=State.multi_select_options,
                is_multi=True,
                on_change=State.handle_multi_select,
            ),
        ),
    )


app = rx.App()
app.add_page(index)
app.compile()

@masenf
Copy link
Collaborator Author

masenf commented Oct 1, 2023

also needs

diff --git a/reflex/components/forms/multiselect.py b/reflex/components/forms/multiselect.py
index 9625e15..430418b 100644
--- a/reflex/components/forms/multiselect.py
+++ b/reflex/components/forms/multiselect.py
@@ -48,6 +48,7 @@ class Select(Component):
 
     library = "chakra-react-select"
     tag = "Select"
+    alias = "MultiSelect"
 
     # Focus the control when it is mounted
     auto_focus: Var[bool]

allow it to be used along with normal Select component
@masenf masenf changed the title [WiP] multi_select somewhat usable multi_select somewhat usable Oct 18, 2023
Copy link
Contributor

@picklelo picklelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works for me

@picklelo picklelo merged commit fe244b7 into main Oct 20, 2023
37 checks passed
@masenf masenf deleted the masenf/multi-select-somewhat-usable branch October 22, 2023 17:04
@cyrus0880
Copy link

i use same code
but on ui click the select box is not any response
reflex
not show options

@topkek-issou
Copy link

Hi @masenf
Thanks for the fix, really useful!

Is there a way to populate it on the UI with a few selected options from the backend? Like with other components, we can use the value attribute to fill it with state vars.

So for example I have a select with Monday, Tuesday, ..., Sunday options.
And I'd like to use a state var to prefill the component with, say, State.defaults, which would be Tuesday and Thursday.
image

Thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants