Update st.data_editor columns when Checkbox is used

Hi Everyone,

Just wondering if this is possible with st.data_editor table. I am trying to create an editable table which also contains a column with a checkbox that asks if you want concentration doubled. I’d like the table to automatically update with the doubled concentrations (in the concentration columns from the st.data_editor table) when the box is selected but I also want to allow users to change these values if something other than doubled concentrations are used.

Is this possible? I saw topics on session states and perhaps that’s the way to go but I wasn’t sure if there were other options.

Thanks!

Yes, it’s absolutely possible to create an editable table with st.data_editor in Streamlit where users can toggle a checkbox to automatically double the values in the concentration column. You can use st.session_state to manage state updates for when the checkbox is selected, and also allow users to override the doubled concentrations manually. Here’s how you can approach this:

import streamlit as st
import pandas as pd

# Sample data
data = {
    'Sample ID': ['A1', 'B1', 'C1'],
    'Concentration': [1.0, 2.5, 3.0],
    'Double Concentration': [False, False, False]  # Checkbox for doubling
}

# Create a DataFrame
df = pd.DataFrame(data)

# Initialize session state if not already done
if 'df' not in st.session_state:
    st.session_state.df = df

# Display the checkbox and table for editing
st.title('Editable Table with Concentration Control')

# Display the editable data editor
edited_df = st.data_editor(
    st.session_state.df,
    use_container_width=True
)

# Check if any of the checkboxes are selected
selected_checkboxes = edited_df['Double Concentration']
if selected_checkboxes.any():
    # Double the concentrations only if any checkbox is selected
    edited_df.loc[selected_checkboxes, 'Concentration'] *= 2
    # Uncheck all checkboxes after doubling
    edited_df['Double Concentration'] = False

# Rerun the script if data is edited
if not edited_df.equals(st.session_state.df):
    st.session_state.df = edited_df
    st.rerun()

For each row, you’ll have a checkbox button to double the concentration value. You’ll also be able to manually edit the concentration values.

Ah amazing! Thank you so much! :slight_smile:

Thanks again! One more question:
Is there a way in streamlit to allow the user to check the box, have the value double, and if they de-select the box, the value is returned to is normal/initial state?

In this example, we basically tell the value to deselect itself otherwise it keeps adding values. But allowing the user to see they have selected “double” already gives them more clarity versus selecting it twice by mistake. The user doesn’t need the ability to keep checking the box for multiple doubling but just once during a run.

Thanks!

Indeed, it is feasible to implement this behavior. I have revised the code to incorporate this logic. Upon selecting a checkbox, the concentration value is doubled. Conversely, upon deselecting a checkbox, the concentration value is halved.

import streamlit as st
import pandas as pd

# Sample data
data = {
    'Sample ID': ['A1', 'B1', 'C1'],
    'Concentration': [1.0, 2.5, 3.0],
    'Double Concentration': [False, False, False]  # Checkbox for doubling
}

# Create a DataFrame
df = pd.DataFrame(data)

# Initialize session state if not already done
if 'df' not in st.session_state:
    st.session_state.df = df

# Display the checkbox and table for editing
st.title('Editable Table with Concentration Control')

# Display the editable data editor
edited_df = st.data_editor(
    st.session_state.df,
    use_container_width=True
)

# Update the concentrations based on the checkbox
for index in range(len(edited_df)):
    # Double the concentrations if any new checkbox is selected
    if edited_df.loc[index, 'Double Concentration'] and not st.session_state.df.loc[index, 'Double Concentration']:
        edited_df.loc[index, 'Concentration'] *= 2

    # Half the concentrations if any new checkbox is deselected
    if not edited_df.loc[index, 'Double Concentration'] and st.session_state.df.loc[index, 'Double Concentration']:
        edited_df.loc[index, 'Concentration'] /= 2

# Rerun the script if data is edited
if not edited_df.equals(st.session_state.df):
    st.session_state.df = edited_df
    st.rerun()
1 Like

Perfect! Thank you!

1 Like