Action on oh-icon not working

When I want a button to open another window or do something else, I always use oh-button, but this element doesn’t support Iconify (yet). that’s why I was looking at oh-icon, but I don’t get my actions to work, actually, nothing happens at all. I’m runnning OH 3.3

Working action with oh-button:

- component: oh-button
            config:
              iconF7: gear_alt_fill
              color: gray
              iconSize: 18
              action: popup
              actionModal: widget:onkyo
              actionModalConfig:
                itemPrefix: Onkyo

Not working with oh-icon:

- component: oh-icon
            config:
              icon: iconify:mdi:television-ambient-light
              width: 20px
              color: gray
              action: popup
              actionModal: widget:onkyo
              actionModalConfig:
                itemPrefix: Onkyo

Did you solve this.
I have the same problem.

I use a “workaround” for oh-chart component (see Include graphic in custom echarts gauge widget - #2 by crnjan), cannot try it out if below works too since I’m not at home, but maybe something like:

- component: f7-block
  config:
    class:
      - no-margin
  slots:
    default:
      - component: oh-link
        config:
          style:
            position: absolute
            width: 100%
            height: 100%
          actionModal: widget:onkyo
          actionModalConfig:
            itemPrefix: Onkyo
      - component: oh-icon
        config:
               ...

I can confirm the following works

tapping on icon will display

My problem is that i have three different icons with different actions on the card.

Actions on an oh-icon work if the icon has been defined with one of the oh specific icons. F7 and iconify icons at present do not register actions. I don’t know if this is a technical limitation, or an oversight. If you wish to see it addressed you can post an issue on the web repo.

In the meantime, the solution is the oh-link. Anywhere you have an oh-icon you should be able to substitute an oh-link with the action configurations and then add the oh-icon in the link’s default slot.

- component: oh-link
  config:
    action: ...
  slots:
    default:
      - component: oh-icon
        config:
          icon: iconify:...
3 Likes

Perfect.

I just stumbled across this problem as well but I can’t get the proposed workaround to work. Could this be a regression in OH4.0.2 or am I doing something wrong?

I always get the following exception in the openhab.log when I click the link (clicking the OH-toggle below works just fine for the same item):

2023-08-27 15:12:05.515 [ERROR] [rg.apache.cxf.jaxrs.utils.JAXRSUtils] - No message body reader has been found for class java.lang.String, ContentType: application/octet-stream
2023-08-27 15:12:05.517 [WARN ] [s.impl.WebApplicationExceptionMapper] - javax.ws.rs.WebApplicationException: HTTP 415 Unsupported Media Type
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1473)
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.processRequestBodyParameter(JAXRSUtils.java:950)
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:881)
	at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:215)
	at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:79)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265)
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225)
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298)
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:517)
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273)
	at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedServlet.service(OsgiInitializedServlet.java:102)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656)
	at org.ops4j.pax.web.service.spi.servlet.OsgiFilterChain.doFilter(OsgiFilterChain.java:100)
	at org.ops4j.pax.web.service.jetty.internal.PaxWebServletHandler.doHandle(PaxWebServletHandler.java:310)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234)
	at org.ops4j.pax.web.service.jetty.internal.PrioritizedHandlerCollection.handle(PrioritizedHandlerCollection.java:96)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:722)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.base/java.lang.Thread.run(Thread.java:833)

I have the following code. It is from my universal toggle widget, I try to make the icon clickable as well:

First the excerpt with the change I just did (replaced a simple f7-icon with the oh-link/f7-icon combination):

                            - component: oh-link
                              config:
                                action: toggle
                                actionItem: =props.maintoggle
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      color: '=items[props.maintoggle].state == "ON" ? props.color : items[props.maintoggle].state > 0 ? props.color : "gray"'
                                      f7: =props.icon
                                      size: '=(props.grouptogglearray) ? "100" : "120"'
                            - component: oh-toggle
                              config:
                                colorTheme: =props.color
                                item: =props.maintoggle
                            - component: f7-block
                              config:
                                style:
                                  display: '=(props.grouptogglearray) ? "block" : "none"'
                                  height: 35px

Here the full example that can be copied & pasted:

uid: universal_toggle_v3
tags: []
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: The card footer
      label: Footer
      name: footer
      required: false
      type: TEXT
    - description: Name of the Icon (see https://framework7.io/icons/ for available icons)
      label: F7 Icon
      name: icon
      required: true
      type: TEXT
    - description: Color scheme for icons and toggles (see https://framework7.io/docs/color-themes.html for available color schemes)
      label: Color
      name: color
      required: true
      type: TEXT
    - context: item
      description: Main toggle item (use for single toggle or as main switch for group)
      label: Item
      name: maintoggle
      required: false
      type: TEXT
    - description: Group toggles (use as group with or without main toggle)
      label: Group toggle Array
      name: grouptogglearray
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Aug 27, 2023, 3:05:01 PM
component: f7-card
config:
  title: =(props.title)
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-swiper
            config:
              init: true
              pagination: "=(props.maintoggle) && (props.grouptogglearray) ? true : false"
              params:
                pagination:
                  clickable: true
                slidesPerView: 1
              style:
                height: 175px
                width: 100%
            slots:
              default:
                - component: f7-swiper-slide
                  config:
                    style:
                      height: 100%
                      width: 100%
                    visible: "=(props.maintoggle) ? true : false"
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - display-flex
                            - flex-direction-column
                            - align-items-center
                            - justify-content-space-evenly
                          style:
                            height: 100%
                            width: 100%
                        slots:
                          default:
                            - component: oh-link
                              config:
                                action: toggle
                                actionItem: =props.maintoggle
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      color: '=items[props.maintoggle].state == "ON" ? props.color : items[props.maintoggle].state > 0 ? props.color : "gray"'
                                      f7: =props.icon
                                      size: '=(props.grouptogglearray) ? "100" : "120"'
                            - component: oh-toggle
                              config:
                                colorTheme: =props.color
                                item: =props.maintoggle
                            - component: f7-block
                              config:
                                style:
                                  display: '=(props.grouptogglearray) ? "block" : "none"'
                                  height: 35px
                - component: f7-swiper-slide
                  config:
                    visible: "=(props.grouptogglearray) ? true : false"
                  slots:
                    default:
                      - component: f7-swiper
                        config:
                          params:
                            direction: vertical
                            mousewheel: true
                            scrollbar:
                              hide: true
                            slidesPerView: 1
                          scrollbar: true
                          style:
                            height: 100%
                            width: 100%
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: item
                                fragment: true
                                in: =props.grouptogglearray.split("|")
                              slots:
                                default:
                                  - component: f7-swiper-slide
                                    config:
                                      style:
                                        height: 100%
                                        width: 100%
                                    slots:
                                      default:
                                        - component: f7-col
                                          config:
                                            class:
                                              - display-flex
                                              - flex-direction-column
                                              - align-items-center
                                              - justify-content-space-evenly
                                            style:
                                              height: 100%
                                              width: 100%
                                          slots:
                                            default:
                                              - component: f7-block-title
                                                config:
                                                  style:
                                                    margin-bottom: -2px
                                                    margin-top: 10px
                                                slots:
                                                  default:
                                                    - component: Label
                                                      config:
                                                        text: =loop.item.split("\"")[1]
                                              - component: f7-icon
                                                config:
                                                  color: '=items[loop.item.split("\"")[3]].state == "ON" ? props.color : "gray"'
                                                  f7: =props.icon
                                                  size: 70
                                              - component: oh-toggle
                                                config:
                                                  colorTheme: =props.color
                                                  item: =(loop.item.split("\"")[3])
                                              - component: f7-block
                                                config:
                                                  style:
                                                    display: '=(props.maintoggle) ? "block" : "none"'
                                                    height: 35px
    - component: f7-card-footer
      slots:
        default:
          - component: Label
            config:
              text: =props.footer

The toggle action does not have any default commands to send. It also requires you to set the actionCommand and actionCommandAlt properties.

- component: oh-link
  config:
    action: toggle
    actionItem: =props.maintoggle
    actionCommand: ON
    actionCommandAlt: OFF

Thanks a lot JustinG! This makes sense… :slight_smile: Works perfectly, too :slight_smile: