Custom Widget Callback Problem

I’m trying to create a custom widget where I’m using foreach to create multiple clickable buttons. I must be missing something basic, as I can’t get a callback to work for items in the foreach loop. Any thoughts? I know there are some scoping rules with knockoutjs, but unclear how that works with HADashboard.

<!-- DOESN'T WORK -->
<div data-bind="foreach: buttons">
     <div style="height:10px; width:10px" class="test1">TEST</div>
     <!-- OTHER BUTTON STUFF -->
</div>

<!-- WORKS -->
<div style="height:10px; width:10px" class="test1">TEST</div>

 <div data-bind="foreach: buttons">
      <!-- OTHER BUTTON STUFF -->     
 </div>

JS

var buttons = [ new ButtonData("Full", "255","","color: orange; font-size: 450%;")];

var callbacks = [{"selector": '.test1', "action": "click", "callback": self.OnButtonClick}]

WidgetBase.call(self, widget_id, url, skin, parameters, monitored_entities, callbacks)  

function OnButtonClick(self)
{
     console.log("OnButtonClick");
}

I’m using baselight as a starting point.

EDIT - Corrected example

if i see it right then you try to create multiple buttons with the same id (test1) and that wont work
every id can only be used once.

i am not sure if you can connect 1 callback to several items.

@ReneTode - Thanks for the suggestion. My example was slightly incorrect, I’ll edit. I’ve tried a single instance of the loop and also removed the ID field so it’s just referencing the class. I’ve also tried creating a callback reference for each unique ID with no luck.

It seems that once it’s in the foreach loop the event handler can’t pick it up

could very well be possible.
i have not enough experience with js to guide you in this.

the only thing i can advice is to look at widgets that work with more then 1 entity.
for instance heater (works with slider and switch)

here is an example with multiple callbacks:

    self.OnButtonClick = OnButtonClick
    self.OnRaiseLevelClick = OnRaiseLevelClick
    self.OnLowerLevelClick = OnLowerLevelClick
    
    var callbacks =
        [
            {"selector": '#' + widget_id + ' > span', "action": "click", "callback": self.OnButtonClick},
            {"selector": '#' + widget_id + ' #level-up', "action": "click", "callback": self.OnRaiseLevelClick},
            {"selector": '#' + widget_id + ' #level-down', "action": "click", "callback": self.OnLowerLevelClick},
        ]        

if i understand correctly then an id is called with an # in front and a class with a . in front

you need to create a callback for each action to do different things.
data_bind has nothing to do with callbacks.
data_bind is used to show changable data in the html

maybe you can give more info what exactly you are trying to create.

Hi @ReneTode
I’m trying to create something like a multi button scene controller. Where I can specify the button options via parameters. In this case various light brightnesses, and have the buttons highlighted for the current light state. In progress example here: https://imgur.com/a/sLvnTkt

I think I found the change needed to dashboard.js in the AppDaemon source code. Turns out the typical method of creating jqeuery event handlers doesn’t work when creating dynamic components (as done with foreach data binding in Knockoutjs).

It’s a minor syntax change, but seems to address my use case and hopefully doesn’t break anything. I’ll submit a PR after I can test a bit more.

Thanks for being willing to go back and forth on this.

please do test it over a longer time before making a PR.
and even then its questionable if its needed.

the thing you try to create can be created also without foreach.
what you try to create is a very complicated widget for something that can be done with several widgets.