Take a look at:
Justin was as usual very helpful.
Maybe you can add your use case to the Git Issue to try get some traction?
From what I have seen the variable is not really set, just a default value used till it is set.
Take a look at:
Justin was as usual very helpful.
Maybe you can add your use case to the Git Issue to try get some traction?
From what I have seen the variable is not really set, just a default value used till it is set.
Nothing is set. The OR statement simply chooses the variable value if it exists, and if not, it chooses the secondary value you provide. There is no way to set a variable that is not one of the widget variable actions.
Nope. Assignment statements are just not supported by the expression parser.
That’s why I said you will have to make your expressions a little more complicated. You simply have to replace every instance of “vars.buttonIndex” with (vars.buttonIndex || 0)
. There are other expressions that will achieve the same thing, but this is the cleanest.
cc @Dimitris
Hi guys, I played a bit with the f7-swiper in combination with the oh-repeater and found a more dynamic solution, as I think.
Only prerequisit is to set a tag “Floor” to the floor group items and a tag with the floor group name to the rooms accordingly.
here is the code snippet:
uid: widget_DynamicNavbar
tags: []
props:
parameters:
- description: Dynamic NavBar V0.1
required: false
parameterGroups: []
timestamp: Sep 1, 2022, 3:43:39 PM
component: f7-card
config:
expandable: false
swipeToClose: true
style:
--f7-theme-color: var(--f7-text-color)
background-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
slots:
default:
- component: f7-card-content
slots:
default:
- component: f7-block
slots:
default:
- component: f7-swiper
config:
init: true
class:
- padding-top
- padding-bottom
params:
initialSlide: 0
observer: true
observeSlideChildren: true
updateOnWindowResize: true
mousewheel: true
keyboard: true
slidesPerView: 3
style:
--swiper-navigation-size: 20px
--swiper-navigation-color: gray
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,uiSemantics
for: i
fragment: true
itemTags: Floor
sourceType: itemsWithTags
slots:
default:
- component: f7-swiper-slide
slots:
default:
- component: oh-button
config:
text: =loop.i.label
action: variable
actionVariable: floor
actionVariableValue: =loop.i.name
style:
--f7-button-bg-color: orange
--f7-button-hover-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
--f7-button-pressed-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
- component: f7-block
slots:
default:
- component: f7-swiper
config:
init: true
class:
- padding-top
- padding-bottom
params:
initialSlide: 0
observer: true
observeSlideChildren: true
updateOnWindowResize: true
mousewheel: true
keyboard: true
slidesPerView: 3
style:
--swiper-navigation-size: 20px
--swiper-navigation-color: gray
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics, uiSemantics
for: i
fragment: true
itemTags: =vars.floor
sourceType: itemsWithTags
slots:
default:
- component: f7-swiper-slide
slots:
default:
- component: oh-button
config:
text: =loop.i.label
style:
--f7-button-bg-color: orange
--f7-button-hover-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
--f7-button-pressed-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
I have not added styles for selected buttons or any other fancy stuff, just wanted to show a poc…
Edit : If you want to have shorte Names for the buttons, you can use additional metadata (uiSemantics) and add a shortname…
I hope that, in addition to having this published to the Marketplace, that some effort is being made to capture what has been learned in this thread to build a tutorial, augment the official docs, etc. There is a lot of great effort and new ground being broken here and I’d hate for it to remain hard to find.
@hmerk Merci Monsieur! Hope that @Nic0205 will find some time to investigate deeper.
I have strong inerest only for
Fancy stuff and me =
Thank you!
If I find some time, I will try to combine @Nic0205 s last approach with mine…
Dear @rlkoshak ,
What we do obviously belongs to the community. I’m sure that @Nic0205 agree on that.
From my side, the final design with the graphical description of all the functions will be published here in the form of a manual: Many of them have already been posted and I’ll continue to post all their updates. Nic does the same with coding.
But I think that even as a plan or development we are looking for our steps and it is still early to “officially” post the project…
The structure we follow consists of two areas:
1. Navigation
NavBar (Header)
Tabs (footer)
2. Widgets
a. Lights
On-off Light
+Brightness
+Ambience
+Color
Mayby 4 Widgets: Will be under investigation if we can create a “smart” that will cover all cases:
b. Rollers
+Venetian Blinds
c. HVAC
d. Security
e. Weather
f. Scenes
On the design side, I dare say we are very close to the first version in both areas.
When Nic is finished, and if he agrees, I commit to create a combined guide (Programming + Design) and post it in the format you indicate.
I want to say here that the important thing is the work that Nic is doing -with the tremendous help and guidance of @JustinG @hmerk - and not mine, without wanting to downplay the design part.
Thank you for your post!
@JustinG
Hmm. I tried it - but with this:
filter: (loop.HomeMenu_idx >= (vars.buttonIndex || 0)) && (loop.HomeMenu_idx <= (vars.buttonIndex || 0)+2 ) )
in my above posted code the filter does not work.
I thought with the filter like I described I would limit the HomeMenu to 3 (0,1,2) but all HomeMenu-Entries are shown.
if I replace it with a fix number:
filter: (loop.HomeMenu_idx >= (vars.buttonIndex || 0)) && (loop.HomeMenu_idx <= 2 )
It filters correct. But not with the variable…
Very cool - it would be great to see things coming together!
cc @rlkoshak
I totally agree with Dimitris!
As a noob in all these things I know now how hard it is to start - of course we and I will share the experience. I think we are part of the community !
Already working on it
As promised, I tried to combine both approches to get it more dynamic.
Prerequisits:
My model is based on a floor/room/equipment structure. All floors groups (gAttic, gGroundFloor, gFirstFloor and gBasement) have a tag "Floor. Rooms within the floor (gAttic has Office (gOffice) and Guestroom (gGuest), have a tag with the floor groop (Office has tag gAttic).
Therefore, I removed the array configuration and hardcoded the top level menu array to Home, Floors and Rooms.
Here is the result:
uid: demo:responsive_navbar1
tags: []
props:
parameterGroups: []
timestamp: Sep 2, 2022, 11:05:52 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-segmented
config:
visible: =!!(vars.selectSection == "SECTION0")
slots:
default:
- component: oh-button
config:
text: <
style:
width: 1vh
color: "#F8BB00"
- component: oh-repeater
config:
fragment: true
for: HomeMenu
sourceType: array
in: =props.hArray
filter: (loop.HomeMenu_idx >= 0) && (loop.HomeMenu_idx <= (0 +5))
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: selectDivision
actionVariableValue: ="DIV" + loop.HomeMenu_idx
large: true
style:
color: '=vars.selectDivision=="DIV" + loop.HomeMenu_idx ? "black" : "#8C8C8C"'
text-decoration: underline
text-decoration-color: '=vars.selectDivision=="DIV" + loop.HomeMenu_idx ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.HomeMenu
- component: oh-button
config:
text: ">"
style:
width: 1vh
color: "#F8BB00"
- component: f7-segmented
config:
visible: =!!(vars.selectSection == "SECTION1")
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,uiSemantics
fragment: true
for: FloorMenu
itemTags: Floor
sourceType: itemsWithTags
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.FloorMenu.name
large: true
style:
color: '=vars.floor ==loop.FloorMenu.name ? "black" : "#8C8C8C"'
text-decoration: underline
text-decoration-color: '=vars.floor ==loop.FloorMenu.name ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.FloorMenu.label
- component: f7-segmented
config:
visible: =!!(vars.selectSection == "SECTION2")
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics, uiSemantics
fragment: true
for: RoomMenu
itemTags: =vars.floor
sourceType: itemsWithTags
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: selectDivision
actionVariableValue: ="DIV" + loop.RoomMenu_idx
large: true
style:
color: '=vars.selectDivision=="DIV" + loop.RoomMenu_idx ? "black" : "#8C8C8C"'
text-decoration: underline
text-decoration-color: '=vars.selectDivision=="DIV" + loop.RoomMenu_idx ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.RoomMenu.label
- component: f7-block
config:
style:
flex: 1 1 auto
overflow: scroll
slots:
default:
- component: f7-card
config:
content: With some stuff
title: The middle content
- 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: 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.selectDivision
- component: Label
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
text: =vars.SecDiv
- 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
Wow. This is on a other level. Congrats to Nic to have achieved this challenge.
Great help also from other guys involved in this!
Wow - looks cool and makes the code much “cleaner”.
But to be sure - the posted code is without the swiper approach.
@All: Should we integrate the swiper or go further with this great state after solving the “variable Index” challenge?
@Hmerk: I agree with Ruben! That’s really the next level!
No, I did not clean that much in the code, just a few lines. But removed the array configs.
No, still the segmented approach. But we can try this with the swiper approach as well. Benefit would be that it could handle long names better, as I was wrong, uiSemantics can not be set on group items, so no easy way to get short names lige EG, FF, SF and so on…
Thanks, glad I can help
on my device (iphone x) when i click floors or rooms, sub menu is not shown.
for floors i only have “scale” sub menu.
i think this is normal in this version, but i would like just to report in case is not known …
Did you add the tags as decribed to your floor / room groups ? If not, the code does not work…
yes, but sure i’m missing something.
Taverna (gTaverna) is member of gCasa.
Taverna is set as Floor as Semantic Class.
Taverna is shown as Floor in widget.
Taverna has 2 memebers: Bagno Taverna (gBagnoTaverna) and Tunnel Taverna (gTunnelTaverna).
Both defined as Room as Semantic Class.
Both not shown in widget.
what’s missing?
You need to add a tag “gTaverna” to Bagno Taverna and Tunnel Taverna.