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

Adding dictionary-like access to mo.md when using mo.batch #3589

Open
mimansajaiswal opened this issue Jan 27, 2025 · 3 comments
Open

Adding dictionary-like access to mo.md when using mo.batch #3589

mimansajaiswal opened this issue Jan 27, 2025 · 3 comments
Labels
enhancement New feature or request

Comments

@mimansajaiswal
Copy link

Description

For context, I am developing a web application that processes CSV files for statistical analysis. The application follows multiple decision paths depending on data characteristics. For example, if the data is normalized, specific tests are applied; if not, different tests are implemented or user input is requested before proceeding. Each test may generate multiple outputs and might require linked inputs requiring separate cells, which may also reference each other.

I often end up needing to create nested form structures. Previously, I created a dictionary as suggested in the documentation and it renders perfectly fine using a combination of hstack and vstack. I then decided to render it as a form, which doesn't accept hstack or vstack. So, I attempted to render it using batch. The form method only accepts flattened inputs, which prevents me from nesting it. For instance, while you can reference name, you cannot use name["first"] or name["last"]. Instead, batch requires name_first and name_last, making nested dictionary processing more challenging. I would prefer if mo.md, when used with mo.batch, could accept dictionary-based formats and allow form usage without needing to convert flattened list of variables back to a nested dictionary.

Image

The following code snippet works

markdown = mo.md(
    """
    **Your form.**

    {name_first}
    
    {name_last}
    
    {date}
    """
)

form_inputs = ui.dictionary(
    {
        "name_first": mo.ui.text(label="First Name"),
        "name_last": mo.ui.text(label="Last Name"),
        "date": mo.ui.date(label="date"),
    }
)

form = mo.ui.batch(markdown, form_inputs).form(show_clear_button=True, bordered=False)

The following code snippet doesn't work

markdown = mo.md(
    """
    **Your form.**

    {name["first"]}
    
    {name["last"]}
    
    {date}
    """
)

form_inputs = ui.dictionary(
    {
        "name": ui.dictionary({"first":mo.ui.text(label="First Name"),"last":mo.ui.text(label="Last Name")}),
        "date": mo.ui.date(label="date"),
    }
)

form2 = mo.ui.batch(markdown, form_inputs).form(show_clear_button=True, bordered=False)

As a follow-up point, based on the current implementation, I expected to access the value for changes in the submitted form using either form.value or the form_inputs.value, as dictionaries are designed to be reactive to changes. However, this isn't occurring, likely due to cloning when converting to a form. I'm unclear why this behavior differs, as form.value works while form_inputs.value doesn't.

Suggested solution

The most viable solution would be to enhance mo.md's rendering capabilities with batch to support dictionary-style key access. This would simplify form creation by eliminating the need for separate functions that flatten dictionaries for batch inputs and re-nest form values.

Alternatively, we could implement form creation with guardrails using submit and reset buttons. I am unsure if this would be more challenging to implement though but, it could offer easier improved layout flexibility (using hstack and vstack) compared to the currently needed HTML code.

Alternative

No response

Additional context

No response

@mimansajaiswal mimansajaiswal added the enhancement New feature or request label Jan 27, 2025
@mscolnick
Copy link
Contributor

Thanks for sharing this use-case. Nested dictionaries would be nice for composition and modularity.

We do clone the element, hence the reactivity issue you are seeing. This also helps with composition/re-usability.

I think we can support dictionary access as a dot-path. Maybe instead of {name["first"]}, it would be {name.first}. The first looks like python, while the second is more common in templating languages and don't depend on the quote type.

@mimansajaiswal
Copy link
Author

mimansajaiswal commented Jan 27, 2025

I realized that the following code renders the form correctly (I didn't know Python's string format supported nested dictionaries like this). However, even after submitting the form, form.value remains empty.

markdown = mo.md(
    """
    **Your form.**

    {name[first]}
    
    {name[last]}
    
    {date}
    """
)

form_inputs = ui.dictionary(
    {
        "name": ui.dictionary({"first":mo.ui.text(label="First Name"),"last":mo.ui.text(label="Last Name")}),
        "date": mo.ui.date(label="date"),
    }
)

form = mo.ui.batch(markdown, form_inputs).form(show_clear_button=True, bordered=False)

@mscolnick
Copy link
Contributor

I have a branch to fix this, but does complicate our logic quite a bit and may have some edge cases. I am putting it on pause, but let me know if this becomes a blocker.

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

No branches or pull requests

2 participants