JustinG
(JustinG)
September 3, 2022, 3:26pm
221
OK, here’s a pretty elegant solution to the wrapping menu. Using the map
property of the repeater instead of the filter
property we can reorder the array of menu options based on the button index. Then instead of the filter we use the flex version of the clean menu trick to keep things down to just what fits in the space. Here’s what it looks like in action:
Here’s the code:
uid: demo:looping_menu
props:
parameterGroups: []
parameters: []
tags: []
component: f7-row
config:
style:
display: flex
flex-direction: row
justify-content: space-between
align-items: center
flex-wrap: nowrap
width: 100%
height: 2em
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndex
actionVariableValue: =(vars.buttonIndex || 0) - 1
iconF7: chevron_left
style:
flex: 0 0 auto
- component: f7-row
config:
style:
display: flex
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
for: menuButton
in:
- Al's Room
- Betty's Room
- Charlie's Room
- Dining Room
- Elizabeth's Room
- Front Room
itemTags: bedroom
map: loop.menuButton_source[(((vars.buttonIndex || 0) % loop.menuButton_source.length) + loop.menuButton_source.length + loop.menuButton_idx) % loop.menuButton_source.length]
fragment: true
slots:
default:
- component: oh-button
config:
text: =loop.menuButton
style:
flex: 0 0 auto
order:
- component: oh-button
config:
action: variable
actionVariable: buttonIndex
actionVariableValue: =(vars.buttonIndex || 0) + 1
iconF7: chevron_right
style:
flex: 0 0 auto
This system has the advantage of being very responsive to the screen width with little extra work at this point as well as not running into the end of menu list issues. hmerk’s swiper version has the advantage of actually responding to scrolling (and swiping on a mobile screen).
2 Likes
hmerk
(Hans-Jörg Merk)
September 3, 2022, 4:04pm
222
Thanks @JustinG .
As I sm only trying to help with some logic issues, @Nic0205 and @Dimitris should finally decide how to move forward.
Segmented or swiper menu.
In the meantime, I will try to spend some time on displaying the cards in the middle part.
Already have something in mind ….
Dimitris
(Dimitris Baltas)
September 3, 2022, 7:44pm
224
The ball is in your hands now @Nic0205 . From a design/UX point of view, this is exactly what i had in my mind.
@JustinG @hmerk . I’m running out of thanks…
Nic0205
(Nic0205)
September 4, 2022, 6:25am
225
That looks like a really really great solution !!!
I will try to integrate this in the existing code this later / this evening. If this works we will go further with this approach.
Dimitris
(Dimitris Baltas)
September 4, 2022, 7:05am
226
@Nic0205 What i really like from the swiper approach, is the auto-configure navbar trick with tags. Don’t know if you can work with a hybrid solution: a wrapping auto configure menu?
Nic0205
(Nic0205)
September 4, 2022, 7:07am
227
@Dimitris : Perhaps I do not understand you right. Do you mean the “auto-populating” so that the Menu is automated generated by the items with tags?
Dimitris
(Dimitris Baltas)
September 4, 2022, 7:15am
228
@Nic0205 Yes Sir. Please forgive the designer for missing a dev brain!
hmerk
(Hans-Jörg Merk)
September 4, 2022, 7:43am
229
This is also possible with the segmented approach.
I am already working on the logic for automatically creating the list entrys, sow we only need fancy widgets, e.g. for the lights…
1 Like
Nic0205
(Nic0205)
September 4, 2022, 3:18pm
230
Hey @Dimitris
I tried it for the floors. Please have a look if it works in your setup. if so I will style it “Dimitri-Style”-conform
Please note - I implemented the logic just for the floors. Rooms and Home comes next…
uid: demo:responsive_navbar2_ext
tags: []
props:
parameterGroups: []
timestamp: Sep 4, 2022, 8:40:48 AM
component: f7-block
config:
style:
display: flex
flex-direction: column
height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-navbar-height) - var(--f7-safe-area-top))
justify-content: space-between
margin: 0
padding: 0
widht: 100vh
slots:
default:
- component: f7-block
config:
style:
flex: 0 0 auto
overflow: scroll
slots:
default:
- component: f7-segmented
config:
style:
flex: 1 1 auto
slots:
default:
- component: oh-repeater
config:
fragment: true
for: baseMenu
sourceType: array
in:
- name: Home
- name: Floors
- name: Rooms
map: loop.baseMenu.name
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: selectSection
actionVariableValue: ="SECTION" + loop.baseMenu_idx
large: true
style:
color: '=vars.selectSection=="SECTION" + loop.baseMenu_idx ? "black" : "#8C8C8C"'
font-size: 30px
font-weight: 200
text-decoration: underline
text-decoration-color: '=vars.selectSection=="SECTION" + loop.baseMenu_idx ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.baseMenu
- component: f7-row
config:
visible: =!!(vars.selectSection == "SECTION0")
style:
display: flex
flex-direction: row
justify-content: space-between
align-items: center
flex-wrap: nowrap
width: 100%
height: 2em
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexHome
actionVariableValue: =(vars.buttonIndexHome || 0) - 1
iconF7: chevron_left
style:
flex: 0 0 auto
color: "#F8BB00"
- component: f7-row
config:
style:
display: flex
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,uiSemantics
fragment: true
for: menuButtonHome
itemTags: Home
sourceType: itemsWithTags
map: loop.menuButtonHome_source[(((vars.buttonIndexHome || 0) % loop.menuButtonHome_source.length) + loop.menuButtonHome_source.length + loop.menuButtonHome_idx) % loop.menuButtonHome_source.length]
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuButtonHome.name
text: =loop.menuButtonHome.name
style:
flex: 0 0 auto
color: '=vars.floor ==loop.menuButtonHome.name ? "black" : "#8C8C8C"'
text-decoration: underline
text-decoration-color: '=vars.floor ==loop.menuButtonHome.name ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
order:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexHome
actionVariableValue: =(vars.buttonIndexHome || 0) + 1
iconF7: chevron_right
style:
flex: 0 0 auto
color: "#F8BB00"
- component: f7-row
config:
visible: =!!(vars.selectSection == "SECTION1")
style:
display: flex
flex-direction: row
justify-content: space-between
align-items: center
flex-wrap: nowrap
width: 100%
height: 2em
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexFloor
actionVariableValue: =(vars.buttonIndexFloor || 0) - 1
iconF7: chevron_left
style:
flex: 0 0 auto
color: "#F8BB00"
- component: f7-row
config:
style:
display: flex
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,uiSemantics
fragment: true
for: menuButtonFloor
itemTags: Floor
sourceType: itemsWithTags
map: loop.menuButtonFloor_source[(((vars.buttonIndexFloor || 0) % loop.menuButtonFloor_source.length) + loop.menuButtonFloor_source.length + loop.menuButtonFloor_idx) % loop.menuButtonFloor_source.length]
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuButtonFloor.name
text: =loop.menuButtonFloor.name
style:
flex: 0 0 auto
color: '=vars.floor ==loop.menuButtonFloor.name ? "black" : "#8C8C8C"'
text-decoration: underline
text-decoration-color: '=vars.floor ==loop.menuButtonFloor.name ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
order:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexFloor
actionVariableValue: =(vars.buttonIndexFloor || 0) + 1
iconF7: chevron_right
style:
flex: 0 0 auto
color: "#F8BB00"
- component: f7-row
config:
visible: =!!(vars.selectSection == "SECTION2")
style:
display: flex
flex-direction: row
justify-content: space-between
align-items: center
flex-wrap: nowrap
width: 100%
height: 2em
slots:
default:
- component: oh-button
visible: =!!(vars.selectSection == "SECTION2")
config:
action: variable
actionVariable: buttonIndexRoom
actionVariableValue: =(vars.buttonIndexRoom || 0) - 1
iconF7: chevron_left
style:
flex: 0 0 auto
color: "#F8BB00"
- component: f7-row
config:
style:
display: flex
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,uiSemantics
fragment: true
for: menuButtonRoom
itemTags: Room
sourceType: itemsWithTags
map: loop.menuButtonRoom_source[(((vars.buttonIndexRoom || 0) % loop.menuButtonRoom_source.length) + loop.menuButtonRoom_source.length + loop.menuButtonRoom_idx) % loop.menuButtonRoom_source.length]
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuButtonRoom.name
text: =loop.menuButtonRoom.name
style:
flex: 0 0 auto
color: '=vars.floor ==loop.menuButtonRoom.name ? "black" : "#8C8C8C"'
text-decoration: underline
text-decoration-color: '=vars.floor ==loop.menuButtonRoom.name ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
order:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexRoom
actionVariableValue: =(vars.buttonIndexRoom || 0) + 1
iconF7: chevron_right
style:
flex: 0 0 auto
color: "#F8BB00"
- component: f7-block
config:
style:
flex: 1 1 auto
overflow: scroll
slots:
default:
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION1DIV2Climate")
widgettrend: HeizungWohnzimmer_Temperature
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
widgettrend: HeizungWohnzimmer_Temperature
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
widgettrend: HeizungWohnzimmer_Temperature
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
widgettrend: HeizungWohnzimmer_Temperature
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
widgettrend: HeizungWohnzimmer_Temperature
- component: oh-cell
config:
icon: f7:lightbulb
style:
flex: 1 1 auto
overflow-y: auto
position: relative
subtitle: only for testing
title: I am a light card in the Bedroom
visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Lights")
- component: oh-cell
config:
icon: f7:lightbulb
style:
flex: 1 1 auto
overflow-y: auto
position: relative
subtitle: only for testing
title: I am a light card in the Home
visible: =!!(vars.selectSection == "SECTION1")
- component: Label
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
text: =vars.selectSection + vars.floor
- component: f7-block
config:
style:
flex: 0 0 auto
overflow: scroll
slots:
default:
- component: f7-segmented
config:
class:
- segmented-strong
style:
--f7-segmented-strong-between-buttons: 0px
--f7-segmented-strong-bg-color: transparent
--f7-segmented-strong-button-font-weight: 300
--f7-segmented-strong-button-hover-bg-color: rgba(255, 255, 255, 0.15)
--f7-segmented-strong-padding: 0px
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: selectThing
actionVariableValue: Lights
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.selectThing=="Lights" ? true : false'
icon-f7: lightbulb
iconColor: black
iconSize: 20
style:
--f7-button-bg-color: '=vars.selectThing=="Lights" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.selectThing=="Lights" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.selectThing=="Lights" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Lights
- component: oh-button
config:
action: variable
actionVariable: selectThing
actionVariableValue: Climate
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.selectThing=="Climate" ? true : false'
icon-f7: snow
iconColor: black
iconSize: 20
style:
--f7-button-bg-color: '=vars.selectThing=="Climate" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.selectThing=="Climate" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.selectThing=="Climate" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Climate
- component: oh-button
config:
action: variable
actionVariable: selectThing
actionVariableValue: Rollers
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.selectThing=="Rollers" ? true : false'
icon-f7: archivebox
iconColor: black
iconSize: 20
style:
--f7-button-bg-color: '=vars.selectThing=="Rollers" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.selectThing=="Rollers" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.selectThing=="Rollers" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Rollers
- component: oh-button
config:
action: variable
actionVariable: selectThing
actionVariableValue: Security
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.selectThing=="Security" ? true : false'
icon-f7: camera
iconColor: black
iconSize: 20
style:
--f7-button-bg-color: '=vars.selectThing=="Security" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.selectThing=="Security" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.selectThing=="Security" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Security
# config:
# visible: =!!(vars.selectSection == "SECTION1")
1 Like
Dimitris
(Dimitris Baltas)
September 4, 2022, 3:59pm
231
Yeap. It works for me -in a form of endless scrolling
Nic0205
(Nic0205)
September 4, 2022, 6:23pm
232
That sound pretty cool. I am curious to see your logic.
It’s great to see how this project grows
@Dimitris - I update the code above with your Design and now for all the categories (home, floors, rooms).
1 Like
Nic0205
(Nic0205)
September 4, 2022, 6:59pm
233
@JustinG I combined your code with the rest of our project - works like a charm .
And as usual: Another question…
Is it possible to set two variables at the same time within the actionVariable part of the oh-button?
hmerk
(Hans-Jörg Merk)
September 4, 2022, 7:31pm
234
No, that‘s not possible.
cc @Dimitris
I have a question regarding the page content.
Should the room selection show all equipment in a room ? And pressing the Lights button filters the result to only show the lights? Or should it show all lights in the house ignoring the room selection?
Same for other equipments.
JustinG
(JustinG)
September 4, 2022, 7:40pm
235
It’s not possible to set two different variables, but you can set a variable to an object with as many different keys as you’d like:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
animalHeight: 16 ft.
animalName: Giraffe
text: Object button
Then you can access the different keys just as you would any other object. For example: vars.objVar.animalName
Nic0205
(Nic0205)
September 4, 2022, 7:45pm
236
I am not Dimitris and not as good in UX as him but I would prefer that the room selection shows the content of the room (perhaps grouped by type) and when pressing lights then only the lights are shown.
For future perhaps we can create something like a favorite collection for the rooms-overview page. but one thin after the next…
Nic0205
(Nic0205)
September 4, 2022, 7:45pm
237
That’s pretty cool and could help much! Thank you!
hmerk
(Hans-Jörg Merk)
September 4, 2022, 7:51pm
238
Indeed, very helpfull, did not know that.
@Nic0205 We should move all actionVariableValues into an object, could make the content filtering easier.
BTW, would be good if you can publish your latest code on github.
Nic0205
(Nic0205)
September 4, 2022, 7:59pm
239
That’s exactly what I had in mind. But will be still a hard way to get all work - but it’s fun to see it grow… and to see oneself learning so much…
Just published the actual state of the code on GitHub:
1 Like
Dimitris
(Dimitris Baltas)
September 4, 2022, 8:06pm
240
Hmmm. That was a really good question: Tabs is same for floors and rooms. So, if you are in a floor or a room, filters in the same way.
I understand, what if you want to filter grouped equipment ie lights in all floors (ie house)? Yes, there is a design gap here… Let me think (i have not design yet the Tabs for Home menu …)