I want to open this post as I can't find anything on the official documentation from streamlit or any resources that mentioned how to do this. After some trial and error I have figured out a way, and will post the answer below. This is a function that in R shiny is called dynamic UI, here's the question.
How to generate dynamic input widgets depending on the value from a different input widget? For example see below picture, the numbers of text_input
called Product Code i
depends on the value from the number_input
called Number of Products
. So if there are x number of products, there will be x number of text_input
generated dynamically. Moreover, the value inside the generated text_input
can be extracted as well.
Here is one way to do this.
First, use list comprehension to store keys (variables to use to extract values from text_input later) and values (text_input).
Next, use key and value to set the attribute in a class.
The value from text_input labelled as product2 can be extracted using the attribute within the class using p.product2
for example.
import streamlit as st
number_of_products = st.sidebar.number_input(label="Number of Products",
min_value=0, max_value=20, value=1)
class Products:
pass
p = Products()
keys = [str("product"+str(x+1)) for x in range(number_of_products)]
values = [st.sidebar.text_input(label=f"Product Code {x+1}", value=0) for x in range(number_of_products)]
for key, value in zip(keys, values):
setattr(p, key, value)
# each key's value is stored in the class as an attribute
st.write(p.product2)
Using dictionary and exec command can also dynamically declare variables, but when the value inside the text_input is not a number, it will generate an error.