I obtained this code from Google to test the drag-and-drop functionality for uploading multiple Excel files into a dataframe across two containers. However, the code is producing an error. Please review the error message and provide the corrected code that will enable dataframe drag-and-drop functionality between two st.container elements in Streamlit. Thank you for your assistance.
# 2. Initialize session state for containers if not present
if “containers” not in st.session_state:
st.session_state.containers = {}
if uploaded_files:
for idx, file in enumerate(uploaded_files):
container_key = f"container\_{idx}\_{[file.name](http://file.name/)}"
\# Read data and extract row names/values as a list for dnd
df = pd.read_excel(file)
rows = df.iloc\[:, 0\].dropna().astype(str).tolist()\[:10\] # First 10 items of col 1
if container_key not in st.session_state.containers:
st.session_state.containers\[container_key\] = rows
# 3. Apply any pending drag-and-drop moves from previous interaction
res = apply_move(st.session_state.containers)
if res:
st.session_state.containers = res
st.rerun()
# 4. Render the containers and items
if st.session_state.containers:
for c_key, items in st.session_state.containers.items():
with st.container(key=c_key, border=True):
st.markdown(f"\*\*{c_key.split('\_', 2)\[-1\]}\*\*")
for item in items:
with st.container(key=f"item\_{c_key}\_{item}", border=True):
st.write(item)
\# 5. Activate dnd tracking for these container keys
dnd(list(st.session_state.containers.keys()))
Welcome to the Streamlit community, and thanks for sharing your code and error! The error occurs because the apply_move() function from the streamlit-dnd package expects two arguments: the event dictionary (from dnd()) and the list(s) you want to update, but your code is only passing one argument. Also, the drag-and-drop functionality provided by streamlit-dnd works for reordering or moving items between containers, not for dragging entire DataFrames between containers. You can, however, drag and drop list items (e.g., row names) between containers.
Here’s a corrected and minimal example for drag-and-drop of row names between two containers using streamlit-dnd (not full DataFrames):
import streamlit as st
import pandas as pd
from streamlit_dnd import dnd, apply_move
st.title("Multiple Excel Drag-and-Drop Loader")
# 1. Upload multiple Excel files
uploaded_files = st.file_uploader(
"Choose Excel files", type=["xlsx"], accept_multiple_files=True
)
# 2. Initialize session state for two containers
if "container_a" not in st.session_state:
st.session_state.container_a = []
if "container_b" not in st.session_state:
st.session_state.container_b = []
# 3. Load data from uploaded files into container_a
if uploaded_files:
rows = []
for file in uploaded_files:
df = pd.read_excel(file)
rows.extend(df.iloc[:, 0].dropna().astype(str).tolist()[:10])
st.session_state.container_a = rows
st.session_state.container_b = []
# 4. Render containers and enable drag-and-drop
with st.container(key="container_a", border=True):
st.write("Container A")
for item in st.session_state.container_a:
with st.container(key=f"item_a_{item}", border=True):
st.write(item)
with st.container(key="container_b", border=True):
st.write("Container B")
for item in st.session_state.container_b:
with st.container(key=f"item_b_{item}", border=True):
st.write(item)
# 5. Activate drag-and-drop and apply moves
event = dnd("container_a", "container_b")
if event:
apply_move(event, st.session_state)
st.rerun()
This will let you drag row names between two containers. For full DataFrame drag-and-drop, Streamlit does not natively support this—only list items can be moved using streamlit-dnd (see streamlit-dnd docs and demo).