I now want an analyzer popup item for the icon area, but have no clue how to… The svg component itself ignores action: analyzer. And adding any oh- or f7- elements breaks the layout. Any help greatly appreciated!
BTW: The original widget used svg files for icon elements. I converted that to be fully self contained and do some trickery with dynamic changes like a rotating heatpump vent and a fading sun.
Correct. Only oh- components accept the action configurations.
Without seeing the full configuration you’re working with, it’s hard to say what the best way to do this would be. From the snippet you’ve provided it looks like the best option is to just put that svg icon inside an oh-link:
- component: oh-link
config:
action: analyzer
...rest of config
slots:
default:
- component: svg
...rest of svg
Another good option, depending on the rest of the structure might be to take advantage of SVG’s foreignObject element:
Full widget code is in the above linked GIT repo Didn’t want to post it here because it only helps readers who are willing to dive into it a bit.
If I add an oh-link, how would this component know where it is? I have no grid/rows/cols, it’s all a single f7-block with a viewbox. The only elements that have any “coordinates” are the SVG ones, and the SVG element in the excerpt above doesn’t even have a parent with coordinates. It is simply placed in the center of its surrounding element by viewbox positioning in the f7-block.
You are correct, the basic oh-link option only works by placing the entire SVG inside the link (with placement being determined by whatever determined the placement of the SVG in the first place). I see now that you are asking about sub SVG elements, in which case the foreignObject method mentioned above is the only best way for you to go.
The foreignObject element is just like any other svg element in that it takes the x, y, height, and width attributes for placement. It is unlike other SVG elements in that it essentially becomes a new region for you to put any html inside your SVG. In this case, that native html would be an oh-link. Because an oh-link can hold any other component you can then but your full SVG block for an icon in the oh-link and then the link encompass the entire icon.
For the example you posted of the sub SVG for your inverter icon. The position and size attributes that determine where the icon is should now, instead determine where the ‘foreignObject’ goes.
Then you put the svg icon elements inside the oh-link, setting the SVG size to just fill the container 100% (which is the oh-link and then by extension the foreignObject which has the size and position that you want).
Works like a charm - thank you sooo much! At least in the browser interface.
In the iOS app, the layout goes nuts. In portrait mode, the oh-link/icon are invisible (behind some other element, I assume). In landscape mode, they become visible but are positioned wrong.
Layout in browser, mouse on the heatpump icon so it gets dimmed a bit, popover working:
Opened the browser interface in Safari on iOS - same symptom in both portrait and landscape. So it might be a safari rendering issue, but beyond my capabilities in diagnosing further.
I know that there are some well-known Safari SVG rendering issues, but I do not know the complete list as I do not work with Safari if it can be avoided. According to the doc link above, foreignObject should have full Safari support on both desktop and iOS.
On the desktop Safari you have a chance. On my troubleshooting tutorial, I go over some browser tools that help you know check out what’s wrong with widgets. In this case the first thing to find out is whether the icon is 1) not being rendered, 2) being rendered in the wrong place, or 3) being rendered at the wrong size. My gut feeling, based on other Safari SVG issues and what you show above, is that this is an instance of #2. Once you can narrow it down to one of those three options it’s usually fixable.
Looking at the html (dev tools) doesn’t provide me any insight, and I don’t have a desktop safari available (all desktops running windows, and safari isn’t available for this OS anymore). Stuck now, dead end (my wife will not accept this weird looking widget… WAF broken.)
There are a few suggestions on that page. For example, you can try adding
style:
position: fixed
to the oh-link and see if that helps.
If none of the workarounds for this bug still work, then you can resort to the other option. This is more of a hack than a native OH widget action but you can use javascript to access the function of the on-link. I don’t think there are any Safari shenanigans that negate this option…but, you never know.
So, for this you would get rid of the foreignObject and the oh-link in the middle and restore your SVG to its original arrangement. Then you would put the oh-link by itself somewhere outside of the SVG, for example, as a child of the f7-block. The trick is to make sure you set the display: none style on this link and give the link a unique ID:
- component: f7-block
config:
style:
content-justify: center
display: flex
height: 100%
padding: 5%
width: 100%
slots:
default:
- component: oh-link
config:
id: heat-pump-analyzer
action: analyzer
actionAnalyzerItems: YOUR ITEM NAME(S) HERE
style:
display: none
- component: svg
...rest of SVG
Note: the SVG is a sibling of the link, not a child.
Now, inline SVG elements will accept event attributes so to your heat pump icon svg, you can just add
Turns out we both missed the correct - and easy - way to do it… I am not too familiar with the widget object model nor with svg, and you maybe simply overlooked it.
- component: svg
config:
comment: heatpump icon area
height: 44px
width: 44px
x: 428px
y: 228px
slots:
default:
- component: oh-link
config:
action: group
actionGroupPopupItem: =props.popup_heatpump
slots:
default:
- component: svg
config:
comment: heatpump icon
fill: =fn.switch_color(#props.power_heatpump, "heatpump")
height: 100%
viewBox: 0 0 490 490
width: 100%
slots:
default:
- component: rect
config:
comment: invisible rectangle to provide a clickable area for oh-link
height: 100%
width: 100%
opacity: 0
The svg component accepts a oh-link child. My fault in the first place was that I then made the icon a sibling of oh-link and not a child in its default slot… (move the svg icon component 3 indents to the left, then the icon vanishes behind the oh-link). Only trick here is to add an invisible rect to the icon to react to the oh-link - otherwise, only “filled” svg components are clickable.
Anyway, talking to you finally got me to a solution, it works like a charm now
You’re right, I didn’t think that would work in this case for reasons that were clearly incorrect. I’m glad you tried it and proved me wrong! Now I know.
Purely by accident… Was in the progress to try the javascript variant, changed the foreignObject back to SVG. Then - dunno why - saved, reloaded and smiled