Checkbox bug where on_change work for last element

Summary

Not really a streamlit problem, I think it’s just a python problem since I’m new. When I check the checkbox, I want the “checked” value to become True and if I uncheck it, it becomes False. However, when I run my code, when I check a checkbox, the checkbox of the last element of my list checks/unchecks too and only that last element’s value changes. I don’t know where my problem lies. Here’s the code:

Steps to reproduce

Code snippet:

import streamlit as st

st.write("# Practice Test Maker!")

if 'question' not in st.session_state:
    st.session_state.question = []

if 'answer' not in st.session_state:
    st.session_state.answer = []

textbox_question = st.text_input("Write a question: ")

textbox_answer = st.text_input("Write the answer of your question: ")

def add_question():
    st.session_state.question.append({"text" : textbox_question, "checked" : False})

def add_answer():
    st.session_state.answer.append(textbox_answer)

def add_on_click():
    add_question()
    add_answer()

def clear_all():
    st.session_state.question = []
    st.session_state.answer = []

enter_button = st.button("Add", on_click = add_on_click)

for i, question in enumerate(st.session_state.question):
    def update_question():
        st.session_state.question[i]['checked'] = not st.session_state.question[i]['checked']
    st.checkbox(question['text'], value = question['checked'], on_change = update_question, key = i)

def remove_question():
    for question in st.session_state.question:
        if question['checked'] == True:
            index = st.session_state.question.index(question)
            st.session_state.question.remove(question)
            del st.session_state.answer[index]
            

remove_button = st.button("Remove", on_click = remove_question)

clear_button = st.button("Clear", on_click = clear_all)

st.write(st.session_state.question)
st.write(st.session_state.answer)

If applicable, please provide the steps we should take to reproduce the error or specified behavior.

Expected behavior:

Explain what you expect to happen when you run the code above.

Actual behavior:

I expect that when I check the checkbox, the st.session_state.question[‘checked’] changes the boolean value to the element corresponding to the checkbox and not the last one of the element. Probably the important parts of the code that have problem are:

if 'question' not in st.session_state:
    st.session_state.question = []

def add_question():
    st.session_state.question.append({"text" : textbox_question, "checked" : False})

for i, question in enumerate(st.session_state.question):
    def update_question():
        st.session_state.question[i]['checked'] = not st.session_state.question[i]['checked']
    st.checkbox(question['text'], value = question['checked'], on_change = update_question, key = i)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.