Widget oh-repeater works in developer mode but not in page?

I have created a widget which will allow me to adjust my “profiles”. In the widget-development environment, everything works properly, and if I set the props, the widget behaves exactly as it should:

Here is the code that makes it work:

uid: profile_looper
tags:
  - list
props:
  parameters:
    - description: Title on top
      label: Title
      name: title
      required: false
      type: TEXT
    - context: item
      description: Profile
      label: profile core item
      name: profilecore
      required: true
      type: TEXT
      filterCriteria:
        - value: Group
          name: type
  parameterGroups: []
timestamp: Jul 31, 2022, 3:38:00 PM
component: f7-card
config:
  style:
    --f7-range-bar-active-bg-color: "#090909"
    --f7-range-bar-bg-color: "#111111"
    --f7-range-bar-border-radius: 1em
    --f7-range-bar-size: 0.6em
    height: 400px
    position: relative
  title: Profile Adjustment Widget
slots:
  default:
    - component: f7-block
      slots:
        default:
          - component: f7-row
            slots:
              default:
                - component: Label
                  config:
                    style:
                      font-size: 18pt
                      padding: 10px
                    text: =items[props.profilecore + "_Name"].state
                - component: oh-button
                  config:
                    action: popup
                    actionModal: widget:profile_looper_popup
                    actionModalConfig:
                      profile: =props.profilecore
                      title: =props.title
                    color: white
                    iconF7: gear_alt_fill
                    large: true
    - component: f7-block
      config:
        style:
          display: flex
          flex-direction: row
          height: 100%
          left: 30px
          position: aboslute
          top: 20px
          width: 95%
      slots:
        default:
          - component: oh-repeater
            config:
              filter: loop.item.type == "Number"
              for: item
              fragment: true
              groupItem: =props.profilecore + '_val'
              sourceType: itemsInGroup
            slots:
              default:
                - component: f7-col
                  config:
                    style:
                      height: 200px
                      width: 100%
                  slots:
                    default:
                      - component: f7-row
                        config:
                          visible: "=(items[props.profilecore + '_Type'].state == 'Percentage') ? true : false"
                        slots:
                          default:
                            - component: oh-slider
                              config:
                                item: =loop.item.name
                                label: true
                                max: 100
                                min: 0
                                scale: "=(loop.item.label == '00') ? true : false"
                                scaleSteps: 4
                                step: 1
                                style:
                                  --f7-range-bar-active-bg-color: "=(dayjs().format('HH') == loop.item.label) ? '#FFAF80' : '' "
                                  --f7-range-knob-color: "=(dayjs().format('HH') == loop.item.label) ? '#FF6700' : '' "
                                title: =loop.item.label
                                vertical: 1
                      - component: f7-row
                        config:
                          visible: "=(items[props.profilecore + '_Type'].state == 'Temperature') ? true : false"
                        slots:
                          default:
                            - component: oh-slider
                              config:
                                item: =loop.item.name
                                label: true
                                max: 25
                                min: 5
                                releaseOnly: true
                                scale: "=(loop.item.label == '00') ? true : false"
                                scaleSteps: 5
                                step: 0.5
                                style:
                                  --f7-range-bar-active-bg-color: "=(dayjs().format('HH') == loop.item.label) ? '#FFAF80' : '' "
                                  --f7-range-knob-color: "=(dayjs().format('HH') == loop.item.label) ? '#FF6700' : '' "
                                title: =loop.item.label
                                vertical: 1
                      - component: f7-row
                        config:
                          visible: "=(items[props.profilecore + '_Type'].state == 'Boolean') ? true : false"
                        slots:
                          default:
                            - component: oh-slider
                              config:
                                item: =loop.item.name
                                label: true
                                max: 1
                                min: 0
                                scale: "=(loop.item.label == '00') ? true : false"
                                scaleSteps: 1
                                step: 1
                                style:
                                  --f7-range-bar-active-bg-color: "=(dayjs().format('HH') == loop.item.label) ? '#FFAF80' : '' "
                                  --f7-range-knob-color: "=(dayjs().format('HH') == loop.item.label) ? '#FF6700' : '' "
                                title: =loop.item.label
                                vertical: 1
                      - component: f7-row
                        slots:
                          default:
                            - component: Label
                              config:
                                style:
                                  position: relative
                                  top: 30px
                                  transform: rotate(-70deg)
                                  width: 1px
                                text: =loop.item.label + ":00"
                                visible: true
    - component: Label
      config:
        style:
          height: 1px
          left: 5px
          position: absolute
          top: 210px
          transform: rotate(-90deg)
          width: 1px
        text: =items[props.profilecore + "_Type"].state

Unfortunately, when I try to put this widget into a page, it does not work properly; the name shows up and the popup-menu works (and even lets me adjust settings that belong to the specific profile) but all the sliders are broken and just show NaN values for some reason despite identical config:

What’s going wrong here? Is there some limitation that prevents oh-repeater from being used in a Pages-environment?

There is no such limitation, if a widget works in the development window then the goal is that it should work identically on pages as well. Honestly, I don’t see any errors or obvious pitfalls in the widget code.

Are there errors in your browser console when you open a page that has the widget?

Actually, yes! I’m getting this:

Proxy: need Profile1_Name 
updateTrackingList: No connection id, not calling the API

and

updateTrackingList: Pending tracking list update, not calling the API

That seems like the issue, but I have no idea what it means.

EDIT: I just checked but I get identical messages when I open the widget in the developer page, except that it works.

Full console output

Start tracking states app.js:38:2597
new SSE connection: http://192.168.1.128:8080/rest/events/states, 1 open app.js:33:140394
Array [ EventSource ]
app.js:33:140477
Setting initial tracking list: [] app.js:38:3057
Proxy: need Profile1_Name app.js:38:2146
Proxy: need Profile1_Type app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Updating tracking list: ["Profile1_Name","Profile1_Type"] app.js:38:3984
Proxy: need Profile1_0 app.js:38:2146
Proxy: need Profile1_1 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_2 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_3 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_4 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_5 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_6 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_7 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_8 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_9 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_10 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_11 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_12 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_13 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_14 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_15 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_16 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_17 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_18 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_19 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_20 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_21 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_22 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Proxy: need Profile1_23 app.js:38:2146
updateTrackingList: Pending tracking list update, not calling the API app.js:38:3702
Updating tracking list: ["Profile1_Name","Profile1_Type","Profile1_0","Profile1_1","Profile1_2","Profile1_3","Profile1_4","Profile1_5","Profile1_6","Profile1_7","Profile1_8","Profile1_9","Profile1_10","Profile1_11","Profile1_12","Profile1_13","Profile1_14","Profile1_15","Profile1_16","Profile1_17","Profile1_18","Profile1_19","Profile1_20","Profile1_21","Profile1_22","Profile1_23"] app.js:38:3984

Do you have these two windows open in different tabs of the same browser?

I’ve tried visiting the pages sequentially, on different tabs, and in different browsers and the problem persists. Interestingly, I’ve also noticed that if I load the “Page” view of the widget, it wipes all the values from the sliders, sending a “1” command to all of them simultaneously. When I load the widget in the developer view, the values simply load the States of the Number Items like they’re supposed to do.

I’ve also tried restarting OH and the server, no changes.

What version of OH are you using?

Latest OH 3.3.0 Release Build running on Raspberry Pi 4 model B, fully up to date.

This one is a little baffling. The console output you’ve shown is not an error report, it’s just the standard debug information for the widget item state tracking, and by the end of it it does appear that the widgets are properly tracking all the items required for the sliders. I have instances where I use a repeater to populate several sliders and I have not seen this behavior before. I’m running a 3.4 milestone, but there are not any significant differences in the sliders between your version and mine, and the repeater hasn’t changed since nearly the beginning of OH3.

I’m beginning to suspect that this is worth a github issue report, but maybe we should call in some higher-level opinion first.

@ysc do you see anything obvious that we’ve missed?

Here’s a video of me reproducing this issue: openHAB — Widget Development vs Pages strange error - YouTube in case it helps diagnose what’s going on here.

I’ll have a look later but at first glance already found this (2nd f7-block)!

@Marmoset_Threat try adding height: 200px to the style of your vertical slider, like so:

                            - component: oh-slider
                              config:
                                item: =loop.item.name
                                label: true
                                max: 100
                                min: 0
                                scale: "=(loop.item.label == '00') ? true : false"
                                scaleSteps: 4
                                step: 1
                                style:
                                  --f7-range-bar-active-bg-color: "=(dayjs().format('HH') == loop.item.label) ? '#FFAF80' : '' "
                                  --f7-range-knob-color: "=(dayjs().format('HH') == loop.item.label) ? '#FF6700' : '' "
                                  height: 200px
                                title: =loop.item.label
                                vertical: true

It appears when the widget is in a page the slider couldn’t compute its own height and misbehaves.

1 Like

That did the trick!

It seems the “visibility” setting does not work properly in edit mode, but in run mode, it work fine:

Edit mode:

Run mode:

Thanks!

1 Like

This one is by design. It’s a parameter that applies to all components including those you set up in the designer (like blocks, rows, cols) and you wouldn’t want those to disappear from you while you’re editing, so everything’s visible regardless of those parameters. It’s the same principle as the fact that no action can be performed while in edit mode (you’ll get a toast notification instead) - you wouldn’t want to navigate away or perform something you didn’t intend to during the design phase so all actions are neutered.

It’s true that it breaks widgets that rely on it to display correctly, so it could be improved.