Remove buttons when clicked on

Hello everyone,

Python : 3.11.9
Streamlit : 1.37.1

I have a local streamlit app, which is a chat interface. I have button for placeholder messages, user can click on one of them and the appropriate message will be sent automatically.

1- User can click on : Click here to display placeholder messages

2- Then placeholder messages are being displayed.

3- The message has been sent and is being processed.

I would like to fix an UI issue, once user has clicked on a message, I want all placeholders messages and the call to action button “Click here” to disappear.
What would be the best “streamlit” way to do so ?

Thank you,

You can use the function ‘on_click’ combine with session_state.

        # Initialize session state for controlling the visibility
        if 'clicked' not in st.session_state:
            st.session_state.clicked = False

        # Function to handle placeholder message click
        def handle_placeholder_click(message=None):
            # Set the session state to True so that placeholders and button are hidden
            st.session_state.clicked = ~st.session_state.clicked
            # Simulate sending the message and display it
            st.write(f"Message sent: {message}")

        # If no message has been clicked, show the "Click here" button and placeholders
        if not st.session_state.clicked:
            # Button to display the placeholders
            if st.button("Click here to display placeholder messages"):
                # Display the placeholder messages (as buttons)
                st.button("Placeholder 1", on_click=handle_placeholder_click, args=("Placeholder 1",))
                st.button("Placeholder 2", on_click=handle_placeholder_click, args=("Placeholder 2",))
                st.button("Placeholder 3", on_click=handle_placeholder_click, args=("Placeholder 3",))
        else:
            # If a message has been sent, display a message saying it is being processed
            st.write("The message has been sent and is being processed.")

            st.button('RESET',on_click=handle_placeholder_click, args=("RESET BUTTON",))

I prefer to manage sequences with Enum, makes it easier to read. I modified Faltawer’s code (demo):

2024-10-22 7.56.37 p.m.

from enum import Enum
import streamlit as st

class Step(Enum):
    INITIAL = 1
    PLACEHOLDER_SELECTION = 2
    PROCESSING = 3

    @classmethod
    def next_value(cls, current_value):
        next_value = (current_value.value % len(cls)) + 1
        return Step(next_value)


if "step" not in st.session_state:
    st.session_state.step = Step.INITIAL

cols = st.columns([1, 1, 1, 1, 1])

def handle_placeholder_click(message=None):
    if st.session_state.step == Step.PROCESSING:
        st.session_state.step = Step.INITIAL
    else:
        st.session_state.step = Step.next_value(st.session_state.step)

    st.write(f"Message: {message}")


if st.session_state.step.value == Step.INITIAL.value:
    st.button(
        "Click here to display placeholder messages",
        on_click=handle_placeholder_click,
        args=("Display placeholders",),
    )
elif st.session_state.step.value == Step.PLACEHOLDER_SELECTION.value:
    with cols[1]:
        st.button(
            "Placeholder 1", on_click=handle_placeholder_click, args=("Placeholder 1",)
        )
    with cols[2]:
        st.button(
            "Placeholder 2", on_click=handle_placeholder_click, args=("Placeholder 2",)
        )
    with cols[3]:
        st.button(
            "Placeholder 3", on_click=handle_placeholder_click, args=("Placeholder 3",)
        )
else:
    st.write("The message has been sent and is being processed.")
    st.button("RESET", on_click=handle_placeholder_click, args=("RESET BUTTON",))

It’s very nice, thank you ! I was looking for something like for a personnal project :smiley:

1 Like

I’ll give it a try thank you, what will be your take to hide all buttons easily ?