How to create two columns drag and drop app by using streamlit_dnd

dear sir

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.

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)

Welcome to the Streamlit community! Thanks for sharing your code and error details—you’re definitely on the right track with streamlit-dnd for drag-and-drop between columns. The error you’re seeing, IndexError: pop index out of range, usually means the drag-and-drop event is trying to move an item from a list index that doesn’t exist, often due to a mismatch between the UI and the underlying data structure.

Here’s a step-by-step, minimal example for a two-column drag-and-drop layout using streamlit-dnd, based on the official streamlit-dnd demo:

import streamlit as st
from streamlit_dnd import dnd, apply_move

# Initialize items in session state
if "items" not in st.session_state:
    st.session_state.items = {
        "left": ["Task A", "Task B", "Task C", "Task D"],
        "right": ["Task 1A"]
    }

col1, col2 = st.columns(2)

# Render left column
with col1:
    with st.container(key="left", border=True):
        st.subheader("To Do")
        for it in st.session_state.items["left"]:
            with st.container(key=f"item_{it}", border=True):
                st.write(it)

# Render right column
with col2:
    with st.container(key="right", border=True):
        st.subheader("Done")
        for it in st.session_state.items["right"]:
            with st.container(key=f"item_{it}", border=True):
                st.write(it)

# Enable drag-and-drop after rendering containers
event = dnd("left", "right")

# Apply move and rerun if an event occurred
if event:
    apply_move(event, st.session_state.items)
    st.rerun()

Key points:

  • Use the same keys (“left”, “right”) for both the containers and the dnd function.
  • Always call dnd() after rendering the containers.
  • Only call apply_move() and st.rerun() if event is not None.
  • Make sure the lists in st.session_state.items are not being modified elsewhere during the same rerun.

If you still see the error, double-check that the items in your lists are unique and that the UI matches the state. If possible, share a minimum reproducible example or your full code/repo for more targeted help. Community members, feel free to jump in with your insights!

Sources: