Switch tabs programitically?

Hello everyone, I have an app with multiple tabs. Based on a User clicking a button I would like to switch to another tab. I cant seem to get this to work, at all.

Even using the unsafe html code below dosent work:

                st.markdown(''' <a target="_self" href="#input">
                    <button>
                       Re enter Input
                    </button>
                </a>''', unsafe_allow_html=True)

Any Hints?

PS ALSO at any input/App reload the App always goes back to tab1, Is there any way to stop this behavior???

1 Like

Hey @Free-Radical,

Does the streamlit-folium component play into this? I noticed this is posted into the streamlit-folium section of the forum

oh no, sorry, wrong place. Re-editing.

Hi - Was this ever resolved? I could not find another thread.

I have the same use case - The user could always navigate to the tab themselves but finds it more intuitive to click on a button I have rendered.

Hi @Bahumat ,

is it possible to use the switch_page function and migrate the tab code to a multipage app?

Hello! Here is my workaround using select_slider:

tab = st.select_slider(
    "Step",
    options=["1", "2", "3"],
    key="tab",
    label_visibility="hidden",
)

if tab == "1":
    def set_tab():
        st.session_state["tab"] = "2"

    st.button("Next Step", type="primary", on_click=set_tab)

Hi everyone!

I also would like to have the option to switch tabs programmatically. Are there any news to this topic yet?

Here’s a simple demonstration:

import streamlit as st
from streamlit.components.v1 import html

a,b,c = st.tabs(["A","B", "C"])

a.title("A")
b.title("B")
c.title("C")

def switch(tab):
    return f"""
var tabGroup = window.parent.document.getElementsByClassName("stTabs")[0]
var tab = tabGroup.getElementsByTagName("button")
tab[{tab}].click()
"""
last_row = st.container()
if last_row.button("Switch to A"):
    html(f"<script>{switch(0)}</script>", height=0)
if last_row.button("Switch to B"):
    html(f"<script>{switch(1)}</script>", height=0)
if last_row.button("Switch to C"):
    html(f"<script>{switch(2)}</script>", height=0)

A small warning (that can easily be overcome):
When you add a script to the page, it will run immediately, but it will not run again on other page reruns unless it was first removed. So in this example, if you click the B button, then click the C tab, and go back to click to B button, it won’t switch back to the B tab on the second button click. This is because that script from the button click has been on the page the whole time. The second button click doesn’t change anything because the script was already there.

To make this a more robust solution, you could use st.empty and a time.sleep to clear out the script a second after it loads on the page, thereby ensuring every button click is actually “adding” a new script to the page which will immediately execute.

I’ve taken another stab at this.

Instead of doing it via the Python side, I add some Javascript that adds an event handler to the button, which then triggers a click event to the tab button. The advantage of this is that it all happens on the frontend.
It does require the labels of the buttons and the tab ‘buttons’ to be unique.

Hi Maarten,
Thanks for the demo , looks great. I have a question though how can we do the same without buttons. e.g. I need to perform certain operations first and then move to the next tab or some previous tab based on a logic. Can you please guide ?

Thanks

Amit