Disclaimer: I can’t share the code itself so I will simulate the logic behind it
Hi all,
I have a st.form object, after some operations that are executed in the backend, I then proceed to actually use the form.
The code looks something like this:
def select_tools() -> None:
multiselect_form = st.form(key='multiselect_form')
st.session_state['message_status'] = st.empty()
# Load a DL model inside the "multiselect_form" context and use
# "st.session_state['message_status']" to show info & success messages accordingly
# Some other functions outside the "multiselect_form" context
with multiselect_form:
multiselect_form.multiselect(label='select tools',
options=list_of_options,
default=None,
key='selected_tools')
multiselect_form.checkbox(label='select all', key='is_all_tools')
multiselect_form.from_submit_button(label='Confirm Selected Tools',
on_click=some_other_func)
Now what I want to do is to disable the button unless the st.session_state['selected_tools'] is not empty or the st.session_state['is_all_tools'] is ticked, I tried writing that condition in the disabled= argument and it was disabled at first but picking a tool or ticking the selectbox didn’t change it.
I tried to assign a variable to the multiselect_form.from_submit_button and then remove the on_click= argument and play with it, the problem was that the variable was never True even after clicking on it.
As far as I know, forms behave a little differently. Values withing widgets will not update until the submit button is clicked. If you need that behavior, recreate the layout without the st.form and your disabled condition should work as intended.
You mean if I don’t need that behavior? because I do need it to wait until the user picks everything he wants from the multiselect menu, I tried to do it before without a form and it would just reset my page after the first pick.
What I want to do now is based on a previous step, and each step and system has to hang and wait for a user interaction so not using a form means that it will go all the way back to step 1 after the user selects an item from the multiselect menu
So if I understand correctly, I should keep track of it (let’s say as st.session_state['step_1']), and then when a user picks something in the multiselection step the rerun phase will skip step 1 by checking if step_1 is in st.session_state?
Something like that. Sometimes just looking at the values in the widgets is enough, but note that they are session state too. The details depend on the specifics.