Changing color of a button text and changing a variable that controls the color

I want buttons to set a status variable, and the buttons to change color based on the current variable. I have it halfway working, however the user has to click twice. 1st click change status variable, 2nd click changes button text color.

I’ve tried a few tricks, like putting markdown at the top and bottom of the script. and changing the regular variable to a st.session_state variable.

import streamlit as st

# Define button styles
styles = {
    "None": {"color": "blue"},
    "Reviewed": {"color": "green"},
    "NotReviewed": {"color": "red"},
    "Error": {"color": "orange"},
}

if "status" not in st.session_state:
    st.session_state.status = "None"

#repeated at top:
button_style = styles.get(st.session_state.status, styles["None"])
st.markdown(f"""<style> div.stButton > button:first-child {{ color: {button_style['color']}; }} </style>""", unsafe_allow_html=True)

if st.session_state.status == "None" and st.button("Mark Reviewed"):
    st.session_state.status = "Reviewed"

elif st.session_state.status == "Reviewed" and st.button("Mark Not Reviewed", key="green-button"):
    st.session_state.status = "NotReviewed"

elif st.session_state.status == "NotReviewed" and st.button("Mark Reviewed", key="red-button"):
    st.session_state.status = "Reviewed"

#repeated at bottom:
button_style = styles.get(st.session_state.status, styles["None"])
st.markdown(f"""<style> div.stButton > button:first-child {{ color: {button_style['color']}; }} </style>""", unsafe_allow_html=True)

st.write(st.session_state.status)

If you add st.experimental_rerun() after each of your session_state.status changes, that should enable you to use a single click.

import streamlit as st

# Define button styles
styles = {
    "None": {"color": "blue"},
    "Reviewed": {"color": "green"},
    "NotReviewed": {"color": "red"},
    "Error": {"color": "orange"},
}

if "status" not in st.session_state:
    st.session_state.status = "None"

#repeated at top:
button_style = styles.get(st.session_state.status, styles["None"])
st.markdown(f"""<style> div.stButton > button:first-child {{ color: {button_style['color']}; }} </style>""", unsafe_allow_html=True)

if st.session_state.status == "None" and st.button("Mark Reviewed"):
    st.session_state.status = "Reviewed"
    st.experimental_rerun()

elif st.session_state.status == "Reviewed" and st.button("Mark Not Reviewed", key="green-button"):
    st.session_state.status = "NotReviewed"
    st.experimental_rerun()

elif st.session_state.status == "NotReviewed" and st.button("Mark Reviewed", key="red-button"):
    st.session_state.status = "Reviewed"
    st.experimental_rerun()

#repeated at bottom:
button_style = styles.get(st.session_state.status, styles["None"])
st.markdown(f"""<style> div.stButton > button:first-child {{ color: {button_style['color']}; }} </style>""", unsafe_allow_html=True)

st.write(st.session_state.status)
1 Like