@Nic0205 You already have the image!
Option a: classic text menu under Home OR
Option b. Tab bar
Let me check tonight, might have a longer coding session after kid is gone to bed…
Ah dismissed the picture. I vote for tabbar!
For me it’s the same. ‘Cause the actual mode for me it’s not so user friendly,i vote for no bottom menu, because i’m curious of how will be new mode of navigating
The stylesheet
property is not processed by the expression parser, so things like props.textColor
won’t be replaced with values, they’re just sent to the css as is, and css has no idea what props.textColor
means. If you want to have values in the stylesheet
that are dynamic you have to do what I demonstrated with the text color for the unselected options. You have to define a css variable in the style
object, which is processed by the expression parser:
style:
display: flex
flex-direction: column
height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-safe-area-top))
justify-content: space-between
margin: 0px
padding: 0px
--opmw-menu-text-color: '=(themeOptions.dark=="light")?("#8C8C8C"):("#848484")'
And then in the stylesheet
you can refer to the value of that variable:
.unselected_menu_item {
color: var(--opmw-menu-text-color);
}
You’re never really going to manage a rules creation/editing page just through custom widgets. It is technically feasible, but the complexity required would many orders of magnitude higher than what you’re doing right now and would only replicate what is already available through the rules page. Really there are only two sensible options for incorporating some sort of “rules” section:
- just have that button take the user to the MainUI rules page
- Allow a configuration where the user adds switch items to the conditions of certain rules and tags those items a certain way. Then your “rules” page could be a list of those toggle switches allowing the user easy access to enabling or disabling the activity of those particular rules.
I was just thinking that would be nice if you can enable/ disable rules (and not editing or creating new one!!s). And yes, a link to OH rules page seems a very good idea.
@Nic0205 @hmerk @rubenfuser So, our milestone is this:
Home menu: sub menu would be only the tab bar on footer
Floors menu: Sub menu on header and tab bar for filtering
Room menu: Sub menu on header and tab bar for filtering
Befor @hmerk and @Nic0205 starts firing up, ithat would be graet if I have your approval.
To be honest I’m quite understand what you mean…
Absolutely not, as you need admin rights for that!
Ahh - I see. thank you works like a charm now - but only after pressing one of the menu buttons once.
Until pressing a button the color is red / dark orange. It seems that the stylesheet takes effect after clicking/ performing the action and not direct after loading the widget…
I cannot see where this red is defined in the code - could you have a quick review on it?
EDIT: The color is “#E64A19” and this is the css variable var(--f7-button-text-color,var(--f7-theme-color))
EDIT2: tried it this way and it works (code is updated):
--f7-button-text-color: "#8c8c8c"
But don’t know if this is a good idea…
How could I define not to use this but the css defined in the widget…?
uid: main_widget
tags: []
props:
parameters:
- default: black
description: Set default color for Text
label: Text color
name: textColor
required: false
type: TEXT
- default: RGB(96, 96, 96)
description: Set default color for Text
label: Bottom-Navbar-Color
name: bnavColor
required: false
type: TEXT
- default: Somewhere
description: Name for your weather location
label: Weather Location
name: locationTitle
required: false
type: TEXT
- context: item
description: Name of scenes group item
label: Scenes Group
name: scenesGroup
required: false
type: TEXT
- context: item
description: Name of security group item
label: Security Group
name: securityGroup
required: false
type: TEXT
- context: item
description: Security Mode Item
label: Security Mode
name: securityMode
required: true
type: TEXT
parameterGroups: []
timestamp: Sep 24, 2022, 6:59:04 PM
component: f7-block
config:
style:
display: flex
flex-direction: column
height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-safe-area-top))
justify-content: space-between
margin: 0
padding: 0
widht: 100vh
--menu-text-color: =props.textColor
--f7-button-text-color: "#8c8c8c"
stylesheet: >
.selected_menu_item {
color: var(--menu-text-color);
font-weight: bold;
text-decoration-color: #F8BB00 !important;
text-decoration: underline;
text-underline-offset: 2.px;
}
.unselected_menu_item {
color: #8C8C8C;
} .chevron {
color: #F8BB00;
}
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:
for: baseMenu
fragment: true
in:
- name: Home
- name: Floors
- name: Rooms
map: loop.baseMenu.name
sourceType: array
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: ="SECTION" + loop.baseMenu_idx
class: '=(vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx) ? "selected_menu_item" : "unselected_menu_item"'
style:
font-size: 28px
font-weight: 200
text: =loop.baseMenu
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: space-between
width: 100%
visible: false
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexHome
actionVariableValue: =(vars.buttonIndexHome || 0) - 1
iconF7: chevron_left
class: chevron
style:
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
fetchMetadata: widgetOrder
for: menuArray
fragment: true
itemTags: Floor
map: loop.menuArray_source
sourceType: itemsWithTags
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
filter: loop.menuArray_idx == 0
for: menuButtonHome
fragment: true
in: =loop.menuArray
map: ((loop.menuButtonHome.metadata && loop.menuButtonHome.metadata.widgetOrder && loop.menuButtonHome.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonHome_idx
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].name
style:
flex: 0 0 auto
height: 2em
order: =(((vars.buttonIndexHome || 0) % loop.menuButtonHome_source.length) + loop.menuButtonHome_source.length + loop.menuButtonHome_idx) % loop.menuButtonHome_source.length
text: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].label
- component: oh-button
config:
action: variable
actionVariable: buttonIndexHome
actionVariableValue: =(vars.buttonIndexHome || 0) + 1
iconF7: chevron_right
class: chevron
style:
flex: 0 0 auto
height: 2em
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: center
width: 100%
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION1") ? true : false : false'
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexFloor
actionVariableValue: =(vars.buttonIndexFloor || 0) - 1
iconF7: chevron_left
class: chevron
style:
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
fetchMetadata: widgetOrder
for: menuArray
fragment: true
itemTags: Floor
map: loop.menuArray_source
sourceType: itemsWithTags
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
filter: loop.menuArray_idx == 0
for: menuButtonFloor
fragment: true
in: =loop.menuArray
map: ((loop.menuButtonFloor.metadata && loop.menuButtonFloor.metadata.widgetOrder && loop.menuButtonFloor.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonFloor_idx
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].name
style:
color: '=vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name) ? textColor : "#8C8C8C"'
flex: 0 0 auto
height: 2em
order: =(((vars.buttonIndexFloor || 0) % loop.menuButtonFloor_source.length) + loop.menuButtonFloor_source.length + loop.menuButtonFloor_idx) % loop.menuButtonFloor_source.length
text-decoration: underline
text-decoration-color: '=vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name) ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].label
- component: oh-button
config:
action: variable
actionVariable: buttonIndexFloor
actionVariableValue: =(vars.buttonIndexFloor || 0) + 1
iconF7: chevron_right
class: chevron
style:
flex: 0 0 auto
height: 2em
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: center
width: 100%
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION2") ? true : false : false'
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexRoom
actionVariableValue: =(vars.buttonIndexRoom || 0) - 1
iconF7: chevron_left
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
fetchMetadata: widgetOrder
for: menuArrayRoom
fragment: true
itemTags: =vars.floor
map: loop.menuArrayRoom_source
sourceType: itemsWithTags
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
filter: loop.menuArrayRoom_idx == 0
for: menuButtonRoom
fragment: true
in: =loop.menuArrayRoom
map: ((loop.menuButtonRoom.metadata && loop.menuButtonRoom.metadata.widgetOrder && loop.menuButtonRoom.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonRoom_idx
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: room
actionVariableValue: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].name
style:
color: '=vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name) ? textColor : "#8C8C8C"'
flex: 0 0 auto
height: 2em
order: =(((vars.buttonIndexRoom || 0) % loop.menuButtonRoom_source.length) + loop.menuButtonRoom_source.length + loop.menuButtonRoom_idx) % loop.menuButtonRoom_source.length
text-decoration: underline
text-decoration-color: '=vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name) ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].label
- component: oh-button
config:
action: variable
actionVariable: buttonIndexRoom
actionVariableValue: =(vars.buttonIndexRoom || 0) + 1
iconF7: chevron_right
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: f7-block
config:
style:
flex: 1 1 auto
margin-bottom: -1em
margin-top: -1em
overflow: scroll
slots:
default:
- component: widget:main_widget_Weather_Card
config:
bigCard: true
dateFormat: true
itemPrefix: OneCallAPIweatherandforecast_
locationTitle: =props.locationTitle
sunIndicator: true
visible: '=(!vars.objVar || ((vars.objVar.selectSection=="SECTION0") && !vars.objVar.selectThing)) ? true : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
for: sceneItem
groupItem: =props.scenesGroup
sourceType: itemsInGroup
slots:
default:
- component: widget:main_widget_Scene_Card
config:
scene: =loop.sceneItem.name
sceneName: =loop.sceneItem.label
visible: '=vars.objVar ? ((vars.objVar.selectSection + vars.objVar.selectThing)=="SECTION0Scenes") ? true : false : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: loop.equipmentItem.metadata.semantics.config.hasLocation == vars.room
for: equipmentItem
itemTags: Blinds
sourceType: itemsWithTags
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: '(loop.shutterItem.type=="Rollershutter") ? true : false'
for: shutterItem
groupItem: =loop.equipmentItem.name
sourceType: itemsInGroup
slots:
default:
- component: widget:main_widget_Rollershutter_Card
config:
RollerItem: =loop.shutterItem.name
visible: '=vars.objVar.selectThing=="Rollers" ? true : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: loop.equipmentItem.metadata.semantics.config.hasLocation == vars.room
for: equipmentItem
itemTags: Lightbulb
sourceType: itemsWithTags
slots:
default:
- component: widget:main_widget_Light_Card
config:
equipmentItem: =loop.equipmentItem.name
visible: '=vars.objVar.selectThing=="Lights" ? true : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: loop.equipmentItem.metadata.semantics.config.hasLocation == vars.room
for: equipmentItem
itemTags: RadiatorControl
sourceType: itemsWithTags
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
for: tempItem
groupItem: =loop.equipmentItem.name
sourceType: itemsInGroup
slots:
default:
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: '=vars.objVar.selectThing=="Climate" ? true : false'
widgettrend: =loop.tempItem.name
- component: widget:main_widget_Security_Card
config:
securityGroup: =props.securityGroup
securityMode: =props.securityMode
visible: '=vars.objVar ? ((vars.objVar.selectSection + vars.objVar.selectThing)=="SECTION0Security") ? true : false : false'
- component: Label
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
text: =vars.objVar.selectSection + vars.floor
visible: "=vars.objVar ? true : false"
- component: f7-block
config:
style:
flex: 0 0 auto
margin-bottom: -2em
overflow: scroll
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? true : false : false'
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: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Security
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Security" ? true : false'
icon-f7: shield_fill
iconColor: green
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="Security" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Security" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Security" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Security
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Scenes
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Scenes" ? true : false'
icon-f7: rectangle_on_rectangle_angled
iconColor: textColor
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="Scenes" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Scenes" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Scenes" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Scenes
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Weather
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Weather" ? true : false'
icon-f7: cloud
iconColor: textColor
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="Weather" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Weather" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Weather" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Weather
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: HVAC
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="HVAC" ? true : false'
icon-f7: flame
iconColor: textColor
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="HVAC" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="HVAC" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="HVAC" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: HVAC
- component: f7-block
config:
style:
background: =props.bnavColor
border-radius: 0px 0px 10px 10px
flex: 0 0 auto
margin-bottom: -2em
overflow: scroll
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? false : true : false'
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: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Lights
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Lights" ? true : false'
icon-f7: lightbulb
iconColor: '=vars.objVar.selectThing=="Lights" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Lights" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Lights" ? "black" : "white"'
font-size: 12px
height: auto
text: Lights
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Climate
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Climate" ? true : false'
icon-f7: snow
iconColor: '=vars.objVar.selectThing=="Climate" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Climate" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Climate" ? "black" : "white"'
font-size: 12px
height: auto
text: Climate
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Rollers" ? true : false'
icon-f7: archivebox
iconColor: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Rollers" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
font-size: 12px
height: auto
text: Rollers
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Energy
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Energy" ? true : false'
icon-f7: bolt
iconColor: '=vars.objVar.selectThing=="Energy" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Energy" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Energy" ? "black" : "white"'
font-size: 12px
height: auto
text: Energy
looks good for me with one addition/question: Why not use an “All Room” for Rooms menu like for the Floors menu?
Cause I voted against „all“ option on both, floor and room.
That would be really complex, error prone and perhaps a really long list of information to show.
Approved with the exception of implementing „All“ menu entries.
it’s also fine for me. Let’s do it without “all” for both sections and if someone wants to add it in future he’s free to so.
I think we have to cut out a bit of complexity and therefore you are absolutely right with your vote!
This is what hmerk was referring to when he said that it has to do with whether vars.objVar
exists. Right now, before you press any button, vars.ObjVar
equals undefined
, so there’s no way that vars.objVar.selectSection
can equal "SECTION" + loop.baseMenu_idx
. If you want the expression to be responsive before you press a button then you have to account for the undefined state of vars.objVar
.
Usually this is most easily done with a simple OR statement because undefined
will be interpreted as a false value. Because we’re looking at the property of an object it’s usually best to test each level as we go. So if you have:
((var.objVar && vars.objVar.selectSection) || "Section0")
first the parser will look at var.objVar
if that doesn’t exist, then already the innner AND statement is false and the parser moves to the second part of the outer OR statement. "Section0"
is a non-zero non-false value (therefore it counts as true) so the OR statement returns that value. The same line of reasoning applies if vars.objVar
does exist but vars.objVar.selectSection
does not. However, if vars.objVar
does exist and vars.objVar.selectSection
also exists then the inner AND statement is true and the most recently evaluated value (in this case vars.objVar.selectSection
) is returned.
Ok, so i will try to bring all the latest changes/improvements together tonight and start with the information for the floors menu.
I understand what you mean and what you say - but not how to do it
I use this code:
class: '=((vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx) || "Section0") ? "selected_menu_item" : "unselected_menu_item"'
this should set it to “Section0” or am I wrong? Or do I use it completely wrong (did not understand how to check objvar)… Is class
at all the right place for this?
Hey @hmerk cause of all the progress I totally forgot this issue.
I created a non semantic group and assigned in a first step a light.
The non-semantic group is shown in the rooms but the lights does not appear. My config is:
Seems I missed something for the light - but what?
class
is the correct place, you are making a jump in reasoning that most computer languages don’t/can’t. While there are some cases where it is OK for a value to be undefined
or whatever the language equivalent is, trying to then do something more with that value is an immediate issue because it is “undefined” so the language has no context to work with. If I ask you what a “procklenard” is, you would say “there’s no such thing” which is fine answer. If I ask you “what do you get when you double a procklenard” your only possible answer is “I can’t even begin to tell you, because I don’t know what a procklenard is”.
If vars.objVar
doesn’t exist, the parser is happy to tell you that. But if you ask it what is the selectSection
property of something that doesn’t exist, it’s only possible answer is, “I can’t even begin to tell you, because I don’t know what vars.objVar
is”. In computer speak, “I can’t even begin to tell you…” is just error
.
This is what I meant by this line. If there’s ever a chance that an expression with vars.objVar
is going to be needed before vars.objVar
exists (which of course there is), then we can’t try to use that value for anything else (getting a property or it, or adding it to something else, for example) until we give the expression parser a way to fall-back to a sensible value. That’s what those &&
and ||
statements do.
The other piece to this that I didn’t explicitly describe is that the &&
and ||
statements do not just return true
or false
they return whatever the most recent value they evaluated is as soon as they know whether the logic is true or false. For example (2 == 3 || "orange")
first checks 2 == 3
, well, this is obviously false, but since the OR statement could still be true it has to check the second value. So it then evaluates "orange"
. Well, that is a value that exists, is not 0
and is not false
so as far as the parser is concerned that is true and the OR statement returns the last thing it evaluated: "orange"
.
So you want a statement that returns vars.objVar.selectSection
, but only if vars.objVar
and vars.objVar.selectSection
exist. One way to do that would be:
(vars.objVar && vars.objVar.selectSection)
but then you want the expression to return "Section0"
if any of that up above equals false:
((vars.objVar && vars.objVar.selectSection) || "Section0")
now you’re ready to test if the result of that actually equals “Section” plus whichever button you are on:
((vars.objVar && vars.objVar.selectSection) || "Section0") == "Section" + loop.baseMenu_idx
Finally you can use that test as the condition for the ternary statement that decides which class to give your button:
class: '=(((vars.objVar && vars.objVar.selectSection) || "Section0") == "Section" + loop.baseMenu_idx) ? "selected_menu_item" : "unselected_menu_item"'