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.

Running into a similar issue. @rsx , were you able to find a solution? Thanks!

Unfortunately not. I don’t know if in the meantime a new Streamlit version introduced any functionality that would help with that issue.

My workaround was kind of an edit mode: I added a button to “enter edit mode”, that button caused a rearrangement of the editor within a Streamlit form. I used the submit button as a “leave edit mode” button, that caused a rearrangement back to the original arrangement without the form. That solution is of course not ideal but was acceptable for my application.

1 Like

Thanks for the reply. No luck with the latest Streamlit version unfortunately, still seeing the same behavior. I’ll likely go down the same route of adding an “edit option”. Hopefully this gets addressed in a future version.