Need help with a button not "working"

Folks, I have a few CSS buttons (via template nodes and one of them is not playing nicely.

This is the code for the NON WORKING node.

<div id="GButtonM_AckA2">
    <button id="{{'btn_'+$id}}" class="md-button program-names small bold" ng-mousedown="send({payload: 'Down'})">{{msg.label}}
    <md-tooltip>See next in list</md-tooltip>
    </button>
</div>

<script>
    (function(scope) {
        scope.$watch('msg', function(msg) {
            if (msg) {
              // Do something when msg arrives
                $("#btn_"+scope.$id).css('background-color',msg.payload.background);
                $("#btn_"+scope.$id).css('color',msg.payload.color);
                $("#btn_"+scope.$id).text(msg.payload.label);
            }
        });
    })(scope);
</script>	

The reload last value on refresh is set.

If I press it, a DOWN message is sent.
A message is received.

{"payload":{"background":"darkgreen","color":"white","label":"ACK"},"_msgid":"74fc09387c322b27"}

And the button background is darkgreen, the text colour is white and it says ACK.

If I go to another page of the dashboard and come back, the button is blank.

Here is another button which is preserved and works.

<div id="GButtonM_WAPAck">
    <md-button style="background-color:{{msg.colour}}" class="md-button program-names small bold">{{msg.text}}
    <md-tooltip>WAP Ack</md-tooltip>
    </md-button>
</div>

<script>

(function($scope) {

$('#GButtonM_WAPAck').on('click', function(e) {
    e.preventDefault(); //prevent default behavior
    $scope.send({"topic":"momentary_regular","payload": true});
});
    
})(scope);
</script>

I'm not sure if in this code the name of the button is declared twice and only once in the first bit of code.

Someone - please.

I note that you've tried to use the mouse down event in the first and the click event in the second. Using mouse down is unusual because it would trigger even if the user presses the button but wants to change their mind and so moves away, click only triggers once the mouse button has been released I think.

1 Like

Yeah, I don't know why.

They were made a long time apart.

As I can't have both nodes opened at the same time I can't easily study them.

I've tried to put the working one's mechanics in the non-working one, but fail miserably.
For reasons unknown: this is still magic to me.

There is no real reason for using either. It isn't important - that I can see - which method is used.
So long as the button keeps it's state (display) when that page is exited and then gone back to.

Looking at both codes:

<div id="GButtonM_WAPAck">
    <md-button style="background-color:{{msg.colour}}" class="md-button program-names small bold">{{msg.text}}
    <md-tooltip>WAP Ack</md-tooltip>
    </md-button>
</div>

<script>

(function($scope) {

$('#GButtonM_WAPAck').on('click', function(e) {
    e.preventDefault(); //prevent default behavior
    $scope.send({"topic":"momentary_regular","payload": true});
});
    
})(scope);
</script>

and

<div id="GButtonM_AckA2">
    <button id="{{'btn_'+$id}}" class="md-button program-names small bold" ng-mousedown="send({payload: 'Down'})">{{msg.label}}
    <md-tooltip>See next in list</md-tooltip>
    </button>
</div>

<script>
    (function(scope) {
        scope.$watch('msg', function(msg) {
            if (msg) {
              // Do something when msg arrives
                $("#btn_"+scope.$id).css('background-color',msg.payload.background);
                $("#btn_"+scope.$id).css('color',msg.payload.color);
                $("#btn_"+scope.$id).text(msg.payload.label);
            }
        });
    })(scope);
</script>	

From the first one:

(function($scope) {

$('#GButtonM_WAPAck').on('click', function(e) {
    e.preventDefault(); //prevent default behavior
    $scope.send({"topic":"momentary_regular","payload": true});
});

Can I put that in the second one's code and remove the ng-mousedown="send({payload: 'Down'})">{{msg.label}} part?

But then I'd have 2 functions in the ...... scope.
(Way above my skill set)
Is that possible?

Asking ChatGPT I fear will be a rabbit hole I don't want to go down, as a lot of times when I ask it things, it gets stuck in one of those..... illusion loops (I believe it is called.)

Further digging.

<div id="GButtonM_AckA2">
    <button id="{{'btn_'+$id}}" class="md-button program-names small bold" ng-mousedown="send({payload: 'Down'})">{{msg.label}}
    <md-tooltip>See next in list</md-tooltip>
    </button>
</div>

<script>
    (function(scope) {
        scope.$watch('msg', function(msg) {
            if (msg) {
              // Do something when msg arrives
                $("#btn_"+scope.$id).css('background-color',msg.payload.background);
                $("#btn_"+scope.$id).css('color',msg.payload.color);
                $("#btn_"+scope.$id).text(msg.payload.label);
            }
        });
    })(scope);
</script>	

Variables like the colour, text are given in the payload arriving.

$("#btn_"+scope.$id).css('background-color',msg.payload.background);
$("#btn_"+scope.$id).css('color',msg.payload.color);
$("#btn_"+scope.$id).text(msg.payload.label);

They aren't stored anywhere (like context in a function node) so if the page refreshes - like when I come/go back to it from another page.
It (the node/button) has no data to put in/on the node.

Correct?

But there again the OTHER one:

<div id="GButtonM_WAPAck">
    <md-button style="background-color:{{msg.colour}}" class="md-button program-names small bold">{{msg.text}}
    <md-tooltip>WAP Ack</md-tooltip>
    </md-button>
</div>

Also gets it's information from the payload.
So why isn't it losing the data the same way as the one in question.

Probably. I don't know your flows so I can't say what you do with that "Down" message. But you can have as many event handlers inside the scope function as you like. All it means is that they have access to the framework's $scope object. (Been a very long time since I looked at AngularJS code!)

I do note that you have a mix of msg.payload.color and msg.color, something to check out.

Also, in some code, you are repeating $("#btn_"+scope.$id) - this, by the way is Not AnglularJS but rather JQuery which I believe D1 also loads.

Is that actually correct? Doesn't D1 have some built-in cache? I think it does.

Good question. :blush: Though do note the use of msg.color here, not msg.payload.color so do check what the message is actually sending.

Yeah, thanks.

I have since worked out that the required structure is msg.payload.xxxx

Silly me.

I may have to ask HotNiPi for help, as I remember he is a CSS expert. :wink:

I did add the two functions into the node but that - typically - failed.

I may give it another try (to test Sod's law) and see what happens.

Thanks again.

I don't know how to mix/combine the two scopes.

This is the best I can do. But - of course - it doesn't work.

<div id="GButtonM_AckAx">
    <button id="{{'btn_'+$id}}" class="md-button program-names small bold" ng-mousedown="send({payload: 'Down'})">{{msg.label}}
    <md-tooltip>See next in list</md-tooltip>
    </button>
</div>

<script>
    (function(scope) {

        $('#GButtonM_AckAx').on('click', function(e) {
            e.preventDefault(); //prevent default behavior
            $scope.send({"topic":"momentary_regular","payload": true})
        })
        $watch('msg', function(msg) {
            if (msg) {
              // Do something when msg arrives
                $("#btn_"+scope.$id).css('background-color',msg.payload.background)
                $("#btn_"+scope.$id).css('color',msg.payload.color)
                $("#btn_"+scope.$id).text(msg.payload.label)
            }
        })
    })(scope)
</script>

Given!

The message arriving is of the structure:

{"_msgid":"8432466b8400de76","payload":{"background":"darkgreen","color":"white","label":"ACK"},"topic":""}

There are other's here on the forum. So ask away.

That doesn't work because you've mixed up scope and $scope.