Prevent rerun when editing 'data editor' cells without 'form'

Hey everyone,

in my application I’m using streamlit ‘data editor’. It is used to display and edit data. In the first column I’ve inserted a ‘checkbox column’, that I use in combination with ‘session state’ to achieve single row selection.

Each selection of a checkbox needs a rerun of the script in order to apply the changes in the checkbox column (remove old selection, insert new selection). The problem I have is that if the user edits data somewhere within the data editor, a rerun is triggered and the top of the data editor is shown after the rerun. That is not very convenient if it’s necessary to edit many cells that are not at the top of the data editor.

Is there a way to trigger a rerun after a click on the checkbox column, but at the same time, dont’t trigger a rerun when editing data?

I’m aware of streamlit ‘form’, but using a form wouldn’t trigger a rerun (I suppose) when clicking a checkbox.

I’m using

  • Streamlit 1.30.0
  • Python 3.9.17

Thank you!

2 Likes

Could you post a minimal reproducible code?

same issue here!

This is an example code with functionality extracted of my actual code:

import pandas as pd
import streamlit as st
from streamlit import session_state as ss

if 'to_insert' not in ss:
    ss.to_insert = {}

if 'key' not in ss:
    ss.key = 0

def get_df():
   data_dict = {'col1': [], 'col2': []}
   for i in range (0, 50):
       data_dict['col1'].append(i)
       data_dict['col2'].append(i+1)
   df = pd.DataFrame(data_dict)
   return df

def callback_fct(*args):
    key = ''.join(args)

    edited_rows = ss[key]['edited_rows']

    for row in ss.to_insert:
        for col in ss.to_insert[row]:
            if col == 'Select':
                del ss.to_insert[row]['Select']
                break
    ss.to_insert.update(edited_rows)

def dataframe_with_selections():

    if 'inserted_df' not in ss:
        inserted_df = get_df()
        inserted_df.insert(0, "Select", False)
    else:
        inserted_df = ss.inserted_df
        inserted_df['Select'] = False

    for row in ss.to_insert:
        for column in ss.to_insert[row]:
            inserted_df.loc[inserted_df.index[row], column] = ss.to_insert[row][column]

    ss.inserted_df = inserted_df

    df_ed=st.data_editor(inserted_df, hide_index=True,use_container_width=True
                        ,column_order=('Select', 'col1','col2')
                        ,column_config={"Select": st.column_config.CheckboxColumn("Show details", required=True)}
                        ,key=f'editor_{ss.key}',
                        on_change=callback_fct, args = (f'editor_{ss.key}'))
    
    ss.inserted_df = inserted_df

dataframe_with_selections()

Sorry but I don’t understand the above.

I tried your code and got this. Editing some values in col1 and col2.

image

What exactly is “the top of the data editor”?

If you scroll down e.g. to the bottom of the data editor and edit a cell there, the editor jumps back to the beginning (due to the rerun). If you want to edit let’s say five cells, you have to scroll down every single time, that is what I want to prevent.

Got it.