Drag and drop rows in a dataframe

Summary

I don’t know if it is possible, but I want to make an interactive dataframe in my application. In this sense, I’m using the streamlit aggrid, that is known for making possible to drag and drop columns of the dataframe (AgGrid — streamlit-aggrid 0.2.3 documentation). I’m trying to use the following commands to add the function to drag and drop rows.

Steps to reproduce

Code snippet:

import pandas as pd
import streamlit as st
from st_aggrid import AgGrid
from st_aggrid.grid_options_builder import GridOptionsBuilder

data_file = st.file_uploader("Upload CSV",type=["csv"])
if data_file is not None:
    data_file = pd.read_csv(data_file)

gb = GridOptionsBuilder.from_dataframe(data_file)
gb.configure_side_bar()
gb.configure_default_column(rowDrag = True, rowDragManaged = True, rowDragEntireRow = True, rowDragMultiRow=True)
gb.configure_pagination(paginationPageSize=40)
gridOptions = gb.build()
data = AgGrid(data_file,
            height=380,
            gridOptions=gridOptions,
            enable_enterprise_modules=True,
            allow_unsafe_jscode=True,
            paginationPageSize=10,
            theme='streamlit'       
)

If applicable, please provide the steps we should take to reproduce the error or specified behavior.

Expected behavior:

I was expecting to be able to drag and drop rows of the output.

Actual behavior:

It actually drag the rows, but it don’t drop them, ie, the row stays in the place I took it. In this website React Data Grid: Row Dragging (ag-grid.com) there is an example that is exactily what I am aiming for.

Really appreciate any help with this matter.

Same problem here!!


import streamlit as st  # pip install streamlit=1.12.0
import pandas as pd
from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, JsCode # pip install streamlit-aggrid==0.2.3

onRowDragEnd = JsCode("""
function onRowDragEnd(e) {
    console.log('onRowDragEnd', e);
}
""")

getRowNodeId = JsCode("""
function getRowNodeId(data) {
    return data.id
}
""")

onGridReady = JsCode("""
function onGridReady() {
    immutableStore.forEach(
        function(data, index) {
            data.id = index;
            });
    gridOptions.api.setRowData(immutableStore);
    }
""")

onRowDragMove = JsCode("""
function onRowDragMove(event) {
    var movingNode = event.node;
    var overNode = event.overNode;

    var rowNeedsToMove = movingNode !== overNode;

    if (rowNeedsToMove) {
        var movingData = movingNode.data;
        var overData = overNode.data;

        immutableStore = newStore;

        var fromIndex = immutableStore.indexOf(movingData);
        var toIndex = immutableStore.indexOf(overData);

        var newStore = immutableStore.slice();
        moveInArray(newStore, fromIndex, toIndex);

        immutableStore = newStore;
        gridOptions.api.setRowData(newStore);

        gridOptions.api.clearFocusedCell();
    }

    function moveInArray(arr, fromIndex, toIndex) {
        var element = arr[fromIndex];
        arr.splice(fromIndex, 1);
        arr.splice(toIndex, 0, element);
    }
}
""")


data = pd.read_csv('generic`Preformatted text`.csv', sep=';', decimal=',', encoding='latin-1').head(10)

gb = GridOptionsBuilder.from_dataframe(data)
gb.configure_default_column(rowDrag = False, rowDragManaged = True, rowDragEntireRow = False, rowDragMultiRow=True)
gb.configure_column('bloco', rowDrag = True, rowDragEntireRow = True)
gb.configure_grid_options(rowDragManaged = True, onRowDragEnd = onRowDragEnd, deltaRowDataMode = True, getRowNodeId = getRowNodeId, onGridReady = onGridReady, animateRows = True, onRowDragMove = onRowDragMove)
gridOptions = gb.build()

data = AgGrid(data,
            gridOptions=gridOptions,
            allow_unsafe_jscode=True,
            update_mode=GridUpdateMode.MANUAL
)

st.write(data['data'])

Thanks mmazzarino! It worked (: