Closing f7-popup

Hi!
i have created a widget with popup but i don’t understand how i can close the popup manually…
this is the widget with poup:

for now i helped myself with swipeToClose: true but there must be a better way to close the popup.
i don’t want to spam in the beautifull main ui examples thread so i hope it’s ok to open a new thread…

You have already discovered popupOpen:

- component: oh-link
      config:
        action: popup
        popupOpen: .myPopupOpenDI

oh-link and oh-button both have a complimentary popupClose property as well. Just include a link or a button on the popup itself and set popupClose to the same popup class .myPopupOpenDI (you don’t even need the popup action):

- component: oh-link
      config:
        text: Close this popup
        popupClose: .myPopupOpenDI
1 Like

this is great, thank you so much!

oh man, i thought the issue was resolved but now i found another (big?) problem:
when i put multiple widgets with the .myPopupOpenDI on the same page only one works as expected, but all the others open the same popup :frowning: with the same item…

here’s (part of) the yaml of my page:

              - component: oh-grid-col
                config:
                  large: "20"
                  xlarge: "20"
                  medium: "33"
                  width: "33"
                slots:
                  default:
                    - component: widget:Card_Dimmer
                      config:
                        header: Tisch
                        item: Licht_Esstisch
              - component: oh-grid-col
                config:
                  large: "20"
                  xlarge: "20"
                  medium: "33"
                  width: "33"
                slots:
                  default:
                    - component: widget:Card_Dimmer
                      config:
                        header: Wohnzimmer
                        item: Licht_Wohnzimmer

both widgets open the Dimmer Widget with “Licht Wohnzimmer” als Item.
When i remove the second widget the first widget works correctly with “Licht_Esstisch”.
so i suppose the popupOpen parameter must be unique?

looks like it works with this workaround (popUp parameter = itemname + “popUp”):

    - component: oh-link
      config:
        action: popup
        popupOpen: ='.' + props.item + 'popUp'
        style:
          position: absolute
          top: 0px
          left: 0px
          width: 100%
          height: 30px
      slots:
        default:
          - component: f7-popup
            config:
              class: =props.item + 'popUp'
              swipeToClose: true
              style:
                --f7-popup-tablet-width: 70%
                --f7-popup-tablet-height: 101px
            slots:
              default:
                - component: widget:Popup_Dimmer2
                  config:
                    item: =props.item
                    title: =props.header
                    popupClass: ='.' + props.item + 'popUp'

but i have a feeling this approach is not very good, is it?

Sure. As it appears that each instance on the page has a different item associated with it, you already have a unique identifier that can be accessed throughout the widget which is fully compatible with a css class name: props.item.

All you need to do is incorporate the props.item string into the class name of the popup in the widget. For example:

popupOpen: ='.myPopupOpenDI' + props.item

The only trick to this is that in the popup itself

class:
  - '.myPopupOpenDI' + props.item

won’t work because of the way the array elements are processed. However, as long as this is the only class that you are assigning to the popup up you can just use

class: ='.myPopupOpenDI' + props.item

just like in the open and close calls. If you need multiple classes, then it gets only a little more difficult because you need to build the array as a string.

thanks for the fast reply! after some thinking (obviously this couldn’t come to my mind before posting…) i was able to incorporate the props.item into the class name of the popup (see edit of my last post) :slight_smile:
is my approach on closing the popup with passing the class name of the popup in the widget to the widget:popup itself wrong?
i have this in the popupwidget:

    - component: oh-button
      config:
        text: close
        popupClose: =props.popupClass
        color: "=themeOptions.dark === 'dark' ? 'white' : 'black'"
        style:
          position: absolute
          right: 10px
          top: 8px

and it looks like it’s working. i must confess, i don’t really understand the 2nd part of your post ( the “class” part)… if that approach is better (less wrong?) i’ll try to figure it out, but if it’s all the same i think i’ll stick with my actual code :grimacing:

It’s not wrong. It works just as well. The only real downside is that it makes an additional configuration point for the widget which isn’t really necessary because the props.item is already configured. That’s not really a huge downside.

It’s quite possible to conceive of a widget where this approach is actually preferable because the widget is sufficiently generalized that there is more than one copy of the widget for the same item in which case the props.item trick would be insufficient and a props.popup class name or at least suffix would be required.

ok, with my luck i’m pretty sure i’ll run into this problem sooner or later.

could you elaborate this part?

i’m afraid i’d need some (more) context how this works…

Multiple css classes can be applied to an object. To handle this in the yaml widget definitions, the easiest option often is to represent this list of classes as an array. You are already familiar with this syntax, it’s all you’re doing every time you put several components in the same space and start each component definition with -.

some slot:
  - component 1
    config etc.
  - component 2
    config etc.
  - component 3
    config etc.

That’s an array of three components in one slot.

So if you needed to add multiple classes to a component you just use that array syntax:

class:
  - pretty.css
  - weird.position.css
  - unique.popup.target

The only point I was making is that when you are building the array like that you cannot have dynamic strings (that is strings that are built out of other pieces and variables), those expressions just aren’t processed at the moment. So, if you tried:

class: ='popup_'+props.item

and

class:
  - 'popup_'+props.item

you would get different results. The first comes out as you would expect and the class is popup_some_oh_item_name but the second doesn’t calculate anything and the class winds up just being 'popup'+props.item. There are workarounds for this if you run into the problem, but it’s only a problem if: 1) you are trying to add more than one class to your component and 2) some of those classes need to be dynamically defined.

thank you again for the information! are there any examples for a “full” widget where this is used?

I don’t have one. There might be some around the forum but searching for them might be difficult. Here is one thread where this syntax is shown:

1 Like

A solution is given here: https://community.openhab.org/t/customwidget-popover-item-from-parameter-does-not-use-the-configuration-of-the-specific-widget-but-the-last-widget/113980/3

You have to make the popup into its own widget, then pass the parameters along.