Oh-repeater with accordion slots

I’m trying to build a widget with an accordion list where the list items are generated by an oh-repeater, but I’m running into a problem. The oh-repeater doesn’t seem to be passing the child elements correctly to the accordion list items.

Here’s a simplified example:

uid: widget_repeater_test
component: oh-list-card
config:
  accordionList: true
  title: Simple Accordion Repeater
slots:
  default:
    - component: oh-list-item
      config:
        title: Item 1
      slots:
        accordion:
          - component: f7-segmented
            config:
              raised: true
            slots:
              default: 
                - component: oh-button
                  config:
                    text: ON
                    raised: true
                    action: command
                    actionItem: dummyItem
                    actionCommand: ON
                - component: oh-button
                  config:
                    text: OFF
                    raised: true
                    action: command
                    actionItem: dummyItem
                    actionCommand: OFF
                - component: oh-button
                  config:
                    text: ADD
                    raised: true
                    action: command
                    actionItem: dummyItem
                    actionCommand: ADD
                - component: oh-button
                  config:
                    text: REMOVE
                    raised: true
                    action: command
                    actionItem: dummyItem
                    actionCommand: REMOVE

This works as expected and produces the widget below with a functional button row hidden in an accordion line.

The problem arises when list items are generated by a repeater.

uid: widget_repeater_test
component: oh-list-card
config:
  accordionList: true
  title: Simple Accordion Repeater
slots:
  default:
    - component: oh-repeater
      config:
        fragment: true
        for: listItem
        in: 
          - Item 1
          - Item 2
          - Item 3
      slots:
        default:
          - component: oh-list-item
            config:
              title: =loop.listItem
            slots:
              accordion:
                - component: f7-segmented
                  config:
                    raised: true
                  slots:
                    default: 
                      - component: oh-button
                        config:
                          text: ON
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: ON
                      - component: oh-button
                        config:
                          text: OFF
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: OFF
                      - component: oh-button
                        config:
                          text: ADD
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: ADD
                      - component: oh-button
                        config:
                          text: REMOVE
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: REMOVE

The resulting widget looks correct on initial inspection and the list items even show accordion chevrons but those chevrons cannot be clicked.

A quick inspection of the html shows that no accordion-item-content element has been generated.

<li class="accordion-item" fragment="61835448df">
  <a class="item-link">
    <div class="item-content" accordionitem="true">
      <div class="item-inner">
        ::before
        <div class="item-title">Item 1</div>
        ::after
      </div>
    </div>
  </a>
  <!---->
  <!---->
  <!---->
  <!---->
</li>

I don’t know if 1) I’m doing something wrong, 2) I’ve hit a technical limitation, or 3) I’ve found an issue.

Looks like a technical limitation/bug.
The oh-list-item will look into its parent component (which usually is a f7-list or oh-list) for the accordionList parameter to render the f7-accordion-content.

In this case, the parent is the oh-repeater.

The workaround is, well, to add it to the oh-repeater even if it’s not a valid parameter, just to make the oh-list-item happy :slight_smile:

uid: widget_repeater_test
component: oh-list-card
config:
  accordionList: true
  title: Simple Accordion Repeater
slots:
  default:
    - component: oh-repeater
      config:
        fragment: true
        accordionList: true
        for: listItem
        in: 
          - Item 1
          - Item 2
          - Item 3
      slots:
        default:
          - component: oh-list-item
            config:
              title: =loop.listItem
            slots:
              accordion:
                - component: f7-segmented
                  config:
                    raised: true
                  slots:
                    default: 
                      - component: oh-button
                        config:
                          text: ON
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: ON
                      - component: oh-button
                        config:
                          text: OFF
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: OFF
                      - component: oh-button
                        config:
                          text: ADD
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: ADD
                      - component: oh-button
                        config:
                          text: REMOVE
                          raised: true
                          action: command
                          actionItem: dummyItem
                          actionCommand: REMOVE
1 Like

Makes sense. Thanks!

@JustinG , can you please help to get accordion working inside oh-repeater in my watering widget? I try to hide 2 options for each channel into accordion, but can’t get what i want.

uid: Watering_v1
tags: []
props:
  parameters:
    - description: A text prop
      label: Prop 1
      name: prop1
      required: false
      type: TEXT
    - context: item
      description: An item to control
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Aug 14, 2021, 1:10:49 AM
component: f7-card
config:
  style:
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
    height: auto
    margin: 5px
    line-height: 1.2
    font-family: sans-serif
slots:
  default:
    - component: f7-card-header
      config:
        class:
          - justify-content-center
          - align-items-center
          - text-align-center
      slots:
        default:
          - component: Label
            config:
              text: Полив
              style:
                font-size: 250%
    - component: f7-card-content
      config:
        style:
          margin: 5px
          padding: 0px
      slots:
        default:
          - component: f7-row
            slots:
              default:
                - component: f7-segmented
                  config:
                    strong: true
                    color: green
                    class:
                      - segmented-strong
                    style:
                      --f7-segmented-strong-padding: 5px
                      --f7-segmented-strong-between-buttons: 5px
                      --f7-segmented-strong-button-font-weight: 300
                      --f7-segmented-strong-bg-color: transparent
                      --f7-segmented-strong-button-hover-bg-color: rgba(255, 255, 255, 0.15)
                      width: 100%
                      outline: true
                  slots:
                    default:
                      - component: oh-button
                        config:
                          text: Утром
                          action: variable
                          actionVariable: select
                          actionVariableValue: 1
                          active: =(vars.select == 1)
                          outline: =(vars.select == 1)
                          style:
                            font-weight: 400
                            font-size: 150%
                      - component: oh-button
                        config:
                          text: Вечером
                          action: variable
                          actionVariable: select
                          actionVariableValue: 2
                          active: =(vars.select == 2)
                          outline: =(vars.select == 2)
                          style:
                            font-weight: 400
                            font-size: 150%
                      - component: oh-button
                        config:
                          text: Днём
                          action: variable
                          actionVariable: select
                          actionVariableValue: 3
                          active: =(vars.select == 3)
                          outline: =(vars.select == 3)
                          style:
                            font-weight: 400
                            font-size: 150%
          - component: f7-tab
            config:
              visible: =(vars.select == 1 || vars.select == NULL)
              style:
                animation: f7-fade-in 300ms
                padding: 0px
                margin: 5px
                margin-right: 5px
              class:
                - display-flex
                - justify-content-space-between
                - flex-direction-column
            slots:
              default:
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      font-size: 120%
                  slots:
                    default:
                      - component: Label
                        config:
                          text: Утренний полив
                      - component: oh-toggle
                        config:
                          item: IrrigationStartAtSunrise
                          color: green
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      font-size: 120%
                  slots:
                    default:
                      - component: f7-row
                        config: {}
                        slots:
                          default:
                            - component: Label
                              config:
                                text: "Рассвет:"
                                style:
                                  margin-right: 10px
                            - component: Label
                              config:
                                text: =items.Voshod.displayState
                      - component: f7-row
                        config: {}
                        slots:
                          default:
                            - component: Label
                              config:
                                text: Время после рассвета
                                style:
                                  margin-right: 10px
                            - component: oh-link
                              config:
                                color: green
                                text: =items.IrrigationHoursAfterSunrise.state
                                action: popover
                                popoverOpen: .timerpopover
                              slots:
                                default:
                                  - component: f7-popover
                                    config:
                                      class:
                                        - timerpopover
                                    slots:
                                      default:
                                        - component: oh-stepper-card
                                          config:
                                            color: green
                                            item: IrrigationHoursAfterSunrise
                                            title: Минут после рассвета
                                            min: 0
                                            max: 180
                                            step: 10
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      margin-bottom: 15px
                      font-size: 120%
                  slots:
                    default:
                      - component: f7-row
                        config: {}
                        slots:
                          default:
                            - component: Label
                              config:
                                text: "Время начала полива:"
                                style:
                                  margin-right: 10px
                            - component: Label
                              config:
                                text: =items.IrrigationStartTime.displayState
                - component: f7-list
                  config:
                    accordionList: true
                    style:
                      padding: 5px
                      margin: 0px
                      font-size: 120%
                      border: 1px solid green
                      border-radius: var(--f7-card-expandable-border-radius)
                      display: inline
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          fragment: false
                          for: item
                          sourceType: itemsInGroup
                          groupItem: GroupIrrigationValves
                        slots:
                          default:
                            - component: f7-row
                              config:
                                style:
                                  margin-top: 5px
                                  display: flex
                                  justify-content: flex-start
                                  align-items: center
                              slots:
                                default:
                                  - component: oh-icon
                                    config:
                                      icon: water
                                      width: 25px
                                  - component: Label
                                    config:
                                      icon: oh:water
                                      text: =loop.item.label
                                      style:
                                        margin-left: 10px
                                  - component: oh-stepper
                                    config:
                                      item: =(loop.item.name + 'Time1')
                                      title: Время полива
                                      min: 0
                                      max: 180
                                      step: 1
                                      round: true
                                      fill: true
                                      raised: true
                                      color: green
                                      autorepeat: true
                                      autorepeat-dynamic: true
                                      style:
                                        margin-left: auto
                            - component: f7-segmented
                              config:
                                strong: true
                                small: true
                                outline: true
                                color: green
                                class:
                                  - segmented-round
                                style:
                                  --f7-segmented-strong-padding: 0px
                                  --f7-segmented-strong-between-buttons: 5px
                                  --f7-segmented-strong-button-font-weight: 300
                                  --f7-segmented-strong-bg-color: transparent
                                  --f7-segmented-strong-button-hover-bg-color: rgba(0, 255, 0, 0.1)
                                  --f7-segmented-strong-button-active-bg-color: transparent
                                  margin-top: 5px
                              slots:
                                default:
                                  - component: oh-repeater
                                    config:
                                      fragment: true
                                      for: day
                                      sourceType: array
                                      in:
                                        - name: 1
                                          label: Пн
                                        - name: 2
                                          label: Вт
                                        - name: 3
                                          label: Ср
                                        - name: 4
                                          label: Чт
                                        - name: 5
                                          label: Пт
                                        - name: 6
                                          label: Сб
                                        - name: 7
                                          label: Вс
                                    slots:
                                      default:
                                        - component: oh-button
                                          config:
                                            text: =loop.day.label
                                            action: toggle
                                            actionCommand: ON
                                            actionCommandAlt: OFF
                                            actionItem: =(loop.item.name + 'M' + loop.day.name)
                                            fill: "=(items[loop.item.name + 'M' + loop.day.name].state === 'ON' ? true : false)"
                                            style:
                                              font-weight: 400
                            - component: f7-list-item
                              config:
                                accordionItem: true
                                style:
                                  margin: 10 px
                              slots:
                                default:
                                  - component: f7-row
                                    config:
                                      style:
                                        margin: 10px
                                        display: flex
                                        justify-content: space-between
                                        align-items: center
                                    slots:
                                      default:
                                        - component: Label
                                          config:
                                            text: "Коррекция: по температуре"
                                            style:
                                              font-size: 12px
                                        - component: oh-toggle
                                          config:
                                            color: green
                                            item: =(loop.item.name + 'TimeCorrection')
                                        - component: Label
                                          config:
                                            text: по осадкам
                                            style:
                                              font-size: 12px
                                        - component: oh-toggle
                                          config:
                                            color: green
                                            item: =(loop.item.name + 'RainCorrection')
          - component: f7-tab
            config:
              visible: =(vars.select == 2)
              style:
                animation: f7-fade-in 300ms
                padding: 0px
                margin: 5px
                margin-right: 5px
              class:
                - display-flex
                - justify-content-space-between
                - flex-direction-column
            slots:
              default:
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      font-size: 120%
                  slots:
                    default:
                      - component: Label
                        config:
                          text: Вечерний полив
                      - component: oh-toggle
                        config:
                          item: IrrigationStartAtSunrise
                          color: green
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      font-size: 120%
                  slots:
                    default:
                      - component: f7-row
                        config: {}
                        slots:
                          default:
                            - component: Label
                              config:
                                text: "Закат:"
                                style:
                                  margin-right: 10px
                            - component: Label
                              config:
                                text: =items.Zakat.displayState
                      - component: f7-row
                        config: {}
                        slots:
                          default:
                            - component: Label
                              config:
                                text: Время до заката
                                style:
                                  margin-right: 10px
                            - component: oh-link
                              config:
                                color: green
                                text: =items.IrrigationHoursBeforeSundown.state
                                action: popover
                                popoverOpen: .timerpopover
                              slots:
                                default:
                                  - component: f7-popover
                                    config:
                                      class:
                                        - timerpopover
                                    slots:
                                      default:
                                        - component: oh-stepper-card
                                          config:
                                            color: green
                                            item: IrrigationHoursBeforeSundown
                                            title: Минут после рассвета
                                            min: 0
                                            max: 180
                                            step: 10
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      margin-bottom: 15px
                      font-size: 120%
                  slots:
                    default:
                      - component: f7-row
                        config: {}
                        slots:
                          default:
                            - component: Label
                              config:
                                text: "Время начала полива:"
                                style:
                                  margin-right: 10px
                            - component: Label
                              config:
                                text: =items.IrrigationStartTime3.displayState
                - component: f7-row
                  config:
                    style:
                      padding: 5px
                      margin: 0px
                      font-size: 120%
                      border: 1px solid green
                      border-radius: var(--f7-card-expandable-border-radius)
                      display: inline
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          accordionList: true
                          fragment: false
                          for: item
                          sourceType: itemsInGroup
                          groupItem: GroupIrrigationValves
                        slots:
                          default:
                            - component: f7-row
                              config:
                                style:
                                  margin-top: 5px
                                  display: flex
                                  justify-content: flex-start
                                  align-items: center
                              slots:
                                default:
                                  - component: oh-icon
                                    config:
                                      icon: water
                                      width: 25px
                                  - component: Label
                                    config:
                                      icon: oh:water
                                      text: =loop.item.label
                                      style:
                                        margin-left: 10px
                                  - component: oh-stepper
                                    config:
                                      item: =(loop.item.name + 'Time2')
                                      title: Время полива
                                      min: 0
                                      max: 180
                                      step: 1
                                      round: true
                                      fill: true
                                      raised: true
                                      color: green
                                      autorepeat: true
                                      autorepeat-dynamic: true
                                      style:
                                        margin-left: auto
                            - component: f7-segmented
                              config:
                                strong: true
                                small: true
                                outline: true
                                color: green
                                class:
                                  - segmented-round
                                style:
                                  --f7-segmented-strong-padding: 0px
                                  --f7-segmented-strong-between-buttons: 5px
                                  --f7-segmented-strong-button-font-weight: 300
                                  --f7-segmented-strong-bg-color: transparent
                                  --f7-segmented-strong-button-hover-bg-color: rgba(0, 255, 0, 0.1)
                                  --f7-segmented-strong-button-active-bg-color: transparent
                                  margin-top: 5px
                              slots:
                                default:
                                  - component: oh-repeater
                                    config:
                                      fragment: true
                                      for: day
                                      sourceType: array
                                      in:
                                        - name: 1
                                          label: Пн
                                        - name: 2
                                          label: Вт
                                        - name: 3
                                          label: Ср
                                        - name: 4
                                          label: Чт
                                        - name: 5
                                          label: Пт
                                        - name: 6
                                          label: Сб
                                        - name: 7
                                          label: Вс
                                    slots:
                                      default:
                                        - component: oh-button
                                          config:
                                            text: =loop.day.label
                                            action: toggle
                                            actionCommand: ON
                                            actionCommandAlt: OFF
                                            actionItem: =(loop.item.name + 'E' + loop.day.name)
                                            fill: "=(items[loop.item.name + 'E' + loop.day.name].state === 'ON' ? true : false)"
                                            style:
                                              font-weight: 400
                            - component: f7-row
                              config:
                                accordionItem: true
                                style:
                                  margin: 10px
                                  display: flex
                                  justify-content: space-between
                                  align-items: center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "Коррекция: по температуре"
                                      style:
                                        font-size: 12px
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =(loop.item.name + 'TimeCorrection')
                                  - component: Label
                                    config:
                                      text: по осадкам
                                      style:
                                        font-size: 12px
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =(loop.item.name + 'RainCorrection')
          - component: f7-block
            config:
              visible: =(vars.select == 3)
              style:
                animation: f7-fade-in 300ms
                width: 99%
                padding: 0px
                margin: 5px
                margin-right: 5px
              class:
                - display-flex
                - justify-content-space-between
                - flex-direction-column
            slots:
              default:
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                      width: 99%
                      font-size: 120%
                  slots:
                    default:
                      - component: Label
                        config:
                          text: Дневной полив
                      - component: oh-toggle
                        config:
                          item: IrrigationStartAtSpecificHour
                          color: green
                - component: f7-row
                  config:
                    style:
                      margin: 5px
                  slots:
                    default:
                      - component: Label
                        config:
                          text: Время начала полива
                      - component: oh-link
                        config:
                          color: green
                          text: =items.IrrigationStartTime2.displayState
                          action: popup
                          actionModal: widget:timepicker_1
                          actionModalConfig:
                            item: IrrigationStartTime2
                - component: f7-row
                  config:
                    style:
                      padding: 5px
                      margin: 0px
                      font-size: 120%
                      border: 1px solid green
                      border-radius: var(--f7-card-expandable-border-radius)
                      display: inline
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          fragment: false
                          for: item
                          sourceType: itemsInGroup
                          groupItem: GroupIrrigationValves
                        slots:
                          default:
                            - component: f7-row
                              config:
                                style:
                                  margin-top: 5px
                                  display: flex
                                  justify-content: flex-start
                                  align-items: center
                              slots:
                                default:
                                  - component: oh-icon
                                    config:
                                      icon: water
                                      width: 25px
                                  - component: Label
                                    config:
                                      icon: oh:water
                                      text: =loop.item.label
                                      style:
                                        margin-left: 10px
                                  - component: oh-stepper
                                    config:
                                      item: =(loop.item.name + 'Time')
                                      title: Время полива
                                      min: 0
                                      max: 180
                                      step: 1
                                      round: true
                                      fill: true
                                      raised: true
                                      color: green
                                      autorepeat: true
                                      autorepeat-dynamic: true
                                      style:
                                        margin-left: auto
                            - component: f7-segmented
                              config:
                                strong: true
                                small: true
                                outline: true
                                color: green
                                class:
                                  - segmented-round
                                style:
                                  --f7-segmented-strong-padding: 0px
                                  --f7-segmented-strong-between-buttons: 5px
                                  --f7-segmented-strong-button-font-weight: 300
                                  --f7-segmented-strong-bg-color: transparent
                                  --f7-segmented-strong-button-hover-bg-color: rgba(0, 255, 0, 0.1)
                                  --f7-segmented-strong-button-active-bg-color: transparent
                                  margin-top: 5px
                              slots:
                                default:
                                  - component: oh-repeater
                                    config:
                                      fragment: true
                                      for: day
                                      sourceType: array
                                      in:
                                        - name: 1
                                          label: Пн
                                        - name: 2
                                          label: Вт
                                        - name: 3
                                          label: Ср
                                        - name: 4
                                          label: Чт
                                        - name: 5
                                          label: Пт
                                        - name: 6
                                          label: Сб
                                        - name: 7
                                          label: Вс
                                    slots:
                                      default:
                                        - component: oh-button
                                          config:
                                            text: =loop.day.label
                                            action: toggle
                                            actionCommand: ON
                                            actionCommandAlt: OFF
                                            actionItem: =(loop.item.name + 'D' + loop.day.name)
                                            fill: "=(items[loop.item.name + 'D' + loop.day.name].state === 'ON' ? true : false)"
                                            style:
                                              font-weight: 400
                            - component: f7-row
                              config:
                                style:
                                  margin: 10px
                                  display: flex
                                  justify-content: space-between
                                  align-items: center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "Коррекция: по температуре"
                                      style:
                                        font-size: 12px
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =(loop.item.name + 'TimeCorrection')
                                  - component: Label
                                    config:
                                      text: по осадкам
                                      style:
                                        font-size: 12px
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =(loop.item.name + 'RainCorrection')

If you are using the f7 list components directly then the problem is not the repeater but the fact that you need an additional component, the f7-accordion-content as a child of the list item. That content component can then hold everything you want hidden in the accordion:

- component: f7-list
  config:
    accordionList: true
  slots:
    default:
      - component: f7-list-item
        config:
          title: List Item
          accordionItem: true
        slots:
          default:
            - component: f7-accordion-content
              slots:
                default:
                  - component: Label
                    config:
                      text: Stuff in the accordion

Thank you very much, I wouldn’t realize it myself. That worked.