Drop-down List in oh-input-item

I’d like to create a drop-down list to enter text (e.g. all playlists - I select one and then it’s played by Alexa).
In the f7-docs I found something that should do the job:

              <div class="item-title item-label">Gender</div>
              <div class="item-input-wrap input-dropdown-wrap">
                <select placeholder="Please choose...">
                  <option value="Male">Male</option>
                  <option value="Female">Female</option>
                </select>
              </div>
            </div>

However, I don’t know how to transform this to YAML. I guess an adapted version might be put somewhere in the ‘type’-definition?

component: oh-input-item
config:
  sendButton: true
  item: AlexaHolger_MusikSprachbefehl
  placeholder: Spiele meine Playlist Holger
  title: Musiksprachbefehl
  name: Input Name
  type: text
slots: null

Not possible atm - theres an open issue for this in the webui repo: Can't add selection elements to oh-input type 'select' · Issue #982 · openhab/openhab-webui · GitHub

You can find some working alternatives here

1 Like

Hello Rainer,

too bad that OH doesn’t support dropdowns yet. Your workaround (selection list #1) is very nice, but it doesn’t show any values/ the popup window remains empty.
My guess is that I need to fill “testItem” with the values I want to appear. So I created the item (as String) and tried to fill it as an array with a script:
image
Both versions didn’t work. Do you know what I need to do to get it working?

Hey @Ursusprimus

you have to assign the selection values inside the “Options” field of the “State Description” Metdata to that item:

Settings → Items → “testItem” → Add Metadata → State Description → Options

1 Like

Thank you!

@RGroll Now I have follow up question/problem:
I’d like several of your drop down items in a list card (I’m aware that I’m not making use of your elegant programming where you can get several dropdown-lists next to each other just by adding three lines each). When I do so, most of the time (not always?) the second popup appears even when I click on the first dropdown-list.
It’s probably because of identical popup-window-names but since I don’t fully understand your code, I don’t know (and dare) what to change …

I tried line 30 (give it a fixed name), but that didn’t work. And messing with line 35 didn’t help either …

component: oh-list-card
config: {}
slots:
  default:
    - component: f7-row
      config: {}
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: array
              for: selection
              in:
                - title: Musik/Lists
                  icon: f7:music_albums
                  item: Alexa_Musik
              fragment: true
            slots:
              default:
                - component: f7-col
                  slots:
                    default:
                      - component: oh-list
                        config:
                          id: list
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: =loop.selection.title
                                after: =items[loop.selection.item].displayState
                                smartSelect: true
                                icon: =loop.selection.icon
                                iconColor: default
                                popupOpen: =".selectionPopup_"+loop.selection_idx
                                style:
                                  border: 1px solid lightgray
                                  border-radius: 5px
                      - component: f7-popup
                        config:
                          class: ="selectionPopup_"+loop.selection_idx
                        slots:
                          default:
                            - component: f7-page
                              slots:
                                default:
                                  - component: f7-navbar
                                    config:
                                      title: =loop.selection.title
                                      style:
                                        position: sticky
                                    slots:
                                      left:
                                        - component: oh-link
                                          config:
                                            iconIos: f7:arrow_left
                                            iconMd: material:arrow_back
                                            iconAurora: f7:arrow_left
                                            popup-close: true
                                  - component: f7-list
                                    config:
                                      virtualList: true
                                    slots:
                                      default:
                                        - component: oh-repeater
                                          config:
                                            sourceType: itemStateOptions
                                            itemOptions: =loop.selection.item
                                            for: option
                                            fragment: true
                                          slots:
                                            default:
                                              - component: oh-list-item
                                                config:
                                                  title: =loop.option.label
                                                  actionFeedback: ='{ "text":"You selected <b>' + loop.option.label +
                                                    '</b><br>Sending command
                                                    <b>' +  loop.option.value +
                                                    '</b> to item",
                                                    "position":"center","icon":"<i
                                                    style=\\"color:green\\"
                                                    class=\\"f7-icons\\">checkmark_alt</i>","closeButton":true
                                                    }'
                                                  noChevron: true
                                                  radio: true
                                                  checked: "=loop.option.value === items[loop.selection.item].state ? true :
                                                    false"
                                                  popupClose: true
                                                  action: command
                                                  actionItem: =loop.selection.item
                                                  actionCommand: =loop.option.value
    - component: f7-row
      config: {}
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: array
              for: selection
              in:
                - title: Alexa Gerät
                  icon: f7:tv_music_note
                  item: Alexa_Device
              fragment: true
            slots:
              default:
                - component: f7-col
                  slots:
                    default:
                      - component: oh-list
                        config:
                          id: list
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: =loop.selection.title
                                after: =items[loop.selection.item].displayState
                                smartSelect: true
                                icon: =loop.selection.icon
                                iconColor: default
                                popupOpen: =".selectionPopup_"+loop.selection_idx
                                style:
                                  border: 1px solid lightgray
                                  border-radius: 5px
                            - component: oh-list-item
                              config: {}
                      - component: f7-popup
                        config:
                          class: ="selectionPopup_"+loop.selection_idx
                        slots:
                          default:
                            - component: f7-page
                              slots:
                                default:
                                  - component: f7-navbar
                                    config:
                                      title: =loop.selection.title
                                      style:
                                        position: sticky
                                    slots:
                                      left:
                                        - component: oh-link
                                          config:
                                            iconIos: f7:arrow_left
                                            iconMd: material:arrow_back
                                            iconAurora: f7:arrow_left
                                            popup-close: true
                                  - component: f7-list
                                    config:
                                      virtualList: true
                                    slots:
                                      default:
                                        - component: oh-repeater
                                          config:
                                            sourceType: itemStateOptions
                                            itemOptions: =loop.selection.item
                                            for: option
                                            fragment: true
                                          slots:
                                            default:
                                              - component: oh-list-item
                                                config:
                                                  title: =loop.option.label
                                                  actionFeedback: ='{ "text":"You selected <b>' + loop.option.label +
                                                    '</b><br>Sending command
                                                    <b>' +  loop.option.value +
                                                    '</b> to item",
                                                    "position":"center","icon":"<i
                                                    style=\\"color:green\\"
                                                    class=\\"f7-icons\\">checkmark_alt</i>","closeButton":true
                                                    }'
                                                  noChevron: true
                                                  radio: true
                                                  checked: "=loop.option.value === items[loop.selection.item].state ? true :
                                                    false"
                                                  popupClose: true
                                                  action: command
                                                  actionItem: =loop.selection.item
                                                  actionCommand: =loop.option.value
    - component: oh-toggle-item
      config:
        title: Alexa starten
        item: Alexa_Start

Hey @Ursusprimus

I can understand that the oh-repeater component might be hard to understand at first glance but it’s more than worth digging into it’s concept, as its maybe one of the mightiest ones that the MainUI has to offer currently.

Some material which might help you here:

It’s crucial that all elements (that should trigger a list selection) are childs of the oh-repeater component, to distinguish between the correct popup to open.


In the way you did it, the selection popups have the same ID and the system grabs one randomly, which is the reason for the observed behaviour, as you already recognized by yourself. :slight_smile:


The ‘funny’ thing is, that you made yourself much more work than needed and you already touched the right elements while doing so (I might repeat me here, but trust me, that you’ll save a lot of time in the long-term if this trial&error approach changes to ‘I understand what I do’ - It’s worth it!) :

          - component: oh-repeater
            config:
              sourceType: array
              for: selection
              in:
                - title: Musik/Lists
                  icon: f7:music_albums
                  item: Alexa_Musik
                - title: Alexa Gerät
                  icon: f7:tv_music_note
                  item: Alexa_Device

This first oh-repeater component of type: array creates the structure of its childs (everything that is in it’s default slot) for every array that is defined at the in: part of it (every array starts with the dash -). Each of these arrays have elements assigned to it (3 for each of them in this case).

As you want to create 2 selection elements you need 2 arrays with 3 elements each (The list-title; list-icon & the itemName which holds your selection metadata)

To access these array elements you have to use the name of the for-loop (selection in that case) and the elements name… so for the list-title for example, if would look like:

= loop .selection .title
Start your expression [fixed] Accessing the oh-repeater for-loop [fixed] Name of your loop [custom] Element inside your array that you want to access [custom]

… which leads to:
=loop.selection.title

Hope this made it a bit more clear for you.


Corrected YAML
uid: ursusprimus_selection
component: f7-card
slots:
  default:
    - component: f7-row
      config:
        class:
          - padding
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: array
              for: selection
              in:
                - title: Musik/Lists
                  icon: f7:music_albums
                  item: Alexa_Musik
                - title: Alexa Gerät
                  icon: f7:tv_music_note
                  item: Alexa_Device
              fragment: true
            slots:
              default:
                - component: f7-col
                  slots:
                    default:
                      - component: oh-list
                        config:
                          id: list
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: =loop.selection.title
                                after: =items[loop.selection.item].displayState
                                smartSelect: true
                                icon: =loop.selection.icon
                                iconColor: default
                                popupOpen: =".selectionPopup_"+loop.selection_idx
                                style:
                                  border: 1px solid lightgray
                                  border-radius: 5px
                      - component: f7-popup
                        config:
                          class: ="selectionPopup_"+loop.selection_idx
                        slots:
                          default:
                            - component: f7-page
                              slots:
                                default:
                                  - component: f7-navbar
                                    config:
                                      title: =loop.selection.title
                                      style:
                                        position: sticky
                                    slots:
                                      left:
                                        - component: oh-link
                                          config:
                                            iconIos: f7:arrow_left
                                            iconMd: material:arrow_back
                                            iconAurora: f7:arrow_left
                                            popup-close: true
                                  - component: f7-list
                                    config:
                                      virtualList: true
                                    slots:
                                      default:
                                        - component: oh-repeater
                                          config:
                                            sourceType: itemStateOptions
                                            itemOptions: =loop.selection.item
                                            for: option
                                            fragment: true
                                          slots:
                                            default:
                                              - component: oh-list-item
                                                config:
                                                  title: =loop.option.label
                                                  actionFeedback: ='{ "text":"You selected <b>' + loop.option.label + '</b><br>Sending command <b>' +  loop.option.value + '</b> to item", "position":"center","icon":"<i style=\\"color:green\\" class=\\"f7-icons\\">checkmark_alt</i>" }'
                                                  noChevron: true
                                                  radio: true
                                                  checked: "=loop.option.value === items[loop.selection.item].state ? true : false"
                                                  popupClose: true
                                                  action: command
                                                  actionItem: =loop.selection.item
                                                  actionCommand: =loop.option.value
    - component: oh-list
      config:
        mediaList: true
      slots:
        default:
          - component: oh-toggle-item
            config:
              title: Alexa starten
              item: Alexa_Start
2 Likes

This was it - for what I want to achieve I had to change the id which you call idx. I didn’t recognize the x as a part of the identifier but thought it was some kind of reserved OH-specific expression. So all I had to do was change one idx to id1 (and for clarity’s sake the other to id2) and nowit’s fine.

I’m sorry I didn’t express myself clearer and you went through the effort of explaining things so thoroughly - although I (more or less) understood the basic structure of repeater and loop already. I knew that I could simply get additional dropdowns next to each other with your code and how to achieve that. But I didn’t want them in the same row or not necessarily in the same card item either, but want to be able to position the drop downs anywhere in the page.

In any way, thank you so much for your patience and continued support. And yes, I’m getting to understand things better (week by week), although I still lack some fundamental basic understanding in so many areas …
I did a little Pascal programming in High School >30years ago, was quite familiar with MS Access and Excel, but that’s about as far as my IT skills go. So RasPi/Linux, general OH-concepts, quite a bunch of binding specific problems, YAML, F7, Jacascript, Nodered - that’s quite a lot to tackle :wink:

It is. The _idx is an oh-specific placeholder for the ‘index’ of the array (which is 0 and 1 here for 2 arrays, which distinguish them from each other) - Don’t get me wrong here, but assuming things isn’t the same as understanding them. :wink:


It will help someone at some point so I don’t mind and it will result in nice widgets for all of us at some point.


This has nothing to do with the oh-repeater. You can build up the structure for each component however you like.


If you only want one component, you shouldn’t use the (1st) oh-repeater at all, as it would cause an unecessary overhead with no purpose.


I’m totaly fine with this, as I see you’re willed to move forward and try to do things by yourself. And as I stated above, I’m sure we’ll get something in return at some point. :slight_smile:


Maybe starting with the basic OH-concept, YAML and F7 is enough for the first year. :stuck_out_tongue_winking_eye:

I’ve tried to get rid off unnecessary code and replace the loop variables with the actual items/texts. There were several aspects I’m unsure about (especially the first 2; indicated with //, which I deleted for the actual YAML). It’s either one of them or some other mistake (or a combination of both :wink: )
Anyway, like this no popup-window opens:

component: oh-list-card
config: {}
slots:
  default:
    - component: f7-row
      config: {}
      slots:
        default:
 

                - component: f7-col
                  slots:
                    default:
                      - component: oh-list
                        config:
                          id: list
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: Musik
                                after: =items.Alexa_Musik.displayState
                                smartSelect: true
                                icon: f7:music_albums
                                iconColor: default
                                popupOpen: PopupMusik                   //=".selectionPopup_"+loop.selection_idx   ???
                                style:
                                  border: 1px solid lightgray
                                  border-radius: 5px
                      - component: f7-popup
                        config:
                          class: popup                                         //    ="selectionPopup_"+loop.selection_idx   ???  
                        slots:
                          default:
                            - component: f7-page
                              slots:
                                default:
                                  - component: f7-navbar
                                    config:
                                      title: Musik
                                      style:
                                        position: sticky
                                    slots:
                                      left:
                                        - component: oh-link
                                          config:
                                            iconIos: f7:arrow_left
                                            iconMd: material:arrow_back
                                            iconAurora: f7:arrow_left
                                            popup-close: true
                                  - component: f7-list
                                    config:
                                      virtualList: true
                                    slots:
                                      default:
                                        - component: oh-repeater
                                          config:
                                            sourceType: itemStateOptions
                                            itemOptions: Alexa_Musik 				// =loop.selection.item        ?
                                            for: option
                                            fragment: true
                                          slots:
                                            default:
                                              - component: oh-list-item
                                                config:
                                                  title: =loop.option.label
                                                  actionFeedback: ='{ "text":"You selected <b>' + loop.option.label +
                                                    '</b><br>Sending command
                                                    <b>' +  loop.option.value +
                                                    '</b> to item",
                                                    "position":"center","icon":"<i
                                                    style=\\"color:green\\"
                                                    class=\\"f7-icons\\">checkmark_alt</i>","closeButton":true
                                                    }'
                                                  noChevron: true
                                                  radio: true
                                                  checked: "=loop.option.value === items[loop.selection.item].state ? true :
                                                    false"
                                                  popupClose: true
                                                  action: command
                                                  actionItem: Alexa_Musik			//	=loop.selection.item
                                                  actionCommand: =loop.option.value

Only smaller things here…

  • popupOpen: expects a classname with a leading dot . - so it would be .PopupMusik in your case.

  • This PopupMusik is also the classname which you have to use in the f7-popup component as this is the component which should open - without the dot. So it would be:
    class: PopupMusik

The rest seems fine!

P.S. To slim down your code even more, you could get rid of the row and columns at the beginning and change the root component to oh-list, to get rid of the padding.

Shortened YAML
component: oh-list
config:
  noHairlinesBetween: true
slots:
  default:
    - component: oh-list-item
      config:
        title: Musik
        after: =items.Alexa_Musik.displayState
        smartSelect: true
        icon: f7:music_albums
        iconColor: default
        popupOpen: .PopupMusik
        style:
          border: 1px solid lightgray
          border-radius: 5px
    - component: f7-popup
      config:
        class: PopupMusik
      slots:
        default:
          - component: f7-page
            slots:
              default:
                - component: f7-navbar
                  config:
                    title: Musik
                    style:
                      position: sticky
                  slots:
                    left:
                      - component: oh-link
                        config:
                          iconIos: f7:arrow_left
                          iconMd: material:arrow_back
                          iconAurora: f7:arrow_left
                          popup-close: true
                - component: f7-list
                  config:
                    virtualList: true
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          sourceType: itemStateOptions
                          itemOptions: Alexa_Musik
                          for: option
                          fragment: true
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: =loop.option.label
                                actionFeedback: ='{ "text":"You selected <b>' + loop.option.label +
                                  '</b><br>Sending command
                                  <b>' +  loop.option.value +
                                  '</b> to item",
                                  "position":"center","icon":"<i
                                  style=\\"color:green\\"
                                  class=\\"f7-icons\\">checkmark_alt</i>
                                  }'
                                noChevron: true
                                radio: true
                                checked: "=loop.option.value === items[loop.selection.item].state ? true :
                                  false"
                                popupClose: true
                                action: command
                                actionItem: Alexa_Musik
                                actionCommand: =loop.option.value

That’s great, thank you again! Not very important any more, but for perfection’s sake: Now all dots in the popup-windows are filled out - what to do about that?

Code isn’t really changed from your improved example, just another list item, so no real need to look at it, I think:

component: oh-list-card
config:
  noHairlinesBetween: true
slots:
  default:
    - component: oh-list-item
      config:
        title: Musik
        after: =items.Alexa_Musik.displayState
        smartSelect: true
        icon: f7:music_albums
        iconColor: default
        popupOpen: .PopupMusik
        style:
          border: 1px solid lightgray
          border-radius: 5px
    - component: f7-popup
      config:
        class: PopupMusik
      slots:
        default:
          - component: f7-page
            slots:
              default:
                - component: f7-navbar
                  config:
                    title: Musik
                    style:
                      position: sticky
                  slots:
                    left:
                      - component: oh-link
                        config:
                          iconIos: f7:arrow_left
                          iconMd: material:arrow_back
                          iconAurora: f7:arrow_left
                          popup-close: true
                - component: f7-list
                  config:
                    virtualList: true
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          sourceType: itemStateOptions
                          itemOptions: Alexa_Musik
                          for: option
                          fragment: true
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: =loop.option.label
                                actionFeedback: ='{ "text":"You selected <b>' + loop.option.label +
                                  '</b><br>Sending command <b>'
                                  +  loop.option.value + '</b> to item",
                                  "position":"center","icon":"<i
                                  style=\\"color:green\\"
                                  class=\\"f7-icons\\">checkmark_alt</i> }'
                                noChevron: true
                                radio: true
                                checked: "=loop.option.value === items[loop.selection.item].state ? true :
                                  false"
                                popupClose: true
                                action: command
                                actionItem: Alexa_Musik
                                actionCommand: =loop.option.value
    - component: oh-list-item
      config:
        title: Alexa/Gerät
        after: =items.Alexa_Device.displayState
        smartSelect: true
        icon: f7:music_albums
        iconColor: default
        popupOpen: .PopupDevice
        style:
          border: 1px solid lightgray
          border-radius: 5px
    - component: f7-popup
      config:
        class: PopupDevice
      slots:
        default:
          - component: f7-page
            slots:
              default:
                - component: f7-navbar
                  config:
                    title: Gerät
                    style:
                      position: sticky
                  slots:
                    left:
                      - component: oh-link
                        config:
                          iconIos: f7:arrow_left
                          iconMd: material:arrow_back
                          iconAurora: f7:arrow_left
                          popup-close: true
                - component: f7-list
                  config:
                    virtualList: true
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          sourceType: itemStateOptions
                          itemOptions: Alexa_Device
                          for: option
                          fragment: true
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: =loop.option.label
                                actionFeedback: ='{ "text":"You selected <b>' + loop.option.label +
                                  '</b><br>Sending command <b>'
                                  +  loop.option.value + '</b> to item",
                                  "position":"center","icon":"<i
                                  style=\\"color:green\\"
                                  class=\\"f7-icons\\">checkmark_alt</i> }'
                                noChevron: true
                                radio: true
                                checked: "=loop.option.value === items[loop.selection.item].state ? true :
                                  false"
                                popupClose: true
                                action: command
                                actionItem: Alexa_Device
                                actionCommand: =loop.option.value

Ah sry, didn’t saw that - it’s about this line:

checked: "=loop.option.value === items[loop.selection.item].state ? true : false"

The loop.selection.item isn’t there any more and it tries to compare every of the list-entries with the current state to mark it as active (checked). So this should work:

checked: "=loop.option.value === items['Alexa_Musik'].state ? true : false"

1 Like