How do I enable/disable a widget based on a toggle click using session state?

I have a function that renders my filters. The goal is that when a user clicks the filter by date range toggle button, the two widgets; “years” and “months” get disabled. Then a user can select a start date and/or end date by which the data will be filtered. Displayed below is my code;

def show_filters():
    if 'date_range_toggle' not in st.session_state:
        st.session_state.date_range_toggle = False

    years = st.multiselect("Select Years", get_years_since_2022(),
                           placeholder="You can choose multiple options",
                           default=datetime.datetime.now().year if st.session_state.date_range_toggle is False else None,
                           disabled=st.session_state.date_range_toggle)

    months = st.multiselect("Select Months", get_month_name_dict().values(),
                            placeholder="You can choose multiple options",
                            default=None,
                            disabled=st.session_state.date_range_toggle)

    cost_categories = st.multiselect("Select Categories", get_cost_categories(),
                                     placeholder="You can choose multiple options")

    filter_by_date_range = st.toggle("Filter by date range",
                                     on_change=reset_years_and_months())

    if filter_by_date_range:
        start_date = st.date_input("Start Date (dd/mm/yyyy)", value=None, format="DD/MM/YYYY",
                                   max_value=datetime.datetime.now(),
                                   min_value=datetime.date(2022, 8, 1),
                                   help="Start Date **MUST** be less than/equal to End Date")

        end_date = st.date_input("End Date (dd/mm/yyyy)", value=None, format="DD/MM/YYYY",
                                 max_value=datetime.datetime.now(),
                                 min_value=datetime.date(2022, 8, 1),
                                 help="End Date **MUST** be greater than/equal to Start Date")

        return years, months, cost_categories, start_date, end_date

    return years, months, cost_categories, None, None



def reset_years_and_months():
    st.session_state.date_range_toggle = not st.session_state.date_range_toggle

On running this code, very unexpected and random behaviour suffices. When I toggle the button on, the years and months widgets get disabled but on selecting a start date, they get enabled again and the wrong filtration happens. Then when I toggle off, the years and months widgets get disabled. And when I toggle on again, the years and months widgets get enabled and yet they should not. I believe it is something I am missing with the session state. Any pointers would be great.

This is a sample of how it can be done.



disable_status = st.toggle("Enable", value=True)
st.multiselect("Select", options=[i for i in range(10)], disabled=not disable_status)

There was a need to set the date_range_toggle to True when the date filters changed. I used another callback for this. Additionally, I was not passing my call-back functions correctly to the on_change argument. I was passing my function like this on_click=callback_func(result) instead of like this callback(result) which caused the function to execute when the associated widget was mounted (during the page load and before a user clicks the button).

Thank you for your assistance @CarlosSerrano

@Arnold_Kigonya
I will suggest that you change that on_click from
on_click=callback_func(result)
to
on_click=callback_func, args=[result]

This is the correct way of passing arguments to that callback function.

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