Actions for different parts of a button card #1145
lisz8
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'd like to share some methods to trigger separate actions for different parts of the awesome button card (currently it allows a separate action only for the icon).
Basic idea
The basic idea of the first method is to retrieve a list of HTML elements "under the pointer", and based on this, decide what action to run. Let's say you want separate tap actions for the
statefield and the custom field namedmy_room, and no action for other parts of the button. Then all you have to do is this:To reuse this example, only the ACTIONS object needs to be changed. It will also work for hold_action, etc.
Advanced template
I created an "advanced" template that covers all types of button actions: tap, hold, double tap, press and release. It supports overlapping elements (e.g. you can have a separate actions for a custom field and elements contained in that field). You can define actions in an (almost) normal way: create them as variables. The pattern looks like this:
key1, key2, etc. are the identifiers of the elements that should trigger the action. These may include custom field names or 'name', 'state', 'label', and others. The key can be overridden by an optional
element_actions_id, and then it can become a descriptive/friendly name of the action.default_actionkey denotes the default action of a given type (tap/hold/etc.). By default it's set to no action.element_actions_priorityis the second optional entry: specifies what action to execute when elements overlap (default priority is 0, and a higher value wins).The action itself is defined in a normal way. You can use any kind of action (more-info, toggle, perform-action, navigate, url, assist, none). You can even use javascript to define actions for this template, but first make sure to read the hidden paragraph below.
Using javascript for actions definition
There could be some edge cases, so take this informations with a grain of salt.
The code enclosed in three square brackets
[[[ ]]]will be executed only once, during the button card initialization. This is very different from normal behavior, as it doesn't re-execute when the card is updated. You can restore the standard behavior by settingvariables.element_actions_volatile: true. It is so because I cache the action definitions, as they usually do not change.Code enclosed in four square brackets
[[[[ ]]]]will be executed only when actions are performed. But note the difference between calculating a value for a field and executing the code as an action E.g. both of the following code snippets will be executed on every tap_action:To run javascript as an action, use the
javascript actionthat is specifically designed for this purpose. This time, each piece of code will only be executed when an action is performed for a specific element (some_keyoranother_key):This also works:
The following code will never run because the key
made_up_nameis not expected in the context ofmore-info.Code enclosed in 4 brackets is not affected by
element_actions_volatile: true.--- end of "Using javascript for actions definition"
Press/release and tap/hold/double tap actions are mutually exclusive.
element_actions_control_rippleis a "global" variable that can be set totrue. In this case, the template will disable the hover effect for the card (by setting--button-card-ripple-hover-opacityto 0), and the press effect will only be visible if an actual action other than none is defined for the pressed item.Template "element_actions1"
Example 1: tap/hold/double tap
Example 2: press/release with javascript actions
A second general method is to manually attach event listeners/handlers to elements in the DOM. It is harder because you can't use the Home Assistant's actions (tap/hold/...). Instead, you chose the event(s) of the HTML element, and write javascript code to handle them. It's tricky because some events only work on PC, while others only work on mobile. Another challenge is avoiding adding the same event handler multiple times. You may also need to enable
pointer-eventsfor the card (card's style). I only used this method to simulate tap actions, with the 'pointerup' event, which seems to be working on both PC and mobile.I created a template to make it a bit easier and prevent mistakes.
Template "element_actions2"
Example
The final method is to place javascript code directly within the HTML definition. This is considered bad practice but is supported by all browsers. The main drawback is that this method cannot be applied to any of the standard parts of the button card (name, label, custom fields, etc.). I no longer use this method and recommend against it.
Beta Was this translation helpful? Give feedback.
All reactions