def create_new_form():
with st.form("myform"):
x = st.text_input("Foo", key="foo")
submit = st.form_submit_button(label="Submit")
if submit:
st.write('Submitted')
st.write(x)
If I run this, the form prints the values properly.
create_new_form()
But if I wrap the above function within a buttonclick (run the below instead), nothing is written and its in its original state
newScenario = st.button('Create New Scenario', key='a')
if newScenario:
create_new_form()
Wondering if this is a bug or something is wrong with my approach?
It may be the latter By the way, you haven’t defined the clear_form function, so I can’t comment on it.
But the larger issue is that you’re conditionally displaying the form based on an st.button click. When you click the newScenario button and then click the form submit button, the app reruns from top to bottom and sets the clicked state of the newScenario button to be false → form is no longer displayed.
The solution may be to set clear_on_submit=True in st.form
import streamlit as st
def create_new_form():
with st.form("myform", clear_on_submit=True):
x = st.text_input("Foo", key="foo")
submit = st.form_submit_button(label="Submit")
if submit:
st.write("Submitted")
st.write(x)
create_new_form()
thanks for the explanation!
Can you instead run the below? This will help you understand what I meant.
import streamlit as st
def create_new_form():
with st.form("myform", clear_on_submit=True):
x = st.text_input("Foo", key="foo")
submit = st.form_submit_button(label="Submit")
if submit:
st.write("Submitted")
st.write(x)
# create_new_form()
newScenario = st.button('Create New Scenario', key='a')
if newScenario:
create_new_form()
Pardon my ignorance here, but I expected the process to write “Submitted” and the value of “x” to be printed on the screen. Instead the form disappears. while I understand that streamlit executes the script in steps, the form_submit_button seem to collide with the st.button and resets it.
Yeah, I completely missed the point. Buttons don’t have state, so after you click Submit the script reruns and now the application does not remember that you had clicked Create New Scenario so the function create_new_form_() is not called.
You can use session_state to remember tha fact that the button has been pressed.
import streamlit as st
from streamlit import session_state as ss
def create_new_form():
with st.form("myform", clear_on_submit=True):
x = st.text_input("Foo", key="foo")
submit = st.form_submit_button(label="Submit")
if submit:
st.write("Submitted")
st.write(x)
if "show_form" not in ss:
ss["show_form"] = False
newScenario = st.button("Create New Scenario", key="a")
if newScenario:
ss["show_form"] = True
if ss["show_form"]:
create_new_form()
Thank you for sharing this information. This works fine for this scenario. However, The challenge with this approach is that there may be some radio buttons and progress bar etc and they won’t reflect until the state gets updated. Whereas, I would like to show it in realtime.
For instance, consider this code below.
Ideal state is, when user is typing, I would like to show progress. Also, see the radio button they have selected, validate the amount they have typed etc. Anyway I can achieve while user is typing realtime instead of waiting until we submit the form?
import streamlit as st
import pandas as pd
state = st.session_state
def show_progress(unit):
progressText = 'Total Amount Status'
if unit > 100:
st.progress(100, text=progressText)
else:
st.progress(int(unit), text=progressText)
def validate_amt(total_amt, key):
if key in state:
val = state[key]['edited_cells']
totalSum = []
for k, v in val.items():
totalSum.append(v)
show_progress(int((sum(totalSum) * 100) / total_amt))
if sum(totalSum) > total_amt:
st.error("Exceeded Total")
else:
st.info(f"total={totalSum}")
def create_departments_form():
return pd.DataFrame(
{
"Department": ['d1', 'd2', 'd3'],
"Amount": [0] * 3
}
)
def create_new_scenario_form():
with st.form("myform1", clear_on_submit=True):
c1, c2 = st.columns(2)
with c1:
formName = st.text_input("Name your form")
with c2:
total_amount = st.number_input("Target amount", value=10000)
if len(formName) > 0:
pass
else:
st.error("Provide form name")
split_amt = st.radio("How do you want to split the amount?", ('Amount', 'Percentage'))
st.write(f"picked = {split_amt}")
key = "dept_amt" if split_amt == "Amount" else "dept_pcnt"
departments = create_departments_form()
dataEdit = st.experimental_data_editor(departments,
key=key,
on_change=validate_amt(total_amount, key))
dataEdit['form_name'] = formName
# Submit button
submit = st.form_submit_button("Save Scenario")
if submit:
st.write("submitted")
st.write(dataEdit)
create_new_scenario_form()
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.