Passing an information from main window to sidebar

Summary

Hi, guys, I’m a new developer and I have to create a box in my sidebar that is filled when the user clicks on one of the cards that are on the main page, the idea is that this box in the sidebar looks like a shopping cart and that it goes from one page to another without changing

My code here:

# Import libraries
import streamlit as st
import pandas as pd


# Page setup
st.set_page_config(page_title="UN", page_icon="🌍", layout="wide")
st.title("Search for a resolution")

#imagem = "ufpe.jpg"
#st.sidebar.image(imagem, use_column_width=False, width=100)

# read file
df = pd.read_excel('metadados_rafael.xlsx')
df['date_p'] = pd.to_datetime(df['date_p']).dt.date

# Use a text_input to get the keywords to filter the dataframe
text_search = st.text_input("by title", value="")
text_search2 = st.text_input("by UN Document Symbol", value="")


# Filter the dataframe using masks
m1 = df["topic"].str.contains(text_search)
m2 = df["content"].str.contains(text_search)
df_search = df[m1 | m2]

# Filter the dataframe using masks
m3 = df["res_id2"].str.contains(text_search2)
m4 = df["res_id3"].str.contains(text_search2)
df_search2 = df[m3 | m4]

# Show the results, if you have a text_search
#if text_search:
#    st.write(df_search)
#elif text_search2:
#    st.write(df_search2)

# Another way to show the filtered results
# Show the cards
N_cards_per_row = 3

if text_search or text_search2:
    for n_row, row in df_search.reset_index().iterrows():
        i = n_row % N_cards_per_row
        if i == 0:
            st.write("---")
            cols = st.columns(N_cards_per_row, gap="large")
        
        # Criar o card clicável
        with cols[n_row % N_cards_per_row]:
            card_content = f"""
            <a href="#card_clicked_{n_row}" style="text-decoration: none; color: inherit;">
                <div style="border: 1px solid #ccc; padding: 10px; border-radius: 5px;">
                    <p style="margin: 0;">{row['location']} - {row['resn']} - {row['date_p']}</p>
                    <p style="margin: 0;"><strong>{row['topic']}</strong></p>
                    <p style="margin: 0;">{row['in_deg']}</p>
                </div>
            </a>
            """
            st.markdown(card_content, unsafe_allow_html=True)

        if f"card_clicked_{n_row}" in st.session_state:
            st.write(f"Você clicou no card {n_row}")
    
            # Defina as informações do card clicado no estado de sessão
            st.session_state.selected_card = {
                "location": row['location'],
                "date": row['date_p'],
                "topic": row['topic']
            }

# Sidebar with text area for resolution
resolution_area = st.sidebar.text_area('Resolution')

# Check if a card is selected
if hasattr(st.session_state, 'selected_card'):
    selected_card = st.session_state.selected_card
    resolution_text = f"Location: {selected_card['location']}\nDate: {selected_card['date']}\nTopic: {selected_card['topic']}"
    resolution_area = st.sidebar.text_area('Resolution', value=resolution_text)

Hi @arthurrslira

Yes you can certainly save and have information persist across app interactions (user clicking on the cards, which may typically trigger a page rerun) by using Session States.

Please see the Docs page for a detailed coverage:

For your use case, you can repurpose the code snippet (also see Add statefulness to apps - Streamlit Docs) for the following counter to keep track of which cards were clicked on:

import streamlit as st

st.title('Counter Example')
if 'count' not in st.session_state:
    st.session_state.count = 0

increment = st.button('Increment')
if increment:
    st.session_state.count += 1

st.write('Count = ', st.session_state.count)

Hope this helps!

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.