After trying out Streamlit, I truly appreciate how Panel makes session state management simple! There’s no need to manually keep track of your widgets in Panel!
Streamlit:
import random
from uuid import uuid4
import streamlit as st
def create_row(hex_id=None):
"""
Dynamically add a new row to the app.
"""
value = random.randint(0, 100)
if hex_id is None:
hex_id = uuid4().hex
st.session_state.rows[hex_id] = value
else:
value = st.session_state.rows[hex_id]
st.number_input("Enter a number", value=value, key=f"num_{hex_id}")
# Initialize rows if it doesn't exist in session_state
st.session_state.setdefault("rows", {})
main = st.columns(1)
with main[0]:
# Layout objects
st.title("Dynamically add new rows")
button_cols = st.columns(2)
with button_cols[0]:
add_row = st.button("Add new row", use_container_width=True)
with button_cols[1]:
clear_rows = st.button("Clear all rows", use_container_width=True)
# Add interactivity
if clear_rows:
st.session_state.rows = {}
for hex_id in st.session_state.rows.keys():
create_row(hex_id=hex_id)
if add_row:
create_row()
Panel:
import random
import panel as pn
pn.extension(sizing_mode="stretch_width")
def create_row(hex_id=None):
"""
Dynamically add a new row to the app.
"""
value = random.randint(0, 100)
row = pn.widgets.TextInput(name="Enter a number", value=str(value))
rows.append(row)
# Layout objects
rows = pn.Column()
add_row = pn.widgets.Button(name="Add new row")
clear_rows = pn.widgets.Button(name="Clear all rows")
button_cols = pn.Row(add_row, clear_rows)
main = pn.Column("# Dynamically add new rows", button_cols, rows)
# Add interactivity
clear_rows.on_click(lambda _: rows.clear())
add_row.on_click(lambda _: create_row())
pn.template.BootstrapTemplate(main=[main], main_max_width="max(50%, 600px)").servable()