Universal Toggle

I‘m still using it so I would say yes it is still supported. However I do not have an Android device so I never tested this. This sounds a bit weird, are there any fundamental differences in main ui depending on the OS? Anyone else using this widget on android?

Can you show the values of maintoggle und grouptogglearray please? Especially check if the quotes are correct, android might use ” instead of " for example.

You can try this hopefully more robust version though it is not thoroughly tested yet:


uid: universal_toggle_v5
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, format: "Label" "ItemName"|"Label2" "ItemName2"'
      label: Group toggle Array
      name: grouptogglearray
      required: false
      type: TEXT
  parameterGroups: []
component: f7-card
config:
  title: '=(props.title && props.title !== "undefined" && props.title !== "null") ? props.title : ""'
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: oh-context
            config:
              functions:
                # Prop is set (not empty, not the strings "undefined"/"null")
                hasMain: |-
                  =(x) => !['', 'undefined', 'null'].includes((''+props.maintoggle).trim())
                hasGroup: |-
                  =(x) => !['', 'undefined', 'null'].includes((''+props.grouptogglearray).trim())
                footerText: |-
                  =(x) => ['', 'undefined', 'null'].includes((''+props.footer).trim()) ? '' : props.footer
                # Split the group array; typographic quotes (Android keyboards) are normalized to "
                groupList: |-
                  =(x) => !['', 'undefined', 'null'].includes((''+props.grouptogglearray).trim()) ? (''+props.grouptogglearray).replace(/[„“”‟″«»]/g, '"').split('|').map(s => s.trim()).filter(s => s !== '') : []
                # Parse one entry: "Label" "Item" -> {label, item}; a plain item name also works
                entry: |-
                  =(s) => ((m, t) => ({label: m ? m[1] : t, item: m ? m[2] : t}))((''+s).replace(/[„“”‟″«»]/g, '"').match(/"([^"]*)"\s*"([^"]*)"/), (''+s).replace(/[„“”‟″«»"]/g, '').trim())
                # Item exists (avoids errors for typos or items that are not loaded yet)
                valid: |-
                  =(n) => !!items[n]
                # State is ON or a number > 0 (dimmer etc.)
                isOn: |-
                  =(n) => ((s) => s === 'ON' || (!isNaN(parseFloat(s)) && parseFloat(s) > 0))(items[n] ? items[n].state : undefined)
            slots:
              default:
                - component: f7-swiper
                  config:
                    init: true
                    pagination: =(fn.hasMain() && fn.hasGroup())
                    params:
                      allowSlideNext: =fn.hasGroup()
                      allowSlidePrev: =fn.hasGroup()
                      allowTouchMove: =fn.hasGroup()
                      observeParents: true
                      observeSlideChildren: true
                      observer: true
                      pagination: '=(fn.hasMain() && fn.hasGroup()) ? {clickable: true} : false'
                      slidesPerView: 1
                      watchOverflow: true
                    style:
                      height: 175px
                      width: 100%
                  slots:
                    default:
                      # Slide 1: main toggle
                      - component: f7-swiper-slide
                        config:
                          style:
                            height: 100%
                            width: 100%
                          visible: =fn.hasMain()
                        slots:
                          default:
                            - component: f7-col
                              config:
                                class:
                                  - display-flex
                                  - flex-direction-column
                                  - align-items-center
                                  - justify-content-space-evenly
                                style:
                                  height: 100%
                                  width: 100%
                              slots:
                                default:
                                  - component: oh-link
                                    config:
                                      action: toggle
                                      actionItem: =props.maintoggle
                                      actionCommand: 'ON'
                                      actionCommandAlt: 'OFF'
                                      visible: =fn.valid(props.maintoggle)
                                    slots:
                                      default:
                                        - component: f7-icon
                                          config:
                                            color: '=fn.isOn(props.maintoggle) ? props.color : "gray"'
                                            f7: =props.icon
                                            size: '=(fn.hasGroup()) ? "100" : "120"'
                                  - component: oh-toggle
                                    config:
                                      colorTheme: =props.color
                                      item: =props.maintoggle
                                      visible: =fn.valid(props.maintoggle)
                                  - component: f7-block
                                    config:
                                      style:
                                        display: '=(fn.hasGroup()) ? "block" : "none"'
                                        height: 35px
                      # Slide 2: group toggles
                      - component: f7-swiper-slide
                        config:
                          style:
                            height: 100%
                            width: 100%
                          visible: =fn.hasGroup()
                        slots:
                          default:
                            - component: f7-swiper
                              config:
                                params:
                                  direction: vertical
                                  mousewheel: true
                                  scrollbar:
                                    hide: true
                                  setWrapperSize: true
                                  slidesPerView: 1
                                scrollbar: true
                                style:
                                  height: 100%
                                  width: 100%
                              slots:
                                default:
                                  - component: oh-repeater
                                    config:
                                      for: item
                                      fragment: true
                                      in: =fn.groupList()
                                    slots:
                                      default:
                                        - component: f7-swiper-slide
                                          config:
                                            style:
                                              height: 100%
                                              width: 100%
                                          slots:
                                            default:
                                              - component: f7-col
                                                config:
                                                  class:
                                                    - display-flex
                                                    - flex-direction-column
                                                    - align-items-center
                                                    - justify-content-space-evenly
                                                  style:
                                                    height: 100%
                                                    width: 100%
                                                slots:
                                                  default:
                                                    - component: f7-block-title
                                                      config:
                                                        style:
                                                          margin-bottom: -2px
                                                          margin-top: 10px
                                                      slots:
                                                        default:
                                                          - component: Label
                                                            config:
                                                              text: =fn.entry(loop.item).label
                                                    - component: oh-link
                                                      config:
                                                        action: toggle
                                                        actionItem: =fn.entry(loop.item).item
                                                        actionCommand: 'ON'
                                                        actionCommandAlt: 'OFF'
                                                        visible: =fn.valid(fn.entry(loop.item).item)
                                                      slots:
                                                        default:
                                                          - component: f7-icon
                                                            config:
                                                              color: '=fn.isOn(fn.entry(loop.item).item) ? props.color : "gray"'
                                                              f7: =props.icon
                                                              size: 70
                                                    - component: oh-toggle
                                                      config:
                                                        colorTheme: =props.color
                                                        item: =fn.entry(loop.item).item
                                                        visible: =fn.valid(fn.entry(loop.item).item)
                                                    - component: f7-block
                                                      config:
                                                        style:
                                                          display: '=(fn.hasMain()) ? "block" : "none"'
                                                          height: 35px
    - component: f7-card-footer
      slots:
        default:
          - component: oh-context
            config:
              functions:
                footerText: |-
                  =(x) => ['', 'undefined', 'null'].includes((''+props.footer).trim()) ? '' : props.footer
            slots:
              default:
                - component: Label
                  config:
                    text: =fn.footerText()