-
Dear community, great piece of work! I am just getting started and this is what I am trying to do: I am working on a small GUI to setup an analysis pipeline to process some samples (biological). I managed to dynamically create a dictionary of samples using mo.state and I can display them using the mo.accordion element. Now, for each of the samples, I would like to add a "remove" button, to remove the associated button from the list. It seems, I am close to a working solution, but I am missing something. Based on the examples in the 'Recipe' section of the documentation, I can create a vstack of buttons. But clicking a button removes always the last element in the samples, not the respective one with the same 'id'. Additionally, I was not able to add the 'remove' buttons to the respective element in the accordion. Based on the code below, I have two questions. 1) How can I add a remove button to each of the elements in the accordion, and 2) how does it work to remove the correct element from the state containing the sample objects? Ultimately, I would like to have the accordion populated with some input fields for each sample and wrap it in a form. That would allow the user to add and remove samples, adjust some parameters and submit everything to be processed. Any input would be highly appreciated! Thank you and cheers!
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This is due to the fact that closures in Python are late-binding. All your
I think you can do this by batching the accordion, which you then assign to a global variable. Then output the accordion in the vstack in another cell. Remember that reactivity only works on global variables in marimo. So instead of what's written in your example code, you'd do something like this: One cell batched_accordion = mo.accordion({...}).batch(**remove_buttons) Another cell mo.vstack([add_sample_button, batched_accordion]) Example code of a batched accordion turned into a form: import marimo
__generated_with = "0.1.78"
app = marimo.App()
@app.cell
def __():
import marimo as mo
return mo,
@app.cell
def __(mo):
btns = {
f"btn_{i}": mo.ui.button(value=i, label=str(i), on_click=lambda v: v + 1)
for i in range(10)
}
content = " | ".join("{" + key + "}" for key in btns)
accordion_form = mo.accordion({"Tip": content}).batch(**btns).form()
accordion_form
return accordion_form, btns, content
@app.cell
def __(accordion_form):
accordion_form.value
return
if __name__ == "__main__":
app.run() |
Beta Was this translation helpful? Give feedback.
This is due to the fact that closures in Python are late-binding. All your
on_click
lambdas bindi
to the last element in your iterable. Here are some references that explain more and show solutions:https://stackoverflow.com/questions/3431676/creating-functions-or-lambdas-in-a-loop-or-comprehension
https://docs.python-guide.org/writing/gotchas/#late-binding-closures
I think you can do this by batching…