4

I am facing an issue that when I select any items from the st.multiselect, the page is reloaded, and the selected item is also reset.

I tried to add st.session_state, but it did not help much. Can anyone have experience in this case? or any comment would be highly appreciated.

Below is my code

def load_data(self, db_result):
    # Load full dataset of RecordSet
    df_record_set, count_record_set = self.load_record_set_data(record_set_col)
    st.write('### Full RecordSet', df_record_set)
    st.info('Total items: ' + str(count_record_set))
    
    record_set_selected_indices = st.selectbox('Select rows:', df_record_set.index)
    record_set_selected_rows = df_record_set.loc[record_set_selected_indices]
    st.write('### Selected Rows', record_set_selected_rows)
        
    # Load full dataset of Exporting Template
    df_exp_tem, count_exp_tem = self.load_exp_tem_data(exp_tem_col)
    st.write('### Full Exporting Template', df_exp_tem)
    st.info('Total items: ' + str(count_exp_tem))
    
    exp_tem_selected_indices = st.selectbox('Select rows:', df_exp_tem.index)
    exp_tem_selected_rows = df_exp_tem.loc[exp_tem_selected_indices]
    st.write('### Selected Rows', exp_tem_selected_rows)
    
    # Add a 'Generate channel' button
    generate_clicked = st.button('Generate channel')

    if generate_clicked or st.session_state.generate_channel:
        st.session_state.generate_channel = True
        
        # Get RecordSet Id to find related ECG with channels
        record_set_id=ObjectId(record_set_selected_rows[cons.HEADER_ID])
        
        # Query to get list of ECG channels based on RecordSet Id
        result = self.load_channel_list_from_record_set(ecg_col, record_set_col, record_set_id)
        
        # Nested For Loop
        ecg_data = [
            ECG(id=y[cons.ECG_ID_SHORT],
                file_name=y[cons.ECG_FILE_NAME],
                channel=y[cons.ECG_CHANNEL])
            for x in result for y in x[ecg_col.name]
        ]

        # Get text of channels based on selected exporting template
        list_channels_str = 'Channel ' + exp_tem_selected_rows[cons.HEADER_CHANNEL]
        
        # Widgets will be genrated by the number of ECG records
        # This is used for mapping channel between ECG record and Exporting template
        for x in ecg_data:
            st.write(list_channels_str + ' from selected exporting template')
            st.multiselect('Record: ' + x.file_name, x.channel, key=str(x))
                    
        st.success('Clicked!')
        map_clicked = st.button('Extract data')

        if map_clicked:
            st.write('test - ''Extract data'' button is clicked')

Screenshot: image

  • Current: When 'V5' is selected, the page is reloaded and no item is selected.
  • Expectation: When 'V5' is selected, the page remains stable (no reload), and the item is added to the multiselect widget. Then, other items are also can be added.

Open question: Is that possible to have 2 different st.session_state to handle 2 different business processes in a function? If not, which is the best practice?

Thanks for your reading.

Huy DQ
  • 121
  • 1
  • 11
  • 2
    You can use [form](https://docs.streamlit.io/library/api-reference/control-flow/st.form) to gather all the input from the user. You can use more than 1 different session_state. – ferdy Apr 24 '22 at 23:16
  • Hi @ferdy, the form works very well. Can you give an example of a combination of different `session_state`s? – Huy DQ Apr 27 '22 at 03:34
  • I don't understand by "combination of different session_state". If you have a variable you can assign a session_state for that variable. – ferdy Apr 27 '22 at 06:24

0 Answers0