How to reset st.pills after selection is done?

Hello,

I would like to know if there’s a way to reset the options of st.pills after an option has been selected ?

  1. At the beginning, all options are possible:

  1. then I select the first one:

However ‘North’ remains selected on the UI.
Is there a way to clear the red lining, red text just after selection ?

thanks in advance,
Jonathan

To provide more information, in a chatbot, I would like to give the option to either get the input from the chat window, or from the st.pill value.

  1. When I select first the chat window, after the bot answers, I still have the choice of the chat window or the st.pill mode.
  2. But once I select the st.pill mode, it renders the chat window unclickable if now the user wants to write a query.

I have developed a solution by utilizing custom CSS to eliminate the select highlight on pill buttons. While this may not be the optimal solution, it does function effectively. Additionally, this solution has the limitation of preventing users from selecting the same prompt suggestion twice consecutively. Apart from prompt suggestions, users are also able to manually input prompts.

import streamlit as st

# Initialize session state for chat messages
if 'chat_messages' not in st.session_state:
    st.session_state.chat_messages = []

# Initialize session state for prompt selection
if 'prompt_selection' not in st.session_state:
    st.session_state.prompt_selection = ""

# Render the chat messages
for message in st.session_state.chat_messages:
    with st.chat_message(message['role']):
        st.markdown(message['content'])

options = ["What is the weather today?", "What is the time now?", "How are you doing?"]

prompt_selection = st.pills("Prompt suggestions", options, selection_mode="single", label_visibility='hidden')
input_prompt = st.chat_input("Type your message here...")

# Get the selected prompt only if it has changed
def get_prompt_selection():
    global prompt_selection

    if prompt_selection == None:
        return None
    elif prompt_selection == st.session_state.prompt_selection:
        return None
    else:
        st.session_state.prompt_selection = prompt_selection

    return prompt_selection

if prompt_selection := get_prompt_selection():
    st.session_state.chat_messages.append({"role": "user", "content": str(prompt_selection)})

    # Trigger a rerun to update the chat messages
    st.rerun()

if input_prompt:
    st.session_state.chat_messages.append({"role": "user", "content": input_prompt})

    # Trigger a rerun to update the chat messages
    st.rerun()

# Add custom CSS to remove the select highlight from pill buttons
st.markdown(
    """
    <style>
    [kind="pillsActive"][data-testid="stBaseButton-pillsActive"] {
        background: rgb(255, 255, 255);
        border: 1px solid rgba(49, 51, 63, 0.2);
        color: rgb(49, 51, 63);
    }
    </style>
    """,
    unsafe_allow_html=True,
)

1 Like

This is an answer to the question in the tittle. You can reset the widget in the on_change event handler. Before that, you need to store the value somewhere else, so that you can use it after the reset.

import streamlit as st


def on_drection_change():
    st.session_state.direction = st.session_state.direction_pill
    st.session_state.direction_pill = None


st.session_state.setdefault("direction", None)
directions = ["North", "East", "South", "West"]
st.pills("Direction", options=directions, on_change=on_drection_change, key="direction_pill")
st.write(f"You selected **{st.session_state.direction}**")
2 Likes

thanks @Goyo and @Encrypt .
I have implemented a version that uses both of your suggestions and it solves my issues.
I appreciate the help.

import streamlit as st
st.set_page_config(layout="wide")
st.title("Ask Me Anything")

# Initialize session state for chat messages
if 'chat_messages' not in st.session_state:
    st.session_state.chat_messages = []
    st.session_state.chat_messages = [{"role":"system","content":"you are a helpful assistant"}]

# Initialize session state for prompt selection
if 'prompt_selection' not in st.session_state:
    st.session_state.prompt_selection = None

if 'direction' not in st.session_state:
    st.session_state.direction = None

def on_direction_change():
    st.session_state.direction = st.session_state.direction_pill
    st.session_state.direction_pill = None

if st.sidebar.button(label="clear chat", 
                       help="clicking this button will clear the whole history",
                       icon="🗑️"):
        st.session_state.prompt_selection = None
        st.session_state["chat_messages"] = [{"role":"system","content":"you are a helpful assistant"}]

col1, col2 = st.columns([.6,.4])

with col1:
     options = ["What is the weather today?", "What is the time now?", 
                "How are you doing?", "what is 1+1 equal to ?", "summarize quantum physics in 50 words max"]
     
     st.session_state.setdefault("direction", None)
     prompt_selection = st.pills("Prompt suggestions", options, selection_mode="single", 
                                 label_visibility='hidden',on_change=on_direction_change, key="direction_pill")
     input_prompt = st.chat_input("Type your message here...")
     st.session_state.prompt_selection = input_prompt
 
     if st.session_state.direction is not None:
          with st.chat_message("user"):
                    st.write(st.session_state.direction)
          with st.spinner("searching ..."):  
               with st.chat_message("assistant"):
                    r = f"you wrote `{st.session_state.direction}`"
                    st.write(r)
          st.session_state.direction = None

     elif st.session_state.prompt_selection is not None:
          st.session_state.chat_messages.append({"role": "user", "content": st.session_state.prompt_selection})
          with st.chat_message("user"):
                    st.write(str(st.session_state.prompt_selection))
          with st.spinner("searching ..."):  
               with st.chat_message("assistant"):
                    r = f"you wrote `{st.session_state.prompt_selection}`"
                    st.write(r)
          st.session_state.prompt_selection = None

with col2:
      st.json(st.session_state)
1 Like

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