Widgets can change if they are defined outside the form but are positioned inside the form using a placeholder like st.empty
. Not sure if that is expected behavior or not, but looks like a feature to me
Code:
import streamlit as st
with st.form("myform"):
"### A form"
# These exist within the form but won't wait for the submit button
placeholder_for_radio = st.empty()
placeholder_for_selectbox = st.empty()
# Other components actually wait for the submit button
number = st.number_input("Add a number", 0, 10, 1, 1)
submit_button = st.form_submit_button("Submit!")
# Create radio and selectbox outside the form
with placeholder_for_radio:
radio_option = st.radio("`st.radio`", ["Plants", "Animals"], horizontal=True)
with placeholder_for_selectbox:
options = dict(
Plants = ["๐ฑ", "๐ฟ", "๐ชด"],
Animals = ["๐", "๐ฆ", "๐"]
)
selection = st.selectbox("`st.selectbox`", options=options[radio_option])
# This is just to show the app behavior
with st.sidebar:
"#### `st.radio` and `st.selectbox` don't wait for `st.form_submit_button` to be clicked to update their value"
st.info(f"`st.radio` = *{radio_option}*")
st.info(f"`st.selectbox` = *{selection}*")
"#### But the other components within `st.form` do wait for `st.form_submit_button` to be clicked to update their value"
st.info(f"{number}")
if submit_button:
st.info(f"""
Form submitted with
- `{radio_option = }`
- `{selection = }`
- `{number = }`""")
else:
st.warning("`st.form_submit_button` has not been clicked yet")