Two button disabling and enabling each other

Hello everyone!

I am trying to make two buttons to enable and disable each other. So let’s say we have Button A and button B consecutively. using a boolean flag the initial state of the button are set in such way that one is enabled and the other is disabled. when this flag is changed, the buttons don’t automatically update and require an additional click to update the state. Is it possible to make the buttons update automatically?

let say the flag == False

then button A is enabled and B is disabled.

When user clicks on A, B is enabled and A is disabled automatically and when B is clicked A is enabled while B is disabled.

Hi @Artemis, are you looking for something like this?

import streamlit as st

if "btnval" not in st.session_state: st.session_state.btnval = False
def toggle_btns(): st.session_state.btnval = not st.session_state.btnval

cols = st.columns((2,2,10))
cols[0].button("Button A", on_click=toggle_btns, disabled=st.session_state.btnval)
cols[1].button("Button B", on_click=toggle_btns, disabled=not st.session_state.btnval)

You can further add the key parameter of the button if you wish, depending on what you want your code to do.

Cheers

Hello Shawn,

Thank you for your help.

Yes I’m looking for something similar. The only difference is that when buttons are initially created, their disabled attr is based on a flag value that is stated by checking something in the background and it can change later on.

let’s say I want to add something to a list. when user enters element for example in a text box. we first check if that element exist in the list. if it does then add button is enabled and delete button disabled and vice versa if the element does not exists. When user clicks on add button, the element is added to the list, the add button is disabled and delete button is enabled. and when user clicks on the delete button, it removes the element, disables the delete button and enables the add button.

The way I’m doing is using flag and not flag for the disabled attr of the buttons but flag is not updated right away. the first click on add or delete updates the list and it requires a second click to update the state of the buttons…

Hi @Artemis,

Well, you can do something like this:

import streamlit as st

if "btnval" not in st.session_state: st.session_state.btnval = None
if "mylist" not in st.session_state: st.session_state.mylist = ["a", "b", "c"]
def toggle_btns(vip): 
  if vip in st.session_state.mylist and st.session_state.btnval == True: st.session_state.mylist.remove(vip)
  if vip not in st.session_state.mylist and st.session_state.btnval == False: st.session_state.mylist.append(vip)
  st.session_state.txtel = ""

def Callback(): st.session_state.btnval = not st.session_state.btnval

txtip = st.text_input("Element for list", value="", key="txtel", on_change=Callback)
if txtip != "":
  st.session_state.btnval = True if txtip in st.session_state.mylist else False

  cols = st.columns((2,2,10))
  cols[0].button("Add", on_click=toggle_btns, args=(txtip,), disabled=st.session_state.btnval)
  cols[1].button("Del", on_click=toggle_btns, args=(txtip,), disabled=not st.session_state.btnval)

st.info(f"Currently mylist contains: {st.session_state.mylist}")

Explanation:

  1. The list initializes with 3 elements: a, b, c. This can be seen in the blue band at the bottom.
  2. If you enter any element on the list, you get an option to delete that element
  3. If you enter any element that is not on the list, you get an option to add that element

You can modify the code to change the logic as you wish.

Cheers

Thank you very much Shawn!!

Your suggestion worked perfectly for my project.

Cheers,

1 Like

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