Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expander resets its expanded state when new elements are included. #2360

Closed
kmcgrady opened this issue Nov 16, 2020 · 14 comments
Closed

Expander resets its expanded state when new elements are included. #2360

kmcgrady opened this issue Nov 16, 2020 · 14 comments

Comments

@kmcgrady
Copy link
Collaborator

kmcgrady commented Nov 16, 2020

Summary

A expander resets when there are changes in the DOM (like an element is inserted before it). This is likely because the element is unmounted and mounted triggering a reset to the expander itself

Steps to reproduce

  1. Run streamlit with the following code:

Open in Streamlit Cloud

import streamlit as st
if st.checkbox("I have something"):
    st.write("Checked")
with st.expander("expand"):
    a = st.selectbox("Choose 1", ['1','2'])
  1. Open the Expander
  2. Click on the checkbox

Expected behavior:

The expander should remain open with "Checked" appearing above it.

Actual behavior:

The expander collapses

Is this a regression?

No

@kmcgrady kmcgrady added type:bug Something isn't working status:needs-triage Has not been triaged by the Streamlit team and removed status:needs-triage Has not been triaged by the Streamlit team labels Nov 16, 2020
@tybirk-mindway
Copy link

Probably related: #2241

@robinsaettele
Copy link

Is there an update on this issue?
As of today I still experience that behaviour.

@vdonato vdonato self-assigned this Mar 1, 2022
@simonlipsonrisk
Copy link

Any update on this? I built a webapp with streamlit for my team and this behaviour happens for half the team and not for the rest. Seems weird and I can't think of or find a resolution. But because it doesn't happen to some people (myself included), i'm assuming its not related to the code i've written and possibly to something else. Any ideas?

@kmcgrady
Copy link
Collaborator Author

Hi @simonlipsonrisk I can try to provide guidance, but would need to look at the code. The main challenge that always exists is connecting the actual line of code to the specific element in the DOM. In many cases, we connect it correctly, but expanders have been unique as a layout feature and not an element.

This is a result of an element appearing or disappearing before causing a misalignment in this connection. For the example above, The following workaround would work.

import streamlit as st

checked = st.checkbox("I have something")
placeholder = st.empty()
if checked:
    placeholder.write("Checked")
with st.expander("expand"):
    a = st.selectbox("Choose 1", ['1','2'])

Note the use of st.empty() to signify something is there, but not necessarily used is something that allows you to not have this problematic behavior.

Hope that helps!

@simonlipsonrisk
Copy link

simonlipsonrisk commented Mar 10, 2022

Thanks @kmcgrady . I'm not sure its relevant to my situation. I'll give a short version of the code that captures what happens. Basically I have check boxes within the expander and for some people, when the box is checked or unchecked, the expander closes. whereas for others it does not close. The code is something similar to

with st.expander("open expander"):
    checked = st.checkbox('check me')
    if checked:
        do something
    else:
        do something else

Does it make sense that checking or unchecking the checkbox in the above could result with the expander closing? And could the st.empty() help in this case?

Thanks

@kmcgrady
Copy link
Collaborator Author

Hmmmm @simonlipsonrisk can't say I understand what's going on here. This issue corresponds to items around the expander appearing and not, vs. the expander itself.

We did some work recently with regards to multiple expanders #4290 in case you are not working on the latest version. That being said, if you have a repro case with a small code sample that demonstrates the issue, it could be investigated.

@simonlipsonrisk
Copy link

@kmcgrady I found the cause of my issue (however not sure what the real underlying issue is). The people in my team that have the latest version (1.7.0) of streamlit experience the closing expanders whereas those of us that have version 1.2.0 do not experience this issue. I even upgraded my streamlit to 1.7.0 and did experience the same issue where the expanders close. So definitely seems it due to difference in version.

That being said, I'm not sure what it is about 1.7.0 thats making those expanders close. I also tried replicating it with a smaller webapp however wasn't able to replicate. If I do succeed, i'll send you the code.

@simonlipsonrisk
Copy link

Ok @kmcgrady I worked out the issue. To spice-up the webapp, I wrote a function that returns a random emoji from a list and then would call that function when creating the title for each expander

with st.expander(f"Top Level {random_emoji()}"):

Whenever anything happened within the expander, it calls that random_emoji function again and updates the emoji in the title. As its technically a new title, I guess there can be an argument that it should be closed as its a new expander and expanders by definition start closed. In streamlit 1.2.0 it does not close but in streamlit 1.7.0 it does. I am not sure what behaviour makes more sense. But I do know that it was wrong (and lazy) of me to call the function within the title string and not set it as a variable before and just inject the variable into the title after.

Here's code that replicates it and you can see for yourself and decide what behaviour is best in this case.

import streamlit as st
import random


def random_emoji():

    emojis = ['\U0001F43E', '\U0001F415', '\U0001F436']
    emoji_count = len(emojis)
    emoji_index = random.randint(0, emoji_count - 1)

    return emojis[emoji_index]

with st.expander(f'expand number{random_emoji()}'):

    for n in range(5):
    
        checked = st.checkbox(f"Do you want to check number{n}?", value = False)

@kmcgrady
Copy link
Collaborator Author

Ah yea @simonlipsonrisk Thanks for the write up! That makes sense. We had made the decision that an expander is a layout element. An argument can be made that an expander is like a widget (text input, etc) with a state. In that case, one solution is the key parameter to make reconciliation between python and the frontend much easier. As more issues like this comes in, we can consider it more.

@davnat
Copy link

davnat commented Sep 2, 2022

I think I'm also hit by this, on v1.12.2.
I have some expanders with dynamic content inside, and they keep closing whenever something in the content changes: it's quite annoying.
If expanders had a state key I could try to write a workaround, but this is not the case.
Do you have any suggestions?

@JawaClass
Copy link

On 1.23.1

Setting the expanded flag to True in the rerun when the expander label was changed keeps it open for me. Only once probably, but thats enough for my case, since I add a little emoji if the user edited the data inside.
Its really really annoying having the expander collapse if the user edits data inside, especially if u have a dozen of those. Have fun finding the expander u just edited 🥲 :

@sfc-gh-mbarnes
Copy link
Contributor

Similar underlying issue to #6257

@sfc-gh-jcarroll
Copy link
Collaborator

I made a demo app to show the behavior: https://container-state-bugs.streamlit.app/Expander_example

Note the same thing happens with st.status

Having some discussions within the Streamlit team about whether / how we address this long term.

@mayagbarnes
Copy link
Collaborator

Thank you all for your input on this issue, it is sincerely appreciated! 😄 Since this is expected behavior for the st.expander React component in its current form, we are closing this issue in favor of consolidating the feedback into a feature/enhancement request here.

Feel free to upvote the request, as its helpful to us in gauging interest & priority. Really appreciate your usage of Streamlit & engagement in making it even better!! 🎈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests