I would like to build a streamlit app where the user gives some inputs and every time it uses the form_submit_button
button, it will fill a dataframe row by row to collect user data. Currently I have the following app:
import streamlit as st
import pandas as pd
import numpy as np
# page
st.sidebar.header("Submit results")
with st.form('Form1'):
option = st.selectbox(
"Select the tracked you played:",
("ds Mario Kart", "Toad Harbour", "Koopa Cape"))
number = st.slider("Pick a number", 1, 12)
submitted1 = st.form_submit_button('Submit 1')
df = pd.DataFrame(np.array([[option, number]]), columns = ["Track", "Result"])
dfs = []
dfs.append(df)
df_combined = pd.concat(dfs)
st.dataframe(df_combined)
Output:
As you can see it creates the dropdown and slider. These return both a value. When we change the value and hit the submit button, the value does change in the dataframe. Unfortunately, the dataframe keeps being only one row. So I was wondering how we can fill the dataframe row by row every time we hit the submit button?
I adapted your code based on this documentation. Basically it uses session_state to remember data between threads and also a callback onAddRow
associated with the submit button:
import pandas as pd
import streamlit as st
st.sidebar.header("Submit results")
if 'data' not in st.session_state:
st.session_state["data"] = pd.DataFrame(columns=["Track", "Result"])
def onAddRow():
row = pd.DataFrame({'Track':[st.session_state["option"]], 'Result':[st.session_state["number"]]})
st.session_state["data"] = pd.concat([st.session_state["data"], row])
with st.form('Form1'):
st.selectbox("Select track", ("ds Mario Kart", "Toad Harbour", "Koopa Cape"), key="option")
st.slider("Pick a number", 1, 12, key="number")
st.form_submit_button('Submit 1', on_click=onAddRow )
st.dataframe(st.session_state["data"])