Dynamic creation of streamlit objects

I ran into an interesting issue this evening, I figured I would share on here in case anyone else observes the same behavior and is looking for a solution.

I had a case where I was iterating through a list and creating a checkbox for each item in the list. Initially, I was observing that clicking any checkbox had the effect of clicking every checkbox.

import streamlit as st

to_be_deleted = set()

for i in range(10):
    delete = st.checkbox(f'delete?', False)
    if delete:
        to_be_deleted.add(i)

st.write(f'to be deleted: {to_be_deleted}')

However, if you change the string in the checkbox to be unique, the observed behavior is as expected.

import streamlit as st

to_be_deleted = set()

for i in range(10):
    delete = st.checkbox(f'delete {i}?', False)
    if delete:
        to_be_deleted.add(i)

st.write(f'to be deleted: {to_be_deleted}')

Lesson learned? Donโ€™t use multiple checkboxes with the same name!

1 Like

Hi jeremyjordan,

This is a good catch :slightly_smiling_face:, this happens because Streamlit uses all characters in the line to generate each widget ID. If there are no character changes, there would be several widgets with the same ID.

With our most recent version, we now raise an error when we detect multiple widgets with the same exact structure. All thatโ€™s needed is to pass a unique key argument to each of the widgets.

For example:
delete = st.checkbox(fโ€™delete?โ€™, False, key=โ€˜delete_%sโ€™ % i)

We just released 0.49.0 version.
You can upgrade with $ pip install --upgrade streamlit

Cheers.
Dani.

1 Like

Your post saved me alot of time, Thanks.

1 Like

I was trying something similar but with text boxes. I havenโ€™t been able to find any documents on accessing the values of the widget by the key value.

1 Like