Welcome to the Streamlit community, and thanks for your thoughtful question!
What you want is a classic “master-detail” interface with single-row selection in the master table, dynamic add/delete in both tables, and automatic deselection when a new master row is picked. Streamlit’s st.data_editor doesn’t natively support single-row selection, but you can achieve this with a Checkbox column and some session state logic.
Here’s a sample implementation based on best practices and community solutions. This code ensures only one master row can be selected at a time, and updates the detail table accordingly. Both editors allow dynamic row management.
import streamlit as st
import pandas as pd
# Initialize session state for master and detail data
if "master_df" not in st.session_state:
st.session_state.master_df = pd.DataFrame([
{"ID": 1, "Name": "Alice", "selected": False},
{"ID": 2, "Name": "Bob", "selected": False},
{"ID": 3, "Name": "Charlie", "selected": False},
])
if "detail_df" not in st.session_state:
st.session_state.detail_df = pd.DataFrame([
{"MasterID": 1, "Detail": "Alice detail 1"},
{"MasterID": 1, "Detail": "Alice detail 2"},
{"MasterID": 2, "Detail": "Bob detail 1"},
])
def on_master_change():
# Only allow one selection at a time
edited_rows = st.session_state.master_editor.get("edited_rows", {})
if edited_rows:
# Get the index of the changed row
idx = next(iter(edited_rows))
# Deselect all, then select only the current
st.session_state.master_df["selected"] = False
st.session_state.master_df.at[idx, "selected"] = True
st.write("## Master Table")
master_df = st.data_editor(
st.session_state.master_df,
key="master_editor",
num_rows="dynamic",
column_config={
"selected": st.column_config.CheckboxColumn("Select", required=False)
},
on_change=on_master_change,
use_container_width=True,
)
# Find selected master row
selected_rows = master_df[master_df["selected"]]
if not selected_rows.empty:
selected_id = selected_rows.iloc[0]["ID"]
else:
selected_id = None
st.write("## Detail Table")
if selected_id is not None:
# Show only details for selected master
detail_df = st.session_state.detail_df[st.session_state.detail_df["MasterID"] == selected_id]
else:
detail_df = pd.DataFrame(columns=["MasterID", "Detail"])
# Allow editing/adding/deleting details
edited_detail_df = st.data_editor(
detail_df,
key="detail_editor",
num_rows="dynamic",
use_container_width=True,
)
# Optionally, update session state with new/edited details here
This approach is based on community best practices for single-row selection and dynamic editing in st.data_editor, as discussed in Streamlit forum threads and the Streamlit documentation.
Sources: