dear sir I am attempting to utilize five dataframes in streamlit_dnd for drag-and-drop functionality, allowing users to move them within Streamlit containers.
Please review the code I obtained from Google, as it is generating an error.
with st.container(key=container_key, border=True):
for df_key, df_val in st.session_state.dfs.items():
with st.container(key=f"item\_{df_key}", border=True):
st.write(f"### {df_key.upper()}")
st.dataframe(df_val)
File “D:\pyff\dndwdf.py”, line 27, in
apply_move(drop_event, st.session_state.dfs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\user\AppData\Local\Programs\Python\Python314\Lib\site-packages\streamlit_dnd\_init_.py”, line 267, in apply_move
src = lists[event.from_container]
~~~~~^^^^^^^^^^^^^^^^^^^^^^
Welcome to the Streamlit community, and thanks for sharing your code and error details! The issue seems to be that you’re passing st.session_state.dfs (a dict of DataFrames) to apply_move, but streamlit-dnd expects a dict where each key is a container key (like “df1”, “df2”, etc.) and each value is a list of items, not DataFrames. Also, your container structure doesn’t match the expected usage for multi-list drag-and-drop—each draggable list should have its own container and key, not a single “my_dnd_list” container.
It seems likely that you should create five separate containers (one for each DataFrame/list), each with its own key, and pass those keys to dnd(). Your lists should be simple lists (not DataFrames) for drag-and-drop, and you can convert them to DataFrames for display if needed. See the streamlit-dnd demo and docs for the correct pattern. Here’s a minimal working example:
import streamlit as st
from streamlit_dnd import dnd, apply_move
# Initialize lists in session state
if "items" not in st.session_state:
st.session_state.items = {
"df1": ["Item A", "Item B"],
"df2": ["Item C", "Item D"],
"df3": ["Item E", "Item F"],
"df4": ["Item G", "Item H"],
"df5": ["Item I", "Item J"],
}
# Render each list in its own container
for key in st.session_state.items:
with st.container(key=key, border=True):
for item in st.session_state.items[key]:
st.write(item)
# Enable drag-and-drop between containers
event = dnd("df1", "df2", "df3", "df4", "df5")
if event:
apply_move(event, st.session_state.items)
st.rerun()
If you want to display as DataFrames, convert the lists to DataFrames just for st.dataframe(). Let us know if you need more detail or want to adapt this for DataFrames!
One issue is that the elements that become draggable must be Streamlit components. If you want your dataframes to be separately draggable, you will have to put each of them in a container.