Hi there,
I’m looking to have a dataframe within a data_editor “tied” to a set of text_inputs…
- I’d like to be able to edit the values either in the text_inputs or the data_editor and they would both update whenever a change in either was made.
- I’d also like to be able to add new rows via the data_editor and have that add additional text_inputs
Any help would be appreciated, I’ve gotten this far but it seems like the changes only update every other change for some reason:
import streamlit as st
from streamlit import session_state as ss
import pandas as pd
st.set_page_config(layout='wide')
print('app started')
# Load data frame
if 'df' not in ss:
ss['df'] = pd.DataFrame({'strategy': ['strategy1', 'strategy2', 'strategy3'], 'value': ['1', '2', '3']})
print('initializing df')
# Initialize session state for text inputs
for strategy in ss['df']['strategy']:
key = strategy + "_input"
if key not in ss:
ss[key] = ss['df'][ss['df']['strategy'] == strategy]['value'].values[0]
# Function to handle changes in text_input fields
def change_value(key):
strategy = key.split('_')[0]
new_value = ss[key]
ss['df'].loc[ss['df']['strategy'] == strategy, 'value'] = new_value
print('--------------')
print('input changed: ' + key)
print(ss[key])
print(ss['df'])
# Function to handle changes in the data_editor
def change_table():
for index, row in ss['df'].iterrows():
key = row['strategy'] + "_input"
ss[key] = row['value']
print('ss[df_editor]_____________')
print(ss['df_editor'])
# Display the data_editor
edited = st.data_editor(ss['df'], num_rows='dynamic', on_change=change_table, key='df_editor',
column_config={
"strategy": st.column_config.TextColumn(
"strategy",
width="small",
required=True,
),
"value": st.column_config.TextColumn(
"value",
width='large',
required=True,
),
})
# Update the session state DataFrame with the edited DataFrame
ss['df'] = edited
# Synchronize text inputs with the updated DataFrame
for index, row in ss['df'].iterrows():
key = row['strategy'] + "_input"
if key not in ss or ss[key] != row['value']:
ss[key] = row['value']
# Display text_input fields for each strategy
for strategy in ss['df']['strategy']:
key = strategy + "_input"
st.text_input(strategy, key=key, value=ss[key], on_change=lambda key=key: change_value(key))
print('--------------')
print('table changed')
print(ss['df'])