Navigation panel - can we have a button on the right hand side like 'Next' which automatically moves to the next 'page' in the navigation panel

Hi. I have been handed over an MultiApp which is used to collect information about products, i.e. it is a questionnaire with a few categories. Within each category there is a set of questions. Each category is created a separate app on the left hand side. Is there a way to have a โ€˜Nextโ€™ button on the right hand side which will direct the user to the next category/page from the right hand side.

it would mean moving from Home to Resources by clicking a button on the right hand side.

Thanks in advance,

1 Like

Hey @vbard,

Sorry for the slow reply, but I have been working on a possible solution to this using just the standard Streamlit functions.

Essentially, this requires knowledge of using session state, that is to get the state of the app at a certain point and be able to increment or change this based on a click that the user does. This is currently not supported in Streamlit but there have been other posts that have created work arounds, and it is something that our team is working on implementing, hopefully in the near future. Here is a link to using session state workarounds: Multi-page app with session state

That being said, if your newer to using python (like myself) and session state seems a bit daunting I have made a bit of a hack that does seem to work.

import streamlit as st
import pickle as pkle
import os.path

# create a button in the side bar that will move to the next page/radio button choice
next = st.sidebar.button('Next on list')

# will use this list and next button to increment page, MUST BE in the SAME order
# as the list passed to the radio button
new_choice = ['Home','Resources','Gallery','Vision','About']

# This is what makes this work, check directory for a pickled file that contains
# the index of the page you want displayed, if it exists, then you pick up where the
#previous run through of your Streamlit Script left off,
# if it's the first go it's just set to 0
if os.path.isfile('next.p'):
    next_clicked = pkle.load(open('next.p', 'rb'))
    # check if you are at the end of the list of pages
    if next_clicked == len(new_choice):
        next_clicked = 0 # go back to the beginning i.e. homepage
else:
    next_clicked = 0 #the start

# this is the second tricky bit, check to see if the person has clicked the
# next button and increment our index tracker (next_clicked)
if next:
    #increment value to get to the next page
    next_clicked = next_clicked +1

    # check if you are at the end of the list of pages again
    if next_clicked == len(new_choice):
        next_clicked = 0 # go back to the beginning i.e. homepage

# create your radio button with the index that we loaded
choice = st.sidebar.radio("go to",('Home','Resources', 'Gallery', 'Vision', 'About'), index=next_clicked)

# pickle the index associated with the value, to keep track if the radio button has been used
pkle.dump(new_choice.index(choice), open('next.p', 'wb'))

# finally get to whats on each page
if choice == 'Home':
    st.write('this is home')
elif choice == 'Resources':
    st.write('here is a resources page')
elif choice == 'Gallery':
    st.write('A Gallery of some sort')
elif choice == 'Vision':
    st.write('The Vision')
elif choice == 'About':
    st.write('About page')

I was able to get this to work on my own computer running locally. This workaround should allow you to click the next button to move down your pages OR click on one of the radio button options to display that page.

HOWEVER CAVEAT CAVEAT CAVEAT:
I have found that occasionally you have to click a radio button 2 times to get it to actually display the page. As I said this is a bit of a hack because itโ€™s kinda cheating how Streamlit reruns your script from top to bottom every time the user presses a button.

Happy Streamlit-ing!
Marisa

2 Likes

1 Like

In above example have added work around for navigation and to โ€œfix click a radio button 2 timesโ€ issue.

Hey @ritesh.sharma29 (and FYI @vbard)

With the release of session state, this can be solved with an even simpler set of code, specific to the streamlit package! :tada:

You can store the values of all of your widgets in the state object and then use them on reruns of your app to dynamically change the output, including adding a โ€œnextโ€ button to a set or radio options :partying_face:

In fact, I have already answered pretty much exactly this question (just recently) using the new session state feature. Check out that post here: How to create recurring forms with unique keys? - #6 by Marisa_Smith

option_names = ["a", "b", "c"]

output_container = st.empty()

next = st.button("Next/save")

if next:
    if st.session_state["radio_option"] == 'a':
        st.session_state.radio_option = 'b'
    elif st.session_state["radio_option"] == 'b':
        st.session_state.radio_option = 'c'
    else:
        st.session_state.radio_option = 'a'

option = st.sidebar.radio("Pick an option", option_names , key="radio_option")
st.session_state

if option == 'a':
    output_container.write("You picked 'a' :smile:")
elif option == 'b':
    output_container.write("You picked 'b' :heart:")
else:
    output_container.write("You picked 'c' :rocket:")

Check out the blog post here: Store Information Across App Interactions | Session State

State API here: Session State API โ€” Streamlit 0.86.0 documentation

Upgrade Streamlit to 0.84 or above to be able to use this new feature!

Happy Streamlit-ing!
Marisa

Thank you @Marisa_Smith for this awesome information ! Will explore out more.

1 Like