Universal Toggle Widget

Hi,

I hereby present you my universal toggle widget. The widget can be used in three different ways:

  1. Toggle a single switch
  2. Toggle a number of similar switches (e.g. some light switches)
  3. Toggle a number of similar switches (like 2.) together with a main switch to toggle all switches at the same time

Note that the widget does not care what switches you give it when you are using it in mode 3. The way I described it is just the way I am using it/the way it is meant to be used.

This is what it looks like:

And in action:

Configuration:

Title: Card title (leave empty for no title bar)
Footer: Card footer (leave empty for no footer) NOTE: There appears to be a bug that sometimes prevents the scrolling of the grouptoggle swiper slide that I filed here: oh-repeater does not work correctly to populate f7-swiper-slides in f7-swiper · Issue #840 · openhab/openhab-webui · GitHub Setting a card footer with an expression (as in the example) seems to “fix” this but unfortunately not reliably. Please let me know if this is also an issue for you or if you know how to fix it.
F7 Icon: The name of the icon that should be shown in the widget
Color: The color scheme to use for the widget
Main toggle item: The “main switch” for the group or just a single switch if no group is configured (leave empty if you only want to switch a group of items without main switch)
Group toggle array: The array of switches that should be shown on the second slide or the single slide if the Main toggle item is omitted. Syntax: “<Label shown above icon of item 1>”,"<Name of item 1>"|"<Label shown above icon of item 2>","<Name of item 2>", repeat as needed (leave empty if you only need the main switch)

The Code:

uid: universal_toggle_v3
tags: []
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: The card footer
      label: Footer
      name: footer
      required: false
      type: TEXT
    - description: Name of the Icon (see https://framework7.io/icons/ for available icons)
      label: F7 Icon
      name: icon
      required: true
      type: TEXT
    - description: Color scheme for icons and toggles (see https://framework7.io/docs/color-themes.html for available color schemes)
      label: Color
      name: color
      required: true
      type: TEXT
    - context: item
      description: Main toggle item (use for single toggle or as main switch for group)
      label: Item
      name: maintoggle
      required: false
      type: TEXT
    - description: Group toggles (use as group with or without main toggle)
      label: Group toggle Array
      name: grouptogglearray
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jan 26, 2021, 4:56:03 PM
component: f7-card
config:
  title: =(props.title)
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-swiper
            config:
              init: true
              pagination: "=(props.maintoggle) && (props.grouptogglearray) ? true : false"
              params:
                slidesPerView: 1
                pagination:
                  clickable: true
              style:
                width: 100%
                height: 175px
            slots:
              default:
                - component: f7-swiper-slide
                  config:
                    visible: "=(props.maintoggle) ? true : false"
                    style:
                      width: 100%
                      height: 100%
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - display-flex
                            - flex-direction-column
                            - align-items-center
                            - justify-content-space-evenly
                          style:
                            width: 100%
                            height: 100%
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                f7: =props.icon
                                size: '=(props.grouptogglearray) ? "100" : "120"'
                                color: '=items[props.maintoggle].state == "ON" ? props.color : "gray"'
                            - component: oh-toggle
                              config:
                                item: =props.maintoggle
                                colorTheme: =props.color
                            - component: f7-block
                              config:
                                style:
                                  height: 35px
                                  display: '=(props.grouptogglearray) ? "block" : "none"'
                - component: f7-swiper-slide
                  config:
                    visible: "=(props.grouptogglearray) ? true : false"
                  slots:
                    default:
                      - component: f7-swiper
                        config:
                          scrollbar: true
                          params:
                            slidesPerView: 1
                            direction: vertical
                            mousewheel: true
                            scrollbar:
                              hide: true
                          style:
                            width: 100%
                            height: 100%
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: item
                                in: =props.grouptogglearray.split("|")
                                fragment: true
                              slots:
                                default:
                                  - component: f7-swiper-slide
                                    config:
                                      style:
                                        width: 100%
                                        height: 100%
                                    slots:
                                      default:
                                        - component: f7-col
                                          config:
                                            class:
                                              - display-flex
                                              - flex-direction-column
                                              - align-items-center
                                              - justify-content-space-evenly
                                            style:
                                              width: 100%
                                              height: 100%
                                          slots:
                                            default:
                                              - component: f7-block-title
                                                config:
                                                  style:
                                                    margin-top: 10px
                                                    margin-bottom: -2px
                                                slots:
                                                  default:
                                                    - component: Label
                                                      config:
                                                        text: =loop.item.split("\"")[1]
                                              - component: f7-icon
                                                config:
                                                  f7: =props.icon
                                                  size: 70
                                                  color: '=items[loop.item.split("\"")[3]].state == "ON" ? props.color : "gray"'
                                              - component: oh-toggle
                                                config:
                                                  item: =(loop.item.split("\"")[3])
                                                  colorTheme: =props.color
                                              - component: f7-block
                                                config:
                                                  style:
                                                    height: 35px
                                                    display: '=(props.maintoggle) ? "block" : "none"'
    - component: f7-card-footer
      slots:
        default:
          - component: Label
            config:
              text: =props.footer

Please let me see screenshots of what you are using them for :slight_smile:

11 Likes

Forgot to mention that there is actually a fourth mode: if you pass a single item into the group array you get the functionality of a single switch (mode 1.) but with a label on top of the icon.

Your Widghets (also the washing machine and the dishwasher) looks very nice.

if my skills in openhab are better i sure will implement this to my project. Maybe some will work a tutorial out for this? :slight_smile:

Thank you Bernhard! You mean a tutorial for the widgets? I hope I wrote down everything you need to know in the first post. If you have any questions feel free to ask here!