Multiselect based on user input

Hi team,
I am trying to get a multiselect option based on certain inputs from the user. The list which I need to display is not deterministic. I have pasted the sample codes here.

naming.py --------------------> sample code to get a non-deterministic list

def show_names(name):
	if name == "Roy":
		list1 = ['Riya','Ananya','Tanya','Sanya','Nikita']
	elif name == "Sen":
		list1 = ['Tarun','Arun','Bob','Karan','John']
	
	return list1

post1.py -----------------------> First trial code to achieve multiselect:

import streamlit as st
import SessionState
import naming as n

def inp_det(type):
    if type == 'source':
        st.write('Enter name (Roy/Sen)')
        name = st.text_input('Source name')
    elif type == 'destination':
        st.write('Enter name (Roy/Sen)')
        name = st.text_input('Destination name')
    return name
    
def main():
    state = SessionState.get(rerun = False, prepro_steps=0)
    name = inp_det('source')
    session_state = SessionState.get(name="", button_sent=False)
    button_sent = st.button("SUBMIT")
    if button_sent:
        session_state.button_sent = True
        if session_state.button_sent:
            listnames = n.show_names(name)
            selectednames=st.multiselect('Select your names',listnames)
            st.write(selectednames)

if __name__ == "__main__":
    main()

post2.py -----------------------> Second trial code to achieve multiselect:

import streamlit as st
import SessionState
import naming as n

def inp_det(type):
    if type == 'source':
        st.write('Enter name (Roy/Sen)')
        name = st.text_input('Source name')
    elif type == 'destination':
        st.write('Enter name (Roy/Sen)')
        name = st.text_input('Destination name')
    return name
    
def main():
    state = SessionState.get(rerun = False, prepro_steps=0)
    name = inp_det('source')
    session_state = SessionState.get(name="", button_sent=False)
    button_sent = st.button("SUBMIT")
    if button_sent:
        session_state.button_sent = True
        if session_state.button_sent:
            listnames = n.show_names(name)
            for ln in listnames:
                selectednames=st.checkbox(ln, value=False, key=None)
            st.write(selectednames)

if __name__ == "__main__":
    main()

The issue is in both the cases, the multiselect disappears as soon as I select one option. Is there any way for me to select multiple options after some input from user and capture those selected options?

Streamlit: version 0.62.1
Python: version 3.7.4
Browser (Google chrome): Version 83.0.4103.116

Hi @Ananya_Roy !

You were close :slight_smile: the thing is, when you press the Submit button, button_sent is set to True and you go inside the if button_sent code block, but any time you interact with the underlying multiselect, the script reruns and since you have not interacted with the button, button_sent variable goes back to None. As a result, you don’t go back inside the multiselect codeblock.

Since you store the info that you clicked the submit button in SessionState, you should use that info to force your code inside the if button_sent code block, something like if button_sent or if button_sent or session_state.button_sent :wink: (the solution is below but hopefully you’re able to correct your code yourself with that info !)

post1.py
import streamlit as st
import SessionState
import naming as n

def inp_det(type):
    if type == 'source':
        st.write('Enter name (Roy/Sen)')
        name = st.text_input('Source name')
    elif type == 'destination':
        st.write('Enter name (Roy/Sen)')
        name = st.text_input('Destination name')
    return name
    
def main():
    name = inp_det('source')
    session_state = SessionState.get(name="", button_sent=False)
    button_sent = st.button("SUBMIT")
    if button_sent or session_state.button_sent: # <-- first time is button interaction, next time use state to go to multiselect
        session_state.button_sent = True
        listnames = n.show_names(name)
        selectednames=st.multiselect('Select your names',listnames)
        st.write(selectednames)

if __name__ == "__main__":
    main()

Fanilo

2 Likes

Thank you so much! This works !

2 Likes

Hi @andfanilo, at this moment in streamlit version 0.79, i was trying to re-organize my code with this transitory pirce of “Hack”, but didn’t work as expected. Below there is a piece of my code i would like to use session_sate:

session_state = SessionState.get(checkboxed=False)
button_sent = st.button("Calcular o Índice de Capabilidade Cg")

    if button_sent or session_state.button_sent:

            session_state.button_sent = True

            p_toleranciamento = float(st.number_input("Porcentagem de Toleranciamento (P): "))

            t_tolerancia = float(st.number_input("TolerĂąncia (T): "))

            n_desvios_padroes = int(st.number_input("NÂș de Desvios PadrĂ”es (W): "))

after i run, returned the following error:

Hey @feliperoque, welcome to the community!

I think you need to initialize the button_sent attribute inside the SessionState.get part, like this session_state = SessionState.get(checkboxed=False, button_sent=False).

LMK if that works.

Happy Streamliting :balloon:
Fanilo

@andfanilo Worked as expected, thx so much for your efforts. BTW u know when this SessionState “Hack” will be released officialy? and for each button i created or will, i need to add a:

session_state = SessionState.get(checkboxed=False, button_sent=False)

?

An official version is currently being worked internally. I don’t have a time frame for its release but my guess would be soonish this year
 @abhi may have more info on this.

@feliperoque , @andfanilo : We are currently targeting official release by the end of Q2(with a disclaimer that we hopefully don’t run into any design issues). Thanks!

1 Like

Hello, Please do check out this is multi-select with text input