Conditionally disabling st.form_submit_button

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',
        multiselect_form.checkbox(label='select all', key='is_all_tools')
        multiselect_form.from_submit_button(label='Confirm Selected Tools',

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.

Any suggestions?

Hi @ImSo3K

You can try the approach in this medium article.

Hi @CarlosSerrano ,

My checkbox works as intended, the logic of the all selection happens in the function that the submit button invokes.

I’m having an issue with the fact that it is clickable when nothing was selected from the multiselect menu and the “select all” tick wasnt ticked.

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

No, the application can keep track of whether step 1 has already been executed or not and act differently based on that knowledge.

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.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.