JustinG
(JustinG)
February 13, 2021, 4:24am
1
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.
ysc
(Yannick Schaus)
February 13, 2021, 10:48am
2
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.
<slot name="after" v-slot:after> </slot> <slot name="content" v-slot:content> </slot> <slot name="root-end" v-slot:root-end> </slot> <slot name="footer" v-slot:footer> </slot> <generic-widget-component slot="after" v-if="context.component.slots && context.component.slots.after && context.component.slots.after.length" :context="childContext(context.component.slots.after[0])" v-on="$listeners" /> <f7-accordion-content v-if="context.parent.component.config.accordionList && !context.editmode"> <generic-widget-component v-if="context.component.slots && context.component.slots.accordion && context.component.slots.accordion.length" :context="childContext(context.component.slots.accordion[0])" v-on="$listeners" /> <!-- <oh-placeholder-widget v-else-if="context.editmode" class="oh-column-item placeholder" @click="context.editmode.addWidget(context.component, null, context.parent, 'accordion')" /> --> </f7-accordion-content> <oh-icon slot="media" v-if="config.icon && config.icon.indexOf('oh:') === 0" :icon="config.icon.substring(3)" height="32" width="32" :state="(config.item && config.iconUseState) ? context.store[config.item].state : null" /> <f7-icon slot="media" v-else-if="config.icon" :ios="config.icon" :md="config.icon" :aurora="config.icon" :size="32" :color="config.iconColor" /> <span slot="media" v-else-if="config.fallbackIconToInitial && config.title && context.parent.component.config && context.parent.component.config.mediaList" class="item-initial">{{config.title[0].toUpperCase()}}</span> </f7-list-item> </template>
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
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
11194
(Вася Пупкин)
August 13, 2021, 10:18pm
4
@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')
JustinG
(JustinG)
August 14, 2021, 4:11am
5
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
11194
(Вася Пупкин)
August 14, 2021, 2:29pm
6
Thank you very much, I wouldn’t realize it myself. That worked.