Checking Streamlit inputs change to prevent manual input overwrite
Mon Jan 16 2023 02:42:55 GMT+0000 (Coordinated Universal Time)
Saved by @tofufu #python #streamlit
# ORRRRR save the inputs as "old" when submitting: ses["old_input"] = orig_input import streamlit as st st.set_page_config(page_title="PLAYGROUND", layout="wide") # Init session states if "num_changed" not in st.session_state: st.session_state["num_changed"] = False if "select_changed" not in st.session_state: st.session_state["select_changed"] = False if "old_res" not in st.session_state: st.session_state["old_res"] = 0 if "toggle_results" not in st.session_state: st.session_state["toggle_results"] = False # on_change Changed fr selectbox, changed by selectbox is true so it can change the result input def change_fr_select(): st.write("Change fr select") st.session_state["select_changed"] = True st.session_state["num_changed"] = False st.session_state["toggle_results"] = False return # on_change Changed fr num_input, changed by num_input is true to prevent result input from changing def change_fr_num(): st.write("Change fr num") st.session_state["num_changed"] = True st.session_state["select_changed"] = False st.session_state["toggle_results"] = True return # Calc function def calculate(num1, num2): st.write("num_changed", st.session_state["num_changed"]) st.write("select_changed", st.session_state["select_changed"]) st.write("toggle_results", st.session_state["toggle_results"]) res = 0 # selectbox has changed + we can calculate/overwrite input if st.session_state["select_changed"] == True: st.write("selectbox") res = num1 * num2 # indep. num_input has changed + retain "old" answer result elif st.session_state["num_changed"]: st.write("num_input") res = st.session_state["old_res"] return res # TODO checkbox to toggle between updated calculation or (manual) input cols = st.columns((5, 5, 5, 5)) selection = cols[0].selectbox(label="Wheee", options=["one", "two", "three", "four"], on_change=change_fr_select) assert selection is not None list1 = { "one": 2, "two": 6, "three": 9, "four": 0 } list2 = { "one": 1, "two": 8, "three": 4, "four": 3 } num1 = cols[2].number_input(label="Num 1", value=list1[selection], on_change=change_fr_num) num2 = cols[3].number_input(label="Num 2", value=list2[selection], on_change=change_fr_num) together = calculate(num1, num2) st.write(together) result = cols[1].number_input(label="Result", value=together) st.session_state["old_res"] = result # TODO toggle b/w old and new results if st.session_state["toggle_results"] == True: cols[1].checkbox("Different result detected! Click to use new result", help="You changed one of the parameters used to estimate this value. You can choose to use the estimation or keep your current value.") st.write(st.session_state["select_changed"]) st.write(st.session_state["num_changed"]) st.markdown("---") # Implementation # num on_change Changed fr selectbox, changed by selectbox is true so it can change the num1 input def change_fr_select(select_changed, num_changed, toggle_results): """ Change session state indicating that the selectbox has changed to determine if the num1 should be changed Arguments: select_changed {string} -- boolean session state indicating user changed selectbox value num_changed {string} -- boolean session state indicating user changed number_input value toggle_results {string} -- boolean session state indicating we toggle option to switch between manual user input or recalculated modulus value """ st.write("select") st.session_state[select_changed] = True # user has changed selectbox value st.session_state[num_changed] = False # thickness and density should not change modulus st.session_state[toggle_results] = False # toggle whether recalculated modulus or manual input should not appear, selectbox should change the modulus return # select on_change def select_on_change(select_changed, num_changed, old_result, toggle_results, index, case_n): st.write(select_changed, st.session_state[select_changed]) st.write(num_changed, st.session_state[num_changed]) st.write(toggle_results, st.session_state[toggle_results]) res = 0 # selectbox has changed + we can calculate/overwrite input if st.session_state[select_changed] == True: st.write("selectbox") st.session_state[old_result] = False res = 10**(31*st.session_state["num1_layer_" + str(index-1) + "_case_" + str(case_n)] - 1.89*((st.session_state["num2_layer_" + str(index-1) + "_case_" + str(case_n)]**29))) # indep. num_input has changed + retain "old" answer result elif st.session_state[num_changed] == True: st.write("num_input") st.session_state[old_result] = True return res # num on_change Changed fr num_input, changed by number_input is true so it does NOT change the modulus input def change_fr_num(select_changed, num_changed, toggle_results): """ Change session state indicating that the bending stiffness thickness and/or density inputs have changed to determine if the modulus should be changed Arguments: select_changed {string} -- boolean session state indicating user changed selectbox value num_changed {string} -- boolean session state indicating user changed number_input value toggle_results {string} -- boolean session state indicating we toggle option to switch between manual user input or recalculated modulus value """ st.write("num") st.session_state[num_changed] = True # num1 and num2 should change select st.session_state[select_changed] = False # user has not changed selectbox value st.session_state[toggle_results] = True # toggle whether recalculated modulus or manual input should appear, user can toggle between their own or recalculated value return
Check Streamlit inputs, only overwrite num_input widgets if selecting different dropdown selection
Comments