Anvil Extras - multiselect dropdown in popover / columnpanel - sub-component remains on screen

What I’m trying to do:
Resolve a subcomponent of anvil extras popover refusing to die:

What I’ve tried and what’s not working:
Various combinations of destroying the popover

Code Sample:
As per clone

Clone link:
https://anvil.works/build#clone:P3X36YKLRC4T23II=73SMDRXBPCB4RCZHZCHVTEUA

1 Like

Thanks for the clone - it was very helpful.
For bug reports on anvil-extras components it’s usually better to submit an issue at the anvil-extras repository.
I’ve added the issue here:

multiselect dropdown and popover bugs · Issue #186 · anvilistas/anvil-extras · GitHub


For the button_1 version that’s definitely a case of - that should probably fail on the line:

self.button_1.popover(self.column_panel_1)

You shouldn’t be able to add a component to a popover that already has a parent.
(We’ll add a warning for this).


button_2 is definitely a bug. It seems to be a race condition.
Here’s a temporary patch you can add at the top of the file until that gets fixed:

def _form_hide(self, **event_args):
    self._el.data("selectpicker")["$bsContainer"].detach()
MultiSelectDropDown._form_hide = _form_hide

for button_3 with the search. There’s no easy way to fix that with a simple patch.
You can implement some manual behaviour by setting auto_dismiss=False for the popover.
This way you’re in control of the transition.
It’s possible to fix internally - so we’ll add that to our list.

1 Like

No problems - I wasn’t sure if these were legit issues or I was just doing something dumb.

Re this - You shouldn’t be able to add a component to a popover that already has a parent. - why not?

I foresee practical UI reasons for wanting this exact behaviour - popovers only take up space on demand and could be useful for replicating a form or container that is otherwise hidden (like a viewport).

It’s fine to create your popover form as a BlankPanel,
then import that form in the usual way,
and use that form as the popover component.

It’s also fine to add the component to another container,
then call remove_from_parent,
before using it as a popover component.

But if you try to do the following in anvil

self.add_component(self.column_panel_1)

You get

# ValueError: This component is already added to a container, call remove_from_parent() first

There are good reasons that anvil raises this error.

Here’s one reason that popovers would need the parent to be correct.
By not removing the component from its previous parent container,
anvil’s show hide events will not fire correctly for that popover component.
And since components like the MultiSelectDropdown do a bunch of instantiation and clean up using those events the popover behaviour might behave strangely for certain components if you do this.

Do raise an issue at anvil-extras if this comes up.

1 Like

Yes. I think I did this inadvertently but created the result I was after:

https://anvil.works/build#clone:WPESSE6LBIR72G56=2BLBAEMVV55QTOLTOGQM2SM2

See button_4 - Clone shows the progression of how I got to button_4 via trying button_5 through button_7 approaches in turn - apologies, there are a couple of programmatic horror shows in there (this reflects the limits in my conceptual grasp of what is going on) :grinning: :shushing_face:

button_4 displays the ColumnPanel containing multselect dropdown & label - but this CP is inside a parent ‘hidden’ ColumnPanel. I think this is what you meant by the show/hide events not firing correctly… but actually resulting in the effect I was after - not being displayed to user on Form1, except on demand via popover on button_4. Ta dah!

Why? (1) I got ‘stuck’ on how to dynamically update the dropdown items across forms, (2) it keeps everything contained on the one form, which I just found easier to visualise / modify / test, and (3) it worked, so I ran with it (aside from the bug…).

Agreed. See (1) above, I just got stuck :grinning: - I suspect through my own ignorance.

Although, I must say, I have subsequently found the process needed get to a solution via the button_4 approach is quicker & easier that going down the blank panel route, i.e. create the CP & components on Form1, drop in the data / test on demand etc, then drop the CP into a ‘hidden’ parent & you’re good to go. Probably a coder’s nightmare, but way easier from my point of view, and the outcome was fine by me.

No need to prolong this thread - I just thought there might be some value in sharing the progression that led to some odd popover behaviour & a bug quite by accident.

Just an update - you can check out the fix for this if you switch to the Development version for the anvil-extras dependency. It’ll be added to the Production version in the next release.

4 Likes