BoGoB: Big Ol' Grid O' Buttons

Jump to the latest working code:

Hi,

I have a requirement to test up to 45+ functions for the forthcoming TiVo binding. So I really need to replicate each of the buttons on the remote control. Unfortunately these functions are associated with different items, some need labels, some need icons etc.

I was hoping to develop something generic that can be re-used for any other relevant application (by me or anyone else). My idea was to use a unset for/loop with an array of the required properties:

- [0, '', false, '', '', false, '', '', '', :'gray', 'white']
- [1, 'Standby', false, 'f7', 'power', true, 'TivoLivingRoom_RemoteControlButton', 'STANDBY', '', :'gray', 'lime']
- [2, 'Home', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'TIVO', '', :'gray', 'white']
- [1, 'TV', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'LIVETV', '', :'gray', 'white']
- [0, '', false, '', '', false, '', '', '', :'gray', 'white']
- [1, 'Guide', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'GUIDE', '', :'gray', 'white']
- [1, 'My Shows', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', '', '', :'gray', 'white']
- [1, 'Subtitles', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', '', '', :'gray', 'white']
- [0, '', false, '', '', false, '', '', '', :'gray', 'white']

Note: I know this is is JSON array format, it works but when you save / exit / re-enter the component it is converted to YAML array format. I just find the one line easier to generate (in an Excel workbook).

Where the array elements are:

  1. size = 0, new row | > 0 renders a button that is n * multiple button size in pixels.
  2. label = button label (also used to keep track of rows where icons are used)
  3. labelShow = true | false to display the label
  4. iconCollection = f7 | material icon collection
  5. iconName = icon name
  6. iconShow = true | false
  7. itemName = item name
  8. itemCommand = command to send when the button is pressed
  9. ruleName = rule to run when button is pressed
  10. bgColor = background color
  11. fgColor = foreground color

The YAML below, basically works but draws each button on a separate row.

Ideally I was hoping it was possible to conditionally add the row component when the loop reached an entry where the first element = 0 i.e. when (loop.i[0]===0 ? true : false).

- component: f7-row
  config:
  class:
    - align-items-flex-center

I’ve been looking at this most of the afternoon and I’m stuck… I’m beginning to think that this may not be possible as I originally envisaged… :crazy_face: I guess it may be the change of indent that tells framework7 to close the component tags ???

So if anyone knows is this is possible / what the syntax is… or has an alternative approach to try…

Andy

Code

Here is the WIP so far:

uid: BoGoB
tags: []
props:
  parameters:
    - description: Set card header title. Only displays if populated.
      label: Card Title
      name: title
      required: false
      type: TEXT
      groupName: general
    - description: Background image URL e.g. http://10.1.0.1/static/fibaromotion.png
      label: Background image URL
      name: backgroundUrl
      required: false
      type: TEXT
      groupName: general
    - description: Intensity of the background-blur (0 - 10)
      label: Background image blur
      name: backgroundBlur
      required: false
      type: TEXT
      groupName: general
    - context: color
      description: Specify the background color for card. Any valid <a class="link external" href="https://www.w3schools.com/css/css_colors.asp" target="_blank">HTML color format (RGB/RGBA/HEX/HSL)</a> or <a class="link external" href="https://framework7.io/docs/css-variables.html" target="_blank">CSS theme</a> color. e.g. rgb(255,255,255), --f7-color-white. <b>Default = --f7-color-white</b>
      label: Background color
      name: backgroundColor
      required: false
      type: TEXT
      groupName: general
    - description: Specify the foreground color for text and icons. Any valid <a class="link external" href="https://www.w3schools.com/css/css_colors.asp" target="_blank">HTML color format (RGB/RGBA/HEX/HSL)</a> or <a class="link external" href="https://framework7.io/docs/css-variables.html" target="_blank">CSS theme</a> color. e.g. rgb(255,255,255), --f7-color-black. <b>Default = --f7-color-black</b>
      label: Foreground color (normal)
      name: foregroundColor
      required: false
      type: TEXT
      groupName: general
    - description: Specify the foreground color for highlighted text / icons (when warning condition is true). Any valid <a class="link external" href="https://www.w3schools.com/css/css_colors.asp" target="_blank">HTML color format (RGB/RGBA/HEX/HSL)</a> or <a class="link external" href="https://framework7.io/docs/css-variables.html" target="_blank">CSS theme</a> color. e.g. rgb(255,255,255), --f7-color-red. <b>Default = --f7-theme-color</b>
      label: Foreground color (warning)
      name: foregroundColorWarn
      required: false
      type: TEXT
      groupName: general
    - description: Set the number of rows in the grid.
      label: Number of rows
      name: rows
      required: true
      type: INTEGER
      groupName: grid
    - description: Set the number of columns in the grid.
      label: Number of columns
      name: columns
      required: true
      type: INTEGER
      groupName: grid
    - description: Set the number of columns in the grid.
      label: Button Array specification
      name: buttArray
      required: true
      type: TEXT
      groupName: grid
  parameterGroups:
    - name: general
      label: Display options
    - name: grid
      label: Grid setup
timestamp: Jan 24, 2021, 8:11:29 PM
component: f7-card
config:
  title: '=(props.title) ? props.title : "Set props to test!"'
slots:
  default:
    - component: f7-block
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: unset
              for: i
              in:
              - [0, '', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Standby', false, 'f7', 'power', true, 'TivoLivingRoom_RemoteControlButton', 'STANDBY', '', :'gray', 'lime']
              - [2, 'Home', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'TIVO', '', :'gray', 'white']
              - [1, 'TV', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'LIVETV', '', :'gray', 'white']
              - [0, '', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Guide', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'GUIDE', '', :'gray', 'white']
              - [1, 'My Shows', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', '', '', :'gray', 'white']
              - [1, 'Subtitles', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', '', '', :'gray', 'white']
              - [0, '', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Blank', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Up', false, 'f7', 'arrowtriangle_up', true, '', 'UP', '', :'gray', 'white']
              - [1, 'Info', false, 'f7', 'info_circle_fill', true, 'TivoLivingRoom_ChangeMenuScreen', 'NOWPLAYING', '', :'gray', 'white']
              - [0, '', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Left', false, 'f7', 'arrowtriange_left', true, '', 'LEFT', '', :'gray', 'white']
              - [1, 'OK', true, '', '', false, '', 'SELECT', '', :'gray', 'white']
              - [1, 'Right', false, 'f7', 'arrowtriange_right', true, '', 'RIGHT', '', :'gray', 'white']
              - [0, '', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Back', true, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Down', false, 'f7', 'arrowtriange_down', true, '', 'DOWN', '', :'gray', 'white']
              - [1, 'Subtitles', true, '', '', false, '', '', '', :'gray', 'white']
              - [0, '', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, '1', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM1', '', :'gray', 'white']
              - [1, '2', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM2', '', :'gray', 'white']
              - [1, '3', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM3', '', :'gray', 'white']
              - [0, '0', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, '4', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM4', '', :'gray', 'white']
              - [1, '5', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM5', '', :'gray', 'white']
              - [1, '6', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM6', '', :'gray', 'white']
              - [0, '0', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, '7', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM7', '', :'gray', 'white']
              - [1, '8', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM8', '', :'gray', 'white']
              - [1, '9', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM9', '', :'gray', 'white']
              - [0, '0', false, '', '', false, '', '', '', :'gray', 'white']
              - [1, 'Clear', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'CLEAR', '', :'gray', 'white']
              - [1, '0', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM0', '', :'gray', 'white']
              - [1, 'Last Ch', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', '', '', :'gray', 'white']
              fragment: true
            slots:
              default:
                - component: f7-row
                  config:
                    class:
                      - align-items-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          visible: "=(loop.i[5] || loop.i[2]) ? true : false"
                          action: analyzer
                          class:
                            - float-left
                            - align-items-flex-start
                            - justify-content-center
                            - align-items-start
                            - text-align-center
                          style:
                            height: 100%
                            border: 1px solid black
                            margin: 1px
                            width: =loop.i[0] * 100 + 'px'
                            --f7-button-bg-color: var(--f7-color-gray-shade)
                            --f7-button-hover-bg-color: var(--f7-color-white-shade)
                            --f7-button-pressed-bg-color: var(--f7-color-white-shade)
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: =loop.i[5]
                                f7: =loop.i[4]
                                size: 14
                                style:
                                  padding-right: 5px
                                  color: =loop.i[10]
                            - component: Label
                              config:
                                visible: =loop.i[2]
                                text: =loop.i[1]
                                style:
                                  font-size: 14px
                                  font-weight: 400
                                  color: =loop.i[10]

For your use case you might be interested in A Complete Guide to Grid | CSS-Tricks - a relatively new, complex but powerful feature of CSS.
In this article the CSS properties in the left column would go to the f7-block (or the oh-repeater if you remove fragment: true) and the properties in the right column to the children (oh-buttons), with expressions to control them.

1 Like

Thanks Yannick @ysc,

That was the solution I was looking for - SO COOL! Once I’d got my head around the concept, it was super easy to use. It’s taken more time mapping the commands from the TiVo protocol specification to the button labels they use on the remote than coding the widget :laughing:

Here is the result (47 clickable buttons):

Even better only one problem was identified to feed back to the team who have picked up the work on this binding, everything else worked.

The properties to populate each of the buttons is done from a JSON/YAML array. This takes the form:

ArrayIndex Name Description Required Example
0 row Specify the row index for the target object (button) Y 1
1 column Specify the column index for the target object (button) Y 1
2 span_row Allows the button to span across multiple grid cells e.g. Home / Guide Y 1
3 span_column Allows the button to span vertically across multiple grid cells Y 1
4 label button label N Standby
5 labelShow true or false to display the label Y FALSE
6 iconCollection f7 material icon collection N
7 iconName icon name N power
8 iconShow true or false Y TRUE
9 itemName item name Y TivoLivingRoom_RemoteControlButton
10 itemCommand command to send when the button is pressed Y STANDBY
11 ruleName * future functionality N
12 bgColor background color (named style or any supported color assignment syntax) N –f7-color-gray-tint
13 fgColor foreground color (named style or any supported color assignment syntax) N –f7-color-green

I used the following Excel sheet to generate the array data in JSON array format. This is pretty easy to generate accurately using this template. I’ve left the values used to generate the above example in the grid. The formula in column O can then be copied / pasted into the widget (search for in: and replace the code until the fragment: true line):

BoGoB Configuration Tool.xlsx

  • You do not need to add buttons in the order that they are eventually displayed, you just need to get the row/column co-ordinates correct.
  • The grid expands automatically depending on the largest index value you assign. So you can add as few or as many buttons as you need.
  • Card title, background color and the grid cell height / width can be specified in the widget properties.

Limitations:

  • I want to eventually trigger some rules using the light blue buttons. I’m sure I’ve read that this is possible somewhere in the forum, but my GoogleFoo is obviously weak at the moment.
  • As the button properties are specified within the widget code, you would need to create separate instances of the code to support different button layouts.
  • It would be great to be able to ‘load’ the configuration data from a file over http (making this a re-usable widget), but that’s a challenge for another day and I suspect would need some additional ‘back end’ functionality. Certainly it’s beyond my knowledge today :stuck_out_tongue_winking_eye:

While I guess most people won’t need a grid of buttons as big as this example I’m going to keep it for that critical moment when the remote control batteries run out and replacements can’t be found :grinning:

Here’s the YAML. Let me know if there’s anything that can be improved, Andy

uid: BoGoB
tags: []
props:
  parameters:
    - description: Set card header title. Only displays if populated.
      label: Card Title
      name: title
      required: false
      type: TEXT
      groupName: general
    - context: color
      description: Specify the background color for card. Any valid <a class="link external" href="https://www.w3schools.com/css/css_colors.asp" target="_blank">HTML color format (RGB/RGBA/HEX/HSL)</a> or <a class="link external" href="https://framework7.io/docs/css-variables.html" target="_blank">CSS theme</a> color. e.g. rgb(255,255,255), --f7-color-white. <b>Default = --f7-color-white</b>
      label: Background color
      name: backgroundColor
      required: false
      type: TEXT
      groupName: general
    - description: Set the width of a grid unit button. <b>You must include the CSS units e.g. px,em,rem etc.</b> Objects that span multiple grid containers will stretch to fill the container. Default 80px.
      label: Button Width
      name: buttWidth
      required: true
      type: TEXT
      groupName: grid
    - description: Set the height of a grid unit button. <b>You must include the CSS units e.g. px,em,rem etc.</b> Objects that span multiple grid containers will stretch to fill the container. Default 3.5rem.
      label: Button Height
      name: buttHeight
      required: true
      type: TEXT
      groupName: grid
  parameterGroups:
    - name: grid
      label: Grid setup
    - name: general
      label: Display options
timestamp: Jan 25, 2021, 10:23:55 PM
component: f7-card
config:
  title: =props.title
  class:
    - padding
  style:
    background-image: ='url(' + props.backgroundUrl + ')'
    backdrop-filter: ='blur(' + props.backgroundBlur + 'px)'
    background-size: contain
    background-repeat: no-repeat
    background-position: 100% 100%
    background-color: '=(props.backgroundColor === undefined ? "var(--f7-color-white)" : (props.backgroundColor.substring(0,2) === "--" ? "var(props.backgroundColor)" : props.backgroundColor))'
    border-radius: 5px
    overflow: hidden
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
slots:
  default:
    - component: f7-block
      config:
        class: bog - margin
        style:
          display: grid
          grid-auto-columns: '=(props.buttWidth === undefined) ? "80px" : props.buttWidth'
          grid-auto-rows: '=(props.buttHeight === undefined) ? "3.5rem" : props.buttHeight'
          grid-gap: 6px 6px
          justify-items: center
          justify-content: start
      slots:
        default:
          - component: oh-repeater
            config:
              sourceType: unset
              for: i
              in:
              - [1, 1, 1, 1, 'Standby', false, 'f7', 'power', true, 'TivoLivingRoom_RemoteControlButton', 'STANDBY', '', '--f7-color-gray-tint', '--f7-color-green']
              - [1, 2, 1, 3, 'Home', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'TIVO', '', '--f7-color-gray-tint', '--f7-color-white']
              - [1, 5, 1, 1, 'TV', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'LIVETV', '', '--f7-color-gray-tint', '--f7-color-white']
              - [2, 2, 1, 3, 'Guide', true, '', '', false, 'TivoLivingRoom_ChangeMenuScreen', 'GUIDE', '', '--f7-color-gray-tint', '--f7-color-white']
              - [2, 5, 1, 1, 'Info', true, 'f7', 'info_circle', true, 'TivoLivingRoom_RemoteControlButton', 'INFO', '', '--f7-color-gray-tint', '--f7-color-white']
              - [3, 3, 1, 1, 'Up', false, 'f7', 'arrowtriangle_up_fill', true, 'TivoLivingRoom_RemoteControlButton', 'UP', '', '--f7-color-gray-shade', '--f7-color-white']
              - [3, 5, 1, 1, 'Subs On', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'CC_ON', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 5, 1, 1, 'Subs Off', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'CC_OFF', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 1, 1, 1, 'Back', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'EXIT', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 2, 1, 1, 'Left', false, 'f7', 'arrowtriangle_left_fill', true, 'TivoLivingRoom_RemoteControlButton', 'LEFT', '', '--f7-color-gray-shade', '--f7-color-white']
              - [4, 3, 1, 1, 'OK', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'SELECT', '', '--f7-color-gray-shade', '--f7-color-white']
              - [4, 4, 1, 1, 'Right', false, 'f7', 'arrowtriangle_right_fill', true, 'TivoLivingRoom_RemoteControlButton', 'RIGHT', '', '--f7-color-gray-shade', '--f7-color-white']
              - [5, 1, 1, 1, 'Vol +', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'VOLUMEUP', '', '--f7-color-gray-shade', '--f7-color-white']
              - [5, 3, 1, 1, 'Down', false, 'f7', 'arrowtriangle_down_fill', true, 'TivoLivingRoom_RemoteControlButton', 'DOWN', '', '--f7-color-gray-shade', '--f7-color-white']
              - [5, 5, 1, 1, 'Ch +', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'CHANNELUP', '', '--f7-color-gray-shade', '--f7-color-white']
              - [6, 1, 1, 1, 'Vol -', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'VOLUMEDOWN', '', '--f7-color-gray-shade', '--f7-color-white']
              - [6, 2, 1, 3, 'My Shows', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'NOWPLAYING', '', '--f7-color-gray-tint', '--f7-color-white']
              - [6, 5, 1, 1, 'Ch -', true, '', '', false, 'TivoLivingRoom_RemoteControlButton', 'CHANNELDOWN', '', '--f7-color-gray-shade', '--f7-color-white']
              - [7, 1, 1, 1, 'Thumb Down', false, 'f7', 'hand_thumbsdown_fill', true, 'TivoLivingRoom_RemoteControlButton', 'THUMBSDOWN', '', '--f7-color-red-shade', '--f7-color-white']
              - [7, 2, 1, 1, 'Mute', true, 'material', 'volumne_off', false, 'TivoLivingRoom_RemoteControlButton', 'MUTE', '', '--f7-color-gray-tint', '--f7-color-white']
              - [7, 3, 1, 2, 'Record', false, 'f7', 'recordingtape', true, 'TivoLivingRoom_RemoteControlButton', 'RECORD', '', '--f7-color-red-shade', '--f7-color-white']
              - [7, 5, 1, 1, 'Thumbs Up', false, 'f7', 'hand_thumbsup_fill', true, 'TivoLivingRoom_RemoteControlButton', 'THUMBSUP', '', '--f7-color-green-shade', '--f7-color-white']
              - [1, 9, 1, 1, 'Play', false, 'f7', 'play_fill', true, 'TivoLivingRoom_RemoteControlButton', 'PLAY', '', '--f7-color-gray-tint', '--f7-color-white']
              - [2, 8, 1, 1, 'Rewind', false, 'f7', 'backward_fill', true, 'TivoLivingRoom_RemoteControlButton', 'REVERSE', '', '--f7-color-gray-tint', '--f7-color-white']
              - [2, 9, 1, 1, 'Pause', false, 'f7', 'pause_fill', true, 'TivoLivingRoom_RemoteControlButton', 'PAUSE', '', '--f7-color-yellow-tint', '--f7-color-black']
              - [2, 10, 1, 1, 'Fast Forward', false, 'f7', 'forward_fill', true, 'TivoLivingRoom_RemoteControlButton', 'FORWARD', '', '--f7-color-gray-tint', '--f7-color-white']
              - [3, 9, 1, 1, 'Stop', false, 'f7', 'stop_fill', true, 'TivoLivingRoom_RemoteControlButton', 'STOP', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 7, 1, 1, 'Skip back', false, 'f7', 'backward_end_fill', true, 'TivoLivingRoom_RemoteControlButton', 'REPLAY', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 8, 1, 1, 'Slow motion', false, 'material', 'slow_motion_video', true, 'TivoLivingRoom_RemoteControlButton', 'SLOW', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 9, 1, 2, 'Search', false, 'material', 'search', true, 'TivoLivingRoom_RemoteControlButton', 'SEARCH', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 11, 1, 1, 'Skip forward', false, 'f7', 'forward_end_fill', true, 'TivoLivingRoom_RemoteControlButton', 'ADVANCE', '', '--f7-color-gray-tint', '--f7-color-white']
              - [5, 7, 1, 2, 'Red', false, 'f7', 'square_fill', true, 'TivoLivingRoom_RemoteControlButton', 'ACTION_A', '', '--f7-color-red-shade', '--f7-color-black']
              - [5, 9, 1, 1, 'Green', false, 'f7', 'square_fill', true, 'TivoLivingRoom_RemoteControlButton', 'ACTION_B', '', '--f7-color-green-shade', '--f7-color-black']
              - [5, 10, 1, 1, 'Yellow', false, 'f7', 'square_fill', true, 'TivoLivingRoom_RemoteControlButton', 'ACTION_C', '', '--f7-color-yellow-tint', '--f7-color-black']
              - [5, 11, 1, 1, 'Blue', false, 'f7', 'square_fill', true, 'TivoLivingRoom_RemoteControlButton', 'ACTION_D', '', '--f7-color-blue-shade', '--f7-color-black']
              - [2, 13, 1, 1, '1', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM1', '', '--f7-color-gray-tint', '--f7-color-white']
              - [2, 14, 1, 1, '2', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM2', '', '--f7-color-gray-tint', '--f7-color-white']
              - [2, 15, 1, 1, '3', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM3', '', '--f7-color-gray-tint', '--f7-color-white']
              - [3, 13, 1, 1, '4', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM4', '', '--f7-color-gray-tint', '--f7-color-white']
              - [3, 14, 1, 1, '5', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM5', '', '--f7-color-gray-tint', '--f7-color-white']
              - [3, 15, 1, 1, '6', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM6', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 13, 1, 1, '7', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM7', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 14, 1, 1, '8', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM8', '', '--f7-color-gray-tint', '--f7-color-white']
              - [4, 15, 1, 1, '9', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'MUM9', '', '--f7-color-gray-tint', '--f7-color-white']
              - [5, 13, 1, 1, 'Clear', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'CLEAR', '', '--f7-color-gray-tint', '--f7-color-white']
              - [5, 14, 1, 1, '0', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', 'NUM0', '', '--f7-color-gray-tint', '--f7-color-white']
              - [5, 15, 1, 1, 'Last Ch', true, '', '', false, 'TivoLivingRoom_KeyboardCommand', '', '', '--f7-color-gray-tint', '--f7-color-white']
              - [7, 7, 1, 1, 'YouTube', true, '', '', false, '', '', 'Tivo_YouTube', '--f7-color-blue-tint', '--f7-color-white']
              - [7, 8, 1, 1, 'Netflix', true, '', '', false, '', '', 'Tivo_Netflix', '--f7-color-blue-tint', '--f7-color-white']
              - [7, 9, 1, 1, 'Amazon Prime', true, '', '', false, '', '', 'Tivo_Prime', '--f7-color-blue-tint', '--f7-color-white']
              - [7, 10, 1, 1, 'BBC News', true, '', '', false, '', '', 'Tivo_BBC', '--f7-color-blue-tint', '--f7-color-white']
              - [7, 11, 1, 1, 'LBC Radio', true, '', '', false, '', '', 'Tivo_LBC', '--f7-color-blue-tint', '--f7-color-white']
              fragment: true
            slots:
              default:
                - component: oh-button
                  config:
                    visible: "=(loop.i[5] || loop.i[8]) ? true : false"
                    action: command
                    actionItem: =loop.i[9]
                    actionCommand: =loop.i[10]
                    class: ob
                    style:
                      display: inline-flex
                      align-items: center
                      grid-row-start: =loop.i[0]
                      grid-row-end: ='span ' + loop.i[2]
                      grid-column-start: =loop.i[1]
                      grid-column-end: ='span ' + loop.i[3]
                      justify-self: stretch
                      height: 100%
                      --f7-button-bg-color: "=(loop.i[12] === undefined || loop.i[12] === '' ? 'var(--bg-color-primary)' : (loop.i[12].substring(0,2) === '--' ? 'var(' + loop.i[12] + ')' : loop.i[12]))"
                      --f7-button-hover-bg-color: var(--f7-color-white-shade)
                  slots:
                    default:
                      - component: f7-icon
                        config:
                          visible: =loop.i[8]
                          f7: '=(loop.i[6] === "f7") ? loop.i[7] : ""'
                          material: '=(loop.i[6] === "material") ? loop.i[7] : ""'
                          size: 20px
                          style:
                            color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                      - component: Label
                        config:
                          visible: =loop.i[5]
                          text: =loop.i[4]
                          style:
                            font-size: 14px
                            color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                            white-space: normal
                            margin: 2px

Note: I know this is is JSON array format, it works but when you save / exit / re-enter the widget, it will have been converted to YAML array format. You can still copy / paste / replace the YAML with updated JSON data from the spreadsheet, but it to will convert when you save / leave your current editing session.

3 Likes

Awesome work with the widget and the writeup @AndyMB,

I really like your solution with the JSON arrays as the data-source (and might reuse parts of this for future widgets :stuck_out_tongue:).

Thank you!

1 Like

Glad you managed to do it @AndyMB - it looks great!

Not much we can do here, but maybe you should have opted for an array of objects instead of an array of arrays.
Something like:

for: i
in:
  - row: 1
    column: 1
    span_row: 1
    span_column: 1
    label: Standby
    ...
  - row: 1
    column: 2
    ...

A little more verbose but then your loop.i[2] become loop.i.span_column which is a little clearer IMO. And it will stay like that (note that you can use the JSON syntax on a single line to define an object in YAML i.e. { "row": "1", ... } but it will get transformed too).

LOL, I tried exactly that for about an hour as named attributes make the code more readable, but couldn’t work out the right syntax… So reverted to the array format that I used in the multifunction widget.

My comment on the format was really just to highlight that the code in the post will look different once converted to the native YAML structure. It freaked me out the first time it happened to me :laughing:

Problem:
BoGoB buttons works great on laptop screens, but is unusable on mobile phone devices because most of the buttons are rendered outside the viewable screen area and there are no scroll bars.

Version 2:

  • Split single grid of buttons into 3 separate grids.
  • Implemented flexbox container to host the three grids.
  • Each grid is displayed in a row (as before) where screen space allows all grids to be rendered. When a grid cannot fit in the remaining screen space, it is rendered as a second row. In practice on a mobile phone the grids appear to be in a column and are all usable.
  • Fixed a couple of incorrectly coded buttons.
  • Improved text alignment in buttons (vertical centred text) / minor styling tweaks.
  • Added a TiVo status reporting label (above keypad) which displays the latest message returned (in the example, channel status 601). This is a simple example of adding additional “non button” controls to a grid object.

Result:
Large screen:

Small screen:

BTW, anyone wanting to give the TiVo binding a go can find it in the latest snapshot builds of openHAB.

If anyone has adapted this widget for their own “Big Ol’ Grid O’ Buttons”, it would be great to see a screenshot or two :grinning:

YAML below:

uid: BoGoB
tags: []
props:
  parameters:
    - description: Set card header title. Only displays if populated.
      label: Card Title
      name: title
      required: false
      type: TEXT
      groupName: general
    - context: color
      description: Specify the background color for card. Any valid <a class="link external" href="https://www.w3schools.com/css/css_colors.asp" target="_blank">HTML color format (RGB/RGBA/HEX/HSL)</a> or <a class="link external" href="https://framework7.io/docs/css-variables.html" target="_blank">CSS theme</a> color. e.g. rgb(255,255,255), --f7-color-white. <b>Default = --f7-color-white</b>
      label: Background color
      name: backgroundColor
      required: false
      type: TEXT
      groupName: general
    - description: Set the width of a grid unit button. <b>You must include the CSS units e.g. px,em,rem etc.</b> Objects that span multiple grid containers will stretch to fill the container. Default 4rem.
      label: Button Width
      name: buttWidth
      required: true
      type: TEXT
      groupName: grid
    - description: Set the height of a grid unit button. <b>You must include the CSS units e.g. px,em,rem etc.</b> Objects that span multiple grid containers will stretch to fill the container. Default 3rem.
      label: Button Height
      name: buttHeight
      required: true
      type: TEXT
      groupName: grid
  parameterGroups:
    - name: grid
      label: Grid setup
    - name: general
      label: Display options
timestamp: Feb 3, 2021, 10:06:04 PM
component: f7-card
config:
  title: =props.title
  style:
    background-image: ='url(' + props.backgroundUrl + ')'
    backdrop-filter: ='blur(' + props.backgroundBlur + 'px)'
    background-size: contain
    background-repeat: no-repeat
    background-position: 100% 100%
    background-color: '=(props.backgroundColor === undefined ? "var(--f7-color-white)" : (props.backgroundColor.substring(0,2) === "--" ? "var(props.backgroundColor)" : props.backgroundColor))'
    border-radius: 5px
    overflow: hidden
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
slots:
  default:
    - component: f7-block
      config:
        style:
          padding-left: 0px
          padding-top: 10px
          padding-bottom: 10px
          display: flex
          flex-direction: row
          flex-wrap: wrap
      slots:
        default:
          - component: f7-block
            config:
              class: bog
              style:
                display: grid
                grid-auto-columns: '=(props.buttWidth === undefined) ? "4rem" : props.buttWidth'
                grid-auto-rows: '=(props.buttHeight === undefined) ? "3rem" : props.buttHeight'
                grid-gap: 6px 6px
                align-items: flex-start
                justify-content: start
                margin-top: 0px
                padding-top: 10px
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: unset
                    for: i
                    in:
                      - - 1
                        - 1
                        - 1
                        - 1
                        - Standby
                        - false
                        - f7
                        - power
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - STANDBY
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-green
                      - - 1
                        - 2
                        - 1
                        - 3
                        - Home
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_ChangeMenuScreen
                        - TIVO
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 1
                        - 5
                        - 1
                        - 1
                        - TV
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_ChangeMenuScreen
                        - LIVETV
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 2
                        - 2
                        - 1
                        - 3
                        - Guide
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_ChangeMenuScreen
                        - GUIDE
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 2
                        - 5
                        - 1
                        - 1
                        - Info
                        - true
                        - f7
                        - info_circle
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - INFO
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 3
                        - 3
                        - 1
                        - 1
                        - Up
                        - false
                        - f7
                        - arrowtriangle_up_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - UP
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 3
                        - 5
                        - 1
                        - 1
                        - Subs On
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - CC_ON
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 5
                        - 1
                        - 1
                        - Subs Off
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - CC_OFF
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 1
                        - 1
                        - 1
                        - Back
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - EXIT
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 2
                        - 1
                        - 1
                        - Left
                        - false
                        - f7
                        - arrowtriangle_left_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - LEFT
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 4
                        - 3
                        - 1
                        - 1
                        - OK
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - SELECT
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 4
                        - 4
                        - 1
                        - 1
                        - Right
                        - false
                        - f7
                        - arrowtriangle_right_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - RIGHT
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 5
                        - 1
                        - 1
                        - 1
                        - Vol +
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - VOLUMEUP
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 5
                        - 3
                        - 1
                        - 1
                        - Down
                        - false
                        - f7
                        - arrowtriangle_down_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - DOWN
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 5
                        - 5
                        - 1
                        - 1
                        - Ch +
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - CHANNELUP
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 6
                        - 1
                        - 1
                        - 1
                        - Vol -
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - VOLUMEDOWN
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 6
                        - 2
                        - 1
                        - 3
                        - My Shows
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - NOWPLAYING
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 6
                        - 5
                        - 1
                        - 1
                        - Ch -
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - CHANNELDOWN
                        - ""
                        - --f7-color-gray-shade
                        - --f7-color-white
                      - - 7
                        - 1
                        - 1
                        - 1
                        - Thumb Down
                        - false
                        - f7
                        - hand_thumbsdown_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - THUMBSDOWN
                        - ""
                        - --f7-color-red-shade
                        - --f7-color-white
                      - - 7
                        - 2
                        - 1
                        - 1
                        - Mute
                        - true
                        - material
                        - volumne_off
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - MUTE
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 7
                        - 3
                        - 1
                        - 2
                        - Record
                        - false
                        - f7
                        - recordingtape
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - RECORD
                        - ""
                        - --f7-color-red-shade
                        - --f7-color-white
                      - - 7
                        - 5
                        - 1
                        - 1
                        - Thumbs Up
                        - false
                        - f7
                        - hand_thumbsup_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - THUMBSUP
                        - ""
                        - --f7-color-green-shade
                        - --f7-color-white
                    fragment: true
                  slots:
                    default:
                      - component: oh-button
                        config:
                          visible: "=(loop.i[5] || loop.i[8]) ? true : false"
                          action: command
                          actionItem: =loop.i[9]
                          actionCommand: =loop.i[10]
                          class: ob
                          style:
                            display: inline-flex
                            grid-row-start: =loop.i[0]
                            grid-row-end: ='span ' + loop.i[2]
                            grid-column-start: =loop.i[1]
                            grid-column-end: ='span ' + loop.i[3]
                            justify-self: stretch
                            height: 100%
                            --f7-button-bg-color: "=(loop.i[12] === undefined || loop.i[12] === '' ? 'var(--bg-color-primary)' : (loop.i[12].substring(0,2) === '--' ? 'var(' + loop.i[12] + ')' : loop.i[12]))"
                            --f7-button-hover-bg-color: var(--f7-color-white-shade)
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: =loop.i[8]
                                f7: '=(loop.i[6] === "f7") ? loop.i[7] : ""'
                                material: '=(loop.i[6] === "material") ? loop.i[7] : ""'
                                size: 20px
                                style:
                                  color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                            - component: Label
                              config:
                                visible: =loop.i[5]
                                text: =loop.i[4]
                                style:
                                  color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                                  white-space: normal
                                  line-height: normal
                                  margin: 2px
          - component: f7-block
            config:
              class: bog
              style:
                padding-top: 10px
                display: grid
                grid-auto-columns: '=(props.buttWidth === undefined) ? "4rem" : props.buttWidth'
                grid-auto-rows: '=(props.buttHeight === undefined) ? "3rem" : props.buttHeight'
                grid-gap: 6px 6px
                align-items: flex-start
                justify-content: start
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: unset
                    for: i
                    in:
                      - - 1
                        - 3
                        - 1
                        - 1
                        - Play
                        - false
                        - f7
                        - play_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - PLAY
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 2
                        - 2
                        - 1
                        - 1
                        - Rewind
                        - false
                        - f7
                        - backward_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - REVERSE
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 2
                        - 3
                        - 1
                        - 1
                        - Pause
                        - false
                        - f7
                        - pause_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - PAUSE
                        - ""
                        - --f7-color-yellow-tint
                        - --f7-color-black
                      - - 2
                        - 4
                        - 1
                        - 1
                        - Fast Forward
                        - false
                        - f7
                        - forward_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - FORWARD
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 3
                        - 3
                        - 1
                        - 1
                        - Stop
                        - false
                        - f7
                        - stop_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - STOP
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 1
                        - 1
                        - 1
                        - Skip back
                        - false
                        - f7
                        - backward_end_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - REPLAY
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 2
                        - 1
                        - 1
                        - Slow motion
                        - false
                        - material
                        - slow_motion_video
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - SLOW
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 3
                        - 1
                        - 2
                        - Search
                        - false
                        - material
                        - search
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - SEARCH
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 5
                        - 1
                        - 1
                        - Skip forward
                        - false
                        - f7
                        - forward_end_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - ADVANCE
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 5
                        - 1
                        - 1
                        - 2
                        - Red
                        - false
                        - f7
                        - square_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - ACTION_A
                        - ""
                        - --f7-color-red-shade
                        - --f7-color-black
                      - - 5
                        - 3
                        - 1
                        - 1
                        - Green
                        - false
                        - f7
                        - square_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - ACTION_B
                        - ""
                        - --f7-color-green-shade
                        - --f7-color-black
                      - - 5
                        - 4
                        - 1
                        - 1
                        - Yellow
                        - false
                        - f7
                        - square_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - ACTION_C
                        - ""
                        - --f7-color-yellow-tint
                        - --f7-color-black
                      - - 5
                        - 5
                        - 1
                        - 1
                        - Blue
                        - false
                        - f7
                        - square_fill
                        - true
                        - TivoLivingRoom_RemoteControlButton
                        - ACTION_D
                        - ""
                        - --f7-color-blue-shade
                        - --f7-color-black
                      - - 6
                        - 1
                        - 1
                        - 1
                        - YouTube
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_CurrentChannelRequest
                        - "198"
                        - Tivo_YouTube
                        - --f7-color-blue-tint
                        - --f7-color-white
                      - - 6
                        - 2
                        - 1
                        - 1
                        - Netflix
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - NETFLIX
                        - Tivo_Netflix
                        - --f7-color-blue-tint
                        - --f7-color-white
                      - - 6
                        - 3
                        - 1
                        - 1
                        - Amazon Prime
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_CurrentChannelRequest
                        - "205"
                        - Tivo_Prime
                        - --f7-color-blue-tint
                        - --f7-color-white
                      - - 6
                        - 4
                        - 1
                        - 1
                        - BBC News
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_CurrentChannelRequest
                        - "601"
                        - Tivo_BBC
                        - --f7-color-blue-tint
                        - --f7-color-white
                      - - 6
                        - 5
                        - 1
                        - 1
                        - LBC Radio
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_CurrentChannelRequest
                        - "919"
                        - Tivo_LBC
                        - --f7-color-blue-tint
                        - --f7-color-white
                    fragment: true
                  slots:
                    default:
                      - component: oh-button
                        config:
                          visible: "=(loop.i[5] || loop.i[8]) ? true : false"
                          action: command
                          actionItem: =loop.i[9]
                          actionCommand: =loop.i[10]
                          class: ob
                          style:
                            display: inline-flex
                            align-items: center
                            grid-row-start: =loop.i[0]
                            grid-row-end: ='span ' + loop.i[2]
                            grid-column-start: =loop.i[1]
                            grid-column-end: ='span ' + loop.i[3]
                            justify-self: stretch
                            height: 100%
                            --f7-button-bg-color: "=(loop.i[12] === undefined || loop.i[12] === '' ? 'var(--bg-color-primary)' : (loop.i[12].substring(0,2) === '--' ? 'var(' + loop.i[12] + ')' : loop.i[12]))"
                            --f7-button-hover-bg-color: var(--f7-color-white-shade)
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: =loop.i[8]
                                f7: '=(loop.i[6] === "f7") ? loop.i[7] : ""'
                                material: '=(loop.i[6] === "material") ? loop.i[7] : ""'
                                size: 20px
                                style:
                                  color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                            - component: Label
                              config:
                                visible: =loop.i[5]
                                text: =loop.i[4]
                                style:
                                  color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                                  white-space: normal
                                  line-height: normal
                                  margin: 2px
          - component: f7-block
            config:
              class: bog
              style:
                padding-top: 10px
                display: grid
                grid-auto-columns: '=(props.buttWidth === undefined) ? "4rem" : props.buttWidth'
                grid-auto-rows: '=(props.buttHeight === undefined) ? "3rem" : props.buttHeight'
                grid-gap: 6px 6px
                align-items: flex-start
                justify-content: center
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: unset
                    for: i
                    in:
                      - - 2
                        - 1
                        - 1
                        - 1
                        - "1"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM1
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 2
                        - 2
                        - 1
                        - 1
                        - "2"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM2
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 2
                        - 3
                        - 1
                        - 1
                        - "3"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM3
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 3
                        - 1
                        - 1
                        - 1
                        - "4"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM4
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 3
                        - 2
                        - 1
                        - 1
                        - "5"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM5
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 3
                        - 3
                        - 1
                        - 1
                        - "6"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM6
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 1
                        - 1
                        - 1
                        - "7"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM7
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 2
                        - 1
                        - 1
                        - "8"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM8
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 4
                        - 3
                        - 1
                        - 1
                        - "9"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - MUM9
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 5
                        - 1
                        - 1
                        - 1
                        - Clear
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - CLEAR
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 5
                        - 2
                        - 1
                        - 1
                        - "0"
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - NUM0
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 5
                        - 3
                        - 1
                        - 1
                        - Last Ch
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_KeyboardCommand
                        - ""
                        - ""
                        - --f7-color-gray-tint
                        - --f7-color-white
                      - - 6
                        - 3
                        - 1
                        - 1
                        - Find Remote
                        - true
                        - ""
                        - ""
                        - false
                        - TivoLivingRoom_RemoteControlButton
                        - FIND_REMOTE
                        - ""
                        - --f7-color-blue-tint
                        - --f7-color-white
                    fragment: true
                  slots:
                    default:
                      - component: oh-button
                        config:
                          visible: "=(loop.i[5] || loop.i[8]) ? true : false"
                          action: command
                          actionItem: =loop.i[9]
                          actionCommand: =loop.i[10]
                          class: ob
                          style:
                            display: inline-flex
                            align-items: center
                            grid-row-start: =loop.i[0]
                            grid-row-end: ='span ' + loop.i[2]
                            grid-column-start: =loop.i[1]
                            grid-column-end: ='span ' + loop.i[3]
                            justify-self: stretch
                            height: 100%
                            --f7-button-bg-color: "=(loop.i[12] === undefined || loop.i[12] === '' ? 'var(--bg-color-primary)' : (loop.i[12].substring(0,2) === '--' ? 'var(' + loop.i[12] + ')' : loop.i[12]))"
                            --f7-button-hover-bg-color: var(--f7-color-white-shade)
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: =loop.i[8]
                                f7: '=(loop.i[6] === "f7") ? loop.i[7] : ""'
                                material: '=(loop.i[6] === "material") ? loop.i[7] : ""'
                                size: 20px
                                style:
                                  color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                            - component: Label
                              config:
                                visible: =loop.i[5]
                                text: =loop.i[4]
                                style:
                                  color: "=(loop.i[13] === undefined || loop.i[13] === '' ? 'var(--text-color-primary)' : (loop.i[13].substring(0,2) === '--' ? 'var(' + loop.i[13] + ')' : loop.i[13]))"
                                  white-space: normal
                                  line-height: normal
                                  margin: 2px
                - component: f7-block
                  config:
                    style:
                      display: inline-flex
                      align-items: center
                      grid-row-start: 1
                      grid-row-end: span 1
                      grid-column-start: 1
                      grid-column-end: span 3
                  slots:
                    default:
                      - component: Label
                        config:
                          visible: =loop.i[5]
                          text: =items.TivoLivingRoom_TiVoStatus.state


2 Likes

You can make fancy widgets like this one so the buttons don’t look plain. Search forum for oh 3 harmony widget if you want the code.

2 Likes

@matt1 - thanks for your work on whipping up this Harmony OH3 widget. I used your Widget as the starting point for a new design of a Universal Remote here:

@AndyMB - I am looking forward to borrowing some of your code to make a pin pad popover possible on the Universal Remote, too!