Building Pages in the OH3 UI: documentation draft (2/3)

Hi all,
i am testing OH3 widget creation, and i try to make a widget that i have in habpanel into the new ui.

My quetion is, how to use icons i have made and placed in /etc/openhab/icons/classic/

I try ther following syntax :

- component: oh-button
              config:
                raised: true
                large: true
            - component: oh-image
              config:
                url: "='/static/a1.png'"
                style:
                  position: absolute
                  height: 100%
                  bottom: -90%

Regards
Ronny

You’re trying to display an image inside the oh-button component I suppose. oh-button (and the f7-component it’s based on) doesn’t support slots - so this will not work.

Generally the oh-button component only supports icons from the f7- and the material-iconset, which I attached an example below.

For explanation to the oh-image component you’re trying to use - the ‘/static/’ path corresponds with the ‘/etc/openhab/html/’ folder of your installation. And you don’t need the equal sign in that case, because you’re not accessing a prop, item or variable. So this would work, if you place an image in the above mentioned path:

- component: oh-image
  config:
    url: "/static/a1.png"

To reach your initial goal, you have to use a small workaround. (see the third button example in the code below) Be aware that there is a slight distinction with this workaround in the ‘hover’ and ‘pressed’-state of the button.

You also can leave your icon inside the ‘/etc/openhab/icons/classic/’ folder then, as ‘oh-icon’ is looking for icons there and in the integrated OH-iconset.

button_example

- component: oh-button
  config:
    action: popup
    actionModal: widget:YOURWIDGET
    class:
      - margin-right
    text: F7-icon
    icon-f7: plus_circle
    iconSize: 25
    iconColor: white
    raised: true
    large: true
    fill: true

- component: oh-button
  config:
    action: popup
    actionModal: widget:YOURWIDGET
    class:
      - margin-right
    text: Material-icon
    icon-material: add_circle
    iconSize: 25
    iconColor: white
    raised: true
    large: true
    fill: true

- component: f7-row
  config:
    class:
      - button
      - button-fill
      - button-large
      - button-raised
      - align-items-center
  slots:
    default:
      - component: oh-button
        config:
          action: popup
          actionModal: widget:YOURWIDGET
          style:
            --f7-button-bg-color: transparent
            --f7-button-hover-bg-color: rgba(var(--f7-theme-color-rgb), .07)
            --f7-button-pressed-bg-color: rgba(0,0,0,.15)
            position: absolute
            top: 0
            left: 0
            height: 100%
            width: 100%
      - component: oh-icon
        config:
          icon: a1
          style:
            height: 25px
      - component: Label
        config:
          text: OH-icon

Hope it helps!

4 Likes

Hi

Thanks for your example.
It explains how certain syntaxes should be used.

I Stil have problems with the syntaxes

I started from the keypad widget and try to adapt it to created a ir remote control keypad (habpanel widget)

uid: irLed_1c08a67036
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: Nov 12, 2020, 9:19:25 AM
    component: f7-block
    config:
    title: Sended IR code
    style:
    outline-border-color: rgba(50, 150, 110, 1)
    outline: 2px
    background-color: rgba (60,100,120,1)
    position: relative
    -ms-user-select: None
    -moz-user-select: None
    -webkit-user-select: None
    user-select: None
    –f7-button-text-color: var(–f7-text-color)
    –f7-button-bg-color: var(–f7-card-bg-color)
    –f7-theme-color-rgb: var(–f7-color-blue-rgb)
    class:
  • padding
    slots:
    default:
  • component: oh-label-card
    config:
    title: Sended IR code
    style:
    border-radius: 10px
    background-color: rgba(80, 150, 50, 1)
    outline-border-color: rgba(50, 150, 110, 1)
    outline: true
    class:
    - margin-bottom
    content: =items[props.item].displayState || items[props.item].state
  • component: f7-row
    config:
    style:
    background-color: rgba(80, 150, 50, 1)
    class:
    - margin
    slots:
    default:
    - component: f7-col
    slots:
    default:
    - component: oh-button
    config:
    text: “2”
    raised: true
    large: true
    action: variable
    actionVariable: pincode
    actionVariableValue: ‘=(vars.pincode) ? vars.pincode + “2” : “2”’
    - component: oh-icon
    config:
    icon: a1
    style:
    height: 25px
    - component: Label
    config:
    text: OH-icon

Apparently I haven’t quite mastered the syntax to get the layout right.

Have read all the examples, but apparently there are more possibilities to influence the display.

I have tried your example, but I am still not getting the display aligned properly (see my screenshot).

The new mainui is great, many thanks for this and also for the good article how to create widgets. This was a good starting point.

Does anyone know if it is possible to use javascript or angularjs to dynamically build e.g. f7-rows. I used this on habpanel to extract parts of a json string for my heating control.

Hey again Ronny,

first of all it would be very helpfull if you use code-fences to make your code readable. I also think, that it wouldn’t help you if anybody here present you a ready-2-go soloution, so I´ll try it with some general tips, that helped me…

  1. Read Part 1 and Part 2 of this writeup again and try to understand the general mechanic of slots and components.

  2. Have a look in the f7-vue-documentation to see what components the framework offers (even if not all of them interacting with OH currently). The global f7-docs could also be helpfull (for things like css classes etc.)

  3. Start small. Instead of modifying already existing (complex) code examples, try to set yourself small goals as a starting point (maybe bringing 4 customs buttons in one row) and work up from there.

To at least briefly address your current problem (as far as it´s possible in that code mess :stuck_out_tongue:). It seems you are wrapping all the columns (in which the 1 - 4 buttons are) inside the row from my button-example.

The f7-row in the example acts just as a horizontal wrapper for the contents of the “fake-button” so it replaces a button in the keypad example, not a whole row. The component order here should be then:

f7-row
  f7-col
    f7-row (#1)
      oh-button
        ...
    f7-row (#2)
      oh-button
        ...
    ...

Hey @buschif4

Pure javascript can’t be used AFAIK. There are just some ‘javascript-like’ functions that you can use at the moment as @ysc mentioned here. But these are too limited for your use-case, I think.

I tried to do a similar thing with a dynamic created button-list and ended creating a bunch of placeholder components (which of course could be f7-rows) and triggered their visibility with expressions.

What also might work for you (even if its not customizable and limited to the use in a modal overlay) is adding an ‘action: group’, which creates a list item component for each group member. (see this discussion)

Hi Rainer,

Thanks for the assistance and tips

I tried to use code-fence, but my cromium browser is having a hard time with it.

  1. I’ve read it several times, but I can’t get a clear view of it yet. (but i also find this with other programming languages :slight_smile: and is a more common problem with the current manuals, they explain all the features, but not how to use them. )
  2. it is not always clear how to use this in yaml, the different examples show different possibilities.
  3. I’m working on that.

Regards,
Ronny

1 Like

@RGroll thanks for the information. I will use placeholders for now :frowning:

Do you know how i can reset certain variables at the same time? So i have 3 vars and want to reser all 3 with a single button. Is this possible?

@buschif4 Seems like we all think alike - asked the same here and fortunately you could use an array for that:

clearVariable: [var1, var2]
1 Like

The most important point is to keep learning and it seems, you are willed to do so. The successes come at some point for sure - and is even sweeter then. :slight_smile: :lollipop:

@RGroll thanks again for your help.
Do you know if I can set/get a variable with a f7-component? I was not able to find some documentation for this. And from my testing it seams that I can only access this from the oh-components.

As far as I understand the underlying architecture, f7-components does not support any of the OH-specific configurations, like variables or actions. Expressions instead does work on the most of the f7-components AFAIK.

In the most cases (at least from the things that I’ve tried) there is a workaround for that: so you can use f7-components for styling things and using OH-components for the inside (including variables and actions then, of course)

I’m sure @ysc is aware of that and as I understand, he would like to implement small oh-components too, which would be very usefull for widget-creators.

But don’t hesitate to contact me, if you have any questions for a specific use-case.

This makes thinks even more complicated :frowning:

Maybe you know a solution. I want to build an popover inside a card to make a dropdown selection. the problem is that I’m not able to close the popover again when I use a oh-component. When i use a f7-component I could just use the config parameter “popoverClose: .mypopover” to close the popover again.

See my example here which sets the var but can not close the popover on action time:

uid: widget_562ed42888
tags: []
props: []
timestamp: Nov 14, 2020, 12:17:34 PM
component: f7-card
config:
slots:
  default:
    - component: f7-button
      config:
        popoverOpen: .mypopover
        text: "click me"
      slots:
        default:
          - component: f7-popover
            config:
              class: mypopover
            slots:
              default:
                - component: oh-label-card
                  config:
                    action: variable
                    actionVariable: myVar
                    actionVariableValue: "test"
                    label: "I should close this popup and set a variable"

@buschif4 Interesting question - you can use a class for this:

btw. thanks for the hint with that component - haven’t used it yet and have some usecases in mind already. :stuck_out_tongue:

uid: widget_562ed42888
tags: []
props: []
component: f7-card
slots:
  default:
    - component: f7-button
      config:
        popoverOpen: .mypopover
        text: click me
      slots:
        default:
          - component: f7-popover
            config:
              class: mypopover
            slots:
              default:
                - component: oh-label-card
                  config:
                    class:
                      - popover-close
                    action: variable
                    actionVariable: myVar
                    clearVariable: true
                    actionVariableValue: success
                    label: I should close this popup and set a variable
                    
    - component: Label
      config:
        class:
          - padding
        text: =vars.myVar
1 Like

@RGroll cool that works. I had to place the label cards in f7-cards because the class object was not properly working when reopening the popover and choosing another item. But now it works. My heating control ist almost working.

Do you know if i can detect if the style is normal or dark mode? I need to change the colors on darkmode because the card shadow effect is not visible

Can we somehow use date time calculations in expressions?
i want to create a widget which only shows the ‘elapsed’ time since, say, the date-time state captured in an item. Eg.,
item “WANIP_Changed” gives the time stamp of last change. then, when i load the UI page containing the widget, it should show me the elapsed time since the change, like “3 hours and 10 minutes ago”. Note, i just want to see this with page load or in auto-refresh, i.e, without actually pressing the widget for action.
Any ideas?

That would be themeOptions.dark === 'dark', by the way the recent snapshots have a new “developer sidebar” where you can conveniently test your expressions:

That’s the sort of things I want to add, but not yet.

4 Likes

Oh okay - didn’t tested it with multiple elements but good to know.

Nice - a lot of people (including me) would be gratefull if you’d post this as an example in the UI category when you’re ready.

All other questions are already answered by @ysc. :slight_smile:

1 Like

About that, also keep in mind that framework7 defines a lot of CSS variables, whose value will vary depending on the theme/dark mode: margins, shadows, but mostly colors. So if you want to reuse them it’s possible in your component style like:

style:
  backgroundColor: var(--f7-page-bg-color)
  color: var(--f7-theme-color-text-color)

etc.

1 Like

How should I defined the drop down values for oh-input-card with type: select
f7-input documentation indicates using <option value="...">...</option>. What should be the equivalent here?