I think you can try doing something like this, take comma separated values of options and then feed its split to options.
import streamlit as st
inputs = st.text_input("Give csv of inputs")
st.selectbox("Select Dynamic", options=[opt.strip() for opt in inputs.split()])
If you want to take the values one by one it will be a little more complex as it will require you to hold the state. This snippet should do the job.
import streamlit as st
from state import provide_state
@provide_state
def main(state):
state.inputs = state.inputs or set()
input_string = st.text_input("Give inputs")
state.inputs.add(input_string)
st.selectbox("Select Dynamic", options=list(state.inputs))
main()
First, thank you so much for your effort. What you have suggested is exactly what I have been using. However, I was looking to do the same thing but in only one box, instead of two.
Most probably, Streamlit does no provide something similar, though I was hopping in any existing hack .
Staying in the realm of native Streamlit solutions, @ash2shukla’s solution is the closest you’ll get , maybe you can hide the text_input in the sidebar or an expander to make it more “configuration box”, and the selectbox in the main container.
As stated by @andfanilo, the only way to achieve what you want is to build your own streamlit component.
You cannot merge a text input and a selectbox natively, but you can at least put them in the same row.
I’ve taken @ash2shukla’s code sample, and modified it accordingly.
I’ve also changed it to automatically select the last input in the selectbox:
import streamlit as st
from state import provide_state
@provide_state
def main(state):
state.inputs = state.inputs or set()
c1, c2 = st.beta_columns([2, 1])
input_string = c1.text_input("Input")
state.inputs.add(input_string)
# Get the last index of state.inputs if it's not empty
last_index = len(state.inputs) - 1 if state.inputs else None
# Automatically select the last input with last_index
c2.selectbox("Input presets", options=list(state.inputs), index=last_index)
if __name__ == "__main__":
main()
Hello,
here is an alternative way to do it. If you are looking for a way to dynamically add/remove text fields
Demo:
Code:
def main():
# add the key choices_len to the session_state
if not "choices_len" in st.session_state:
st.session_state["choices_len"] = 0
# c_up contains the form
# c_down contains the add and remove buttons
c_up = st.container()
c_down = st.container()
with c_up:
with st.form("myForm"):
c1 = st.container() # c1 contains choices
c2 = st.container() # c2 contains submit button
with c2:
st.form_submit_button("submit")
with c_down:
col_l, _, col_r = st.columns((4,15,4))
with col_l:
if st.button("Add Choise"):
st.session_state["choices_len"] += 1
with col_r:
if st.button("remove Choise") and st.session_state["choices_len"] > 1:
st.session_state["choices_len"] -= 1
st.session_state.pop(f'{st.session_state["choices_len"]}')
for x in range(st.session_state["choices_len"]): # create many choices
with c1:
st.text_input("text", key=f"{x}")
# reads values from the session_state using the key.
# also doesn't return an option if the value is empty
st.selectbox("myOptions", options=[
st.session_state[f"{x}"]\
for x in range(st.session_state["choices_len"])\
if not st.session_state[f"{x}"] == ''])