How to use multi dataframe in streamlit_dnd

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.

import streamlit as st

import pandas as pd

from streamlit_dnd import dnd, apply_move

# Initialize 5 dataframes in session state

if “dfs” not in st.session_state:

st.session_state.dfs = {

    "df1": pd.DataFrame({"Data": \["Item A", "Item B"\]}),

    "df2": pd.DataFrame({"Data": \["Item C", "Item D"\]}),

    "df3": pd.DataFrame({"Data": \["Item E", "Item F"\]}),

    "df4": pd.DataFrame({"Data": \["Item G", "Item H"\]}),

    "df5": pd.DataFrame({"Data": \["Item I", "Item J"\]}),

}

# Display each dataframe in a draggable container

container_key = “my_dnd_list”

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)

# Handle drag-and-drop events

drop_event = dnd(container_key)

if drop_event:

apply_move(drop_event, st.session_state.dfs)



st.rerun()

see error

KeyError: ‘my_dnd_list’

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]
~~~~~^^^^^^^^^^^^^^^^^^^^^^

please see my code and give the solution

best regards

Welcome to the Streamlit community, and thanks for sharing your code and error details! :blush: 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!

Sources:

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.

Sir, I appreciate your valuable assistance with the code execution.

I require further help; I need to implement a two-column layout on the pages for a drag-and-drop functionality that allows items to be moved from one container to another. I have some code I found on Google, but it has resulted in numerous errors. Please review the code and the errors, and assist me with the drag-and-drop process for the two columns.

see code

import streamlit as st

from streamlit_dnd import dnd, apply_move

# Initialize items in st.session_state

if “items2” not in st.session_state:

st.session_state.items2 = {

    "left": \["Task A", "Task B", "Task C","Task D"\],

    "right":  \["Task 1A"\]

}

col1, col2 = st.columns(2)

# Render containers and their children

with col1:

with st.container(key="left", border=True):

    st.subheader("To Do")

    for it in st.session_state.items2\["left"\]:

        with st.container(key=f"item\_{it}", border=True):

            st.write(it)

with col2:

with st.container(key="right", border=True):

    st.subheader("Done")

    for it in st.session_state.items2\["right"\]:

        with st.container(key=f"item\_{it}", border=True):

            st.write(it)

# Call dnd AFTER rendering the containers

event = dnd(“left”, “right”)

# Apply the move and rerun to reflect changes

if event:

apply_move(event, st.session_state.items2)

st.rerun()

if st.button(‘Click Me’):

st.write('Button was clicked!')

# 3. Read or loop through all elements belonging to that container

for element_name2 in st.session_state.items2\["right"\]:

    current_value = st.session_state.get(element_name2)

    st.write(f"Element Name: \`{element_name2}\` | Value: \`{current_value}\`")

see error

IndexError: pop index out of range

File “D:\pyff\dndcolwise.py”, line 33, in
apply_move(event, st.session_state.items2)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\user\AppData\Local\Programs\Python\Python314\Lib\site-packages\streamlit_dnd\_init_.py”, line 270, in apply_move
item = src.pop(event.from_index)

thank you for your help