How to use session state with Aggrid to keep the selection even after switching pages?

This is potentially an easy one, but I just can’t figure out how to do it. Here’s a simple reproducible code example. How to use session state to keep the tickbox selection, even after switching pages (you will need to create a page folder to include multi pages)?

import pandas as pd
import streamlit as st
from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, DataReturnMode, ColumnsAutoSizeMode


data = {
    "calories": [420, 380, 390],
    "duration": [50, 40, 45],
    "random1": [5, 12, 1],
    "random2": [230, 23, 1]
}

df = pd.DataFrame(data)

gb = GridOptionsBuilder.from_dataframe(df[["calories", "duration"]])
gb.configure_selection(selection_mode="single", use_checkbox=True)
gb.configure_side_bar()
gridOptions = gb.build()

data = AgGrid(df,
              gridOptions=gridOptions,
              enable_enterprise_modules=True,
              allow_unsafe_jscode=True,
              update_mode=GridUpdateMode.SELECTION_CHANGED,
              columns_auto_size_mode=ColumnsAutoSizeMode.FIT_CONTENTS)

selected_rows = data["selected_rows"]

if len(selected_rows) != 0:
    selected_rows[0]

For example, when I select the tickbox, and after I switch to page 2, then back to test page, the tickbox selection still remains.

2 Likes

@subaruspirit
Below code should be working. Please check

import pandas as pd
import streamlit as st
from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, DataReturnMode, ColumnsAutoSizeMode

if "selected_row" not in st.session_state:
    st.session_state.selected_row = '0'

data = {
    "calories": [420, 380, 390, 410, 420, 550, 600],
    "duration": [50, 40, 45, 50, 55, 60, 65],
    "random1": [5, 12, 1, 4, 5, 6, 7]
}

df = pd.DataFrame(data)

gb = GridOptionsBuilder.from_dataframe(df)
if "id_row" not in st.session_state:
    st.session_state["id_row"] = ''
    st.session_state.selected_row = '0'
else:
    st.session_state.selected_row = st.session_state["id_row"].get('selectedItems')[0]['_selectedRowNodeInfo'][
        'nodeRowIndex']

st.write(st.session_state.selected_row)

gb.configure_selection(selection_mode="single",
                       pre_selected_rows=[str(st.session_state.selected_row)])
gridOptions = gb.build()

data = AgGrid(df,
              gridOptions=gridOptions,
              enable_enterprise_modules=True,
              allow_unsafe_jscode=True,
              update_mode=GridUpdateMode.MODEL_CHANGED, key='id_row')

selected_rows = data["selected_rows"]
if len(selected_rows) != 0:
    st.write(selected_rows[0])
    # st.session_state.selected_row = selected_rows[0]['_selectedRowNodeInfo']['nodeRowIndex']

This question is solved by ferdy on Stack Overflow. Below is the answer. The trick is to use pre_selected_rows. @Manoharan_Thambi has also offered a solution with pre_selected_rows but unfortunately doesn’t work as when I switch from pages, the selection is not remained.

import pandas as pd
import streamlit as st
from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, DataReturnMode, ColumnsAutoSizeMode


if 'sid' not in st.session_state:
    st.session_state.sid = None


data = {
    "calories": [420, 380, 390],
    "duration": [50, 40, 45],
    "random1": [5, 12, 1],
    "random2": [230, 23, 1]
}

df = pd.DataFrame(data)

gb = GridOptionsBuilder.from_dataframe(df[["calories", "duration"]])

# Add pre_selected_rows param.
gb.configure_selection(selection_mode="single", use_checkbox=True,
                       pre_selected_rows=[st.session_state.sid])
gb.configure_side_bar()
gridOptions = gb.build()

# Add key.
data = AgGrid(df,
              gridOptions=gridOptions,
              enable_enterprise_modules=True,
              allow_unsafe_jscode=True,
              update_mode=GridUpdateMode.SELECTION_CHANGED,
              columns_auto_size_mode=ColumnsAutoSizeMode.FIT_CONTENTS,
              key='mykey')

selected_rows = data["selected_rows"]

# Save the row index of the selected row.
if len(selected_rows):
    ind = selected_rows[0]['_selectedRowNodeInfo']['nodeRowIndex']
    st.session_state.sid = ind

if len(selected_rows) != 0:
    selected_rows[0]

@subaruspirit

If you are moving to different page and still you want to preserve the selected row, you should place this code in all the pages, so that the selected rows stays in the session.

if “id_row” not in st.session_state:
st.session_state[“id_row”] = ‘’
st.session_state.selected_row = ‘0’
else:
st.session_state.selected_row = st.session_state[“id_row”].get(‘selectedItems’)[0][‘_selectedRowNodeInfo’][
‘nodeRowIndex’]

is this Solution working for streamlit version 1.25.0… as I was trying to implement the code you have provided I found that when i return back to the main page, the selected option is reset again instead of having the preselected check.

I’ve taken a look, the problem seems to be the pre_selected_rows from gb.configure_selection, no matter what number you put in (you can try to put a static number in rather than a session state value), it always selects the top row (when pre_selected_rows = [0]). I don’t think it has anything to do with streamlit, but more likely an issue from st_aggrid, I’ll see if I can report this as an issue.

1 Like

There has been a fix (but it’s not released yet I think), you can check the link here. But not sure when this fix will be pushed into a new release, I’m currently using the latest version of streamlit-aggrid (0.3.4.post3)

Thank you for your help!!! hopefully this fix works this time.