How to select only single row in st.data_editor for below detail datafreme

dear sir

I am in the process of creating a master-detail data entry application utilizing Streamlit. When a user selects any record in the master st.data_editor section, the detail st.data_editor showcases all associated records. The user is restricted from selecting multiple records.

Upon selecting a different record, the previously checked checkbox is automatically deselected from master st.data_editor. Both the master and detail st.data_editor have their num_rows configured to “dynamic”. The capability to add and remove records is accessible at any time, enabling the user to add or delete any record from both st.data_editors. Kindly provide me with a sample code.

thank you in advance for your valuable help

regard

Welcome to the Streamlit community, and thanks for your thoughtful question! :blush: 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: