"Are You Sure?" Pop-ups

In my dashboard I would like to be able to power off certain devices with the click of a button. I have this already done, but these devices are very critical, and I need to prevent accidental shut-offs from miss-clicks.
A solution would be to require someone to click on the button for a period of time (say 5 sec) and then the pop-up appears to confirm power-off. How could this be done?
Any help is much appreciated!

Here's a small flow that asks for confirmation, before sending the payload.
The button doesnt constantly monitor if you have your finger on it, so you may have to rethink that idea.

[{"id":"9239b1a6.aae0e","type":"function","z":"60728902.17e938","name":"Confirm","func":"//only accept OK msg's\nif (msg.payload == 'OK') {\n    msg.payload = \"Stop\";\n    node.send(msg);\n}\nreturn null;","outputs":1,"noerr":0,"x":530,"y":1770,"wires":[["8a93e441.b4d058"]]},{"id":"9835f029.438b9","type":"ui_button","z":"60728902.17e938","name":"","group":"61d2dced.3db8f4","order":4,"width":"1","height":"1","passthru":false,"label":"Stop","tooltip":"","color":"","bgcolor":"","icon":"","payload":"Stop the process?","payloadType":"str","topic":"","x":160,"y":1770,"wires":[["52559915.a29db8"]]},{"id":"52559915.a29db8","type":"ui_toast","z":"60728902.17e938","position":"dialog","displayTime":"3","highlight":"","outputs":1,"ok":"OK","cancel":"Cancel","topic":"","name":"Deploy?","x":337,"y":1770,"wires":[["9239b1a6.aae0e"]]},{"id":"8a93e441.b4d058","type":"debug","z":"60728902.17e938","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":720,"y":1770,"wires":[]},{"id":"61d2dced.3db8f4","type":"ui_group","z":"","name":"flowtest","tab":"3c94630c.13381c","disp":true,"width":"12","collapse":false},{"id":"3c94630c.13381c","type":"ui_tab","z":0,"name":"Test","icon":"dashboard","order":6}]
2 Likes

That makes sense. Currently I'm using the switch dashboard node as an on/off switch. I have it so the icon changes in the on/off positions. Is there a way to only make the icon change if the "OK" Button is pressed? Currently the icon changes every time the switch is clicked regardless of whether "OK" or "Cancel" is pressed in the pop-up. Thanks for the help!

Yes, by using feedback from the function node with the required msg.background into the front end of the button node. A bit of coding in the function node will be needed.
...I'm not sure where this goes once you've powered down the device, how are you intending to restore it?

I have a similar thing with buttons.

Here is my effort.

Maybe not as "nice", but it is an option.

[{"id":"ed9234b8.2f122","type":"function","z":"df652827.d02c3","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\nvar enabled = context.get(\"ENABLED\")||0;\n\n//  Look for a message with topic set to SETUP to set values.\nif (msg.topic == \"SETUP\")     //Do this if the message is NOT \"X\"\n{\n    //\n    //  Background colours first.\n    //\n    context.set(\"ABGC\", msg.colourA);\n    context.set(\"BBGC\", msg.colourB);\n    //\n    //  Disabled button background colour.\n    //\n    context.set(\"DISABLEDCLR\",msg.disabledColour);\n    //\n    //  Now do text.\n    //\n    context.set(\"Atxt\", msg.txtA);\n    context.set(\"Btxt\", msg.txtB);\n    //\n    //  Font colours.\n    //\n    context.set(\"AFC\",msg.txtclrA);\n    context.set(\"BFC\",msg.txtclrB);\n    //\n    //  Payloads.\n    //\n    context.set(\"PayloadA\", msg.payloadA);\n    context.set(\"PayloadB\", msg.payloadB);\n    //\n    //  Topic.\n    //\n    if (msg.topicSET !== null)\n    {\n        context.set(\"Topic\",msg.topicSET);\n    } else\n    {\n        context.set(\"Topic\",\"~\");\n    }\n    msg.txt = msg.txtA;\n    msg.colour = msg.disabledColour;\n    msg.fontclr = msg.txtclrA;\n    return msg;\n}\n\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    //node.warn(\"X detected\");\n    //  Insert here code to enable other stuff.\n//    if (context.get(\"ENABLED\") === 0)\n    if (enabled === 0)\n    {\n        //\n        //  Old code.\n        //\n        //node.warn(\"Setting enable\");\n//        context.set(\"ENABLED\",1);\n//        msg.txt = context.get(\"Atxt\");\n//        msg.colour = context.get(\"ABGC\");\n//        msg.fontclr = context.get(\"AFC\");\n\n        //  New code.\n        \n        //node.warn(\"State = \" + state);\n\n        if (state === 0)\n        {\n            //\n            //  Set things for state 0\n            //\n            //node.warn(\"State 0 detected\");\n            msg.payload = context.get(\"PayloadA\");\n            msg.colour = context.get(\"ABGC\");\n            msg.txt = context.get(\"Atxt\");\n            msg.fontclr = context.get(\"AFC\");\n        }\n        else if (state === 1)\n        {\n            //\n            //  Set things for state 1\n            //\n            //node.warn(\"State 1 detected\");\n            msg.payload = context.get(\"PayloadB\");\n            msg.colour = context.get(\"BBGC\");\n            msg.txt = context.get(\"Btxt\");\n            msg.fontclr = context.get(\"BFC\");\n        }\n        context.set(\"ENABLED\",1);\n        return msg;\n    }\n\n//    if (context.get(\"ENABLED\") === 1)\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n    if (enabled === 1)\n    {\n        if (state === 0)\n        {\n            //  Condition A\n            msg.payload = context.get(\"PayloadA\");\n            msg.colour = context.get(\"ABGC\");\n            msg.txt = context.get(\"Atxt\");\n            msg.fontclr = context.get(\"AFC\");\n        } else\n        if (state === 1)\n        {\n            //  Condition B\n            msg.payload = context.get(\"PayloadB\");\n            msg.colour = context.get(\"BBGC\");\n            msg.txt = context.get(\"Btxt\");\n            msg.fontclr = context.get(\"BFC\");\n        }\n    }\n    \n    if (context.get(\"Topic\") == \"~\")\n    {\n        msg.topic = \"\";\n    } else\n    {\n        msg.topic = context.get(\"Topic\");\n    }\n    return msg;\n}\nif (msg.payload == \"Z\")\n{\n    //\n    ////node.warn(\"Timed out\");\n    //\n    context.set(\"ENABLED\",0);\n    if (state === 0)\n    {\n        //\n        //  Set things for state 1\n        //\n        msg.payload = context.get(\"PayloadA\");\n        msg.colour = context.get(\"DISABLEDCLR\");\n        msg.txt = context.get(\"Atxt\");\n        msg.fontclr = context.get(\"AFC\");\n    }\n    else if (state === 1)\n    {\n        //\n        //  Set things for state 2\n        //\n        msg.payload = context.get(\"PayloadB\");\n        msg.colour = context.get(\"DISABLEDCLR\");\n        msg.txt = context.get(\"Btxt\");\n        msg.fontclr = context.get(\"BFC\");\n    }\n    return msg;\n}\n","outputs":1,"noerr":0,"x":3120,"y":280,"wires":[["e01f15d7.afae28","e380fd5d.7618b8","2313dbca.3746cc"]]},{"id":"e01f15d7.afae28","type":"ui_button","z":"df652827.d02c3","name":"28 June","group":"373c4fb2.a22078","order":7,"width":"3","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":3110,"y":230,"wires":[["ed9234b8.2f122","356bd2e0.9a44fe"]]},{"id":"584e530b.bfda9c","type":"inject","z":"df652827.d02c3","name":"Inject","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":3100,"y":140,"wires":[["5bc8465e.969d08"]]},{"id":"5bc8465e.969d08","type":"function","z":"df652827.d02c3","name":"Setup","func":"msg = {\n    \"topic\":\"SETUP\",\n    \"disabledColour\":\"brown\",\n    \"colourA\": \"yellow\",\n    \"colourB\": \"green\",\n    \"txtA\": \"Option 1\",\n    \"txtB\": \"Option 2\",\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"black\",\n    \"payloadA\": 0,\n    \"payloadB\": 1,\n    \"topicSET\": \"CONTROL\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":3100,"y":190,"wires":[["ed9234b8.2f122"]]},{"id":"7adca369.70a604","type":"comment","z":"df652827.d02c3","name":"Read me","info":"Variables needing to be set in the **setup** node:\n\"disabledColour\":\"brown\",\n\"colourA\": \"yellow\",\n\"colourB\": \"green\",\n\"txtA\": \"Option 1\",\n\"txtB\": \"Option 2\",\n\"txtclrA\": \"black\",\n\"txtclrB\": \"black\",\n\"payloadA\": 0,\n\"payloadB\": 1,\n\"topicSET\": \"CONTROL\"\n\nDisabledColour - this is the colour shown if the\nbutton is inactive.\ncolourA - this is the colour of the button when\noption A is selected.\ncolourB - (as above but for option B)\ntxtA - this is the text shown when option A\nis selected.\ntxtB - (as above but for option B)\ntxtclrA - the font colour for option A\ntxtclrB - the font colour for option B\npayloadA - what is sent out when option A is\nselected.\npayloadB - (as above but for option B)\ntopicSET - the topic of the payload sent\n\nAdjust the time the button accepts input by\nediting the `trigger` node.\n\nThe output is AFTER the `switch` node.\nThis will need to be edited if the `topic` is \nnot \"CONTROL\".\nThis could be worked around with flow.context\nvariables, but I don't want to make too many\nchanges to people's flows.  But by all means,\nchange if it suits you.\n\n","x":3100,"y":100,"wires":[]},{"id":"356bd2e0.9a44fe","type":"trigger","z":"df652827.d02c3","op1":"","op2":"Z","op1type":"nul","op2type":"str","duration":"3","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":3110,"y":320,"wires":[["ed9234b8.2f122"]]},{"id":"e2b7cb62.3cec68","type":"debug","z":"df652827.d02c3","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":3320,"y":360,"wires":[]},{"id":"e380fd5d.7618b8","type":"switch","z":"df652827.d02c3","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"CONTROL","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":3270,"y":280,"wires":[["e2b7cb62.3cec68","150610bb.fcd347"]]},{"id":"2313dbca.3746cc","type":"debug","z":"df652827.d02c3","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":3270,"y":210,"wires":[]},{"id":"150610bb.fcd347","type":"ui_text","z":"df652827.d02c3","group":"373c4fb2.a22078","order":11,"width":"3","height":"1","name":"","label":"output","format":"{{msg.payload}}","layout":"row-spread","x":3320,"y":400,"wires":[]},{"id":"373c4fb2.a22078","type":"ui_group","name":"Group 1","tab":"bca4b6a6.5ee09","order":1,"disp":true,"width":6},{"id":"bca4b6a6.5ee09","type":"ui_tab","z":"","name":"Pushbutton","icon":"dashboard","order":44,"disabled":false,"hidden":false}]

Once the device is powered off it will require manual startup. Is there a way of only getting the switch node to activate if the "OK" button is pressed?

I'm not sure I follow, what is the purpose of the flow? When I click the button in the UI it changes the color of the option button and the output number from 1 to 0 or visa-versa.

But in post#1 you asked for a button node...

I think I wasn't specific enough. When I said "button" initially I was already using the dashboard switch node as the "button", not the actual dashboard button node.
When it's off it looks like,
image
and when it's on,
image
which can be changed by clicking on it. Ideally when it's on and someone clicks it, the "Are You Sure" notification pops up. From there, if someone presses "OK", the icon turns off (gray power symbol) and the power is turned off. But if they hit "Cancel", the icon stays on (yellow lightning) and the pop-up goes away. Does that make more sense? Sorry for the confusion

The ui-notify node has an ok/cancel mode that could be used for this. It doesn’t have the 5 sec press though, just a pop up window.

Yes, that's what I included in my example flow above.
@HYPER You can use the same principle with a switch as well as a button. Just ensure that the switch node passthrough is deselected, so the feedback from the function node can change the switch icon status.

1 Like

I hope I uploaded the flow where you have to DOUBLE press the button to change the output.

The output (1 or 0) can be changed to what ever you want. I also think I included the README node which explains all the things used/needed.

That being said (and I hope true) it means you can't just click on a button to activate/invoke its output. You have to DOUBLE press it.

Could you provide the flow you used? I'm still learning how the msg properties work.
Thanks!

I'm not using one, just offering a way forward for you to develop this.
See how far you get, post your flow, and the forum will try and help.

Here's what I've tried thusfar:

[{"id":"42747bb3.0931a4","type":"ui_switch","z":"6aaebb0b.4ac3e4","name":"Electrolyzer Kill Switch","label":"Electrolyzer Kill Switch","tooltip":"","group":"6f313104.efd86","order":18,"width":"3","height":"1","passthru":false,"decouple":"true","topic":"","style":"","onvalue":"0","onvalueType":"num","onicon":"fa-2x fa-bolt","oncolor":"yellow","offvalue":"1","offvalueType":"str","officon":"fa-2x fa-power-off","offcolor":"gray","x":460,"y":80,"wires":[["189cd68.a7a3e2a"]]},{"id":"189cd68.a7a3e2a","type":"ui_toast","z":"6aaebb0b.4ac3e4","position":"dialog","displayTime":"3","highlight":"","outputs":1,"ok":"OK","cancel":"Cancel","topic":"","name":"Deploy?","x":660,"y":80,"wires":[["d5e77593.490388","c906cb1d.6321a8"]]},{"id":"d5e77593.490388","type":"function","z":"6aaebb0b.4ac3e4","name":"Confirm","func":"//only accept OK msg's\nif (msg.payload == 'OK') \n    msg.payload = 1\nelse\n    msg.payload = 0\nreturn msg;","outputs":1,"noerr":0,"x":640,"y":160,"wires":[["67ba771f.354b98","1b2a9f0a.fce5e1","42747bb3.0931a4"]]},{"id":"c906cb1d.6321a8","type":"debug","z":"6aaebb0b.4ac3e4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":890,"y":80,"wires":[]},{"id":"67ba771f.354b98","type":"debug","z":"6aaebb0b.4ac3e4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":930,"y":140,"wires":[]},{"id":"1b2a9f0a.fce5e1","type":"ui_text","z":"6aaebb0b.4ac3e4","group":"6f313104.efd86","order":21,"width":"3","height":"1","name":"Electrolyzer Kill Switch Status","label":"Status","format":"{{msg.payload}}","layout":"col-center","x":770,"y":220,"wires":[]},{"id":"6f313104.efd86","type":"ui_group","z":"","name":"Swtiches","tab":"3a1516f.9e622ea","order":2,"disp":false,"width":"11","collapse":false},{"id":"3a1516f.9e622ea","type":"ui_tab","z":"","name":"Hydrogen Liquifying Station","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

It doesn't seem to change what happens to the switch node status though

Hyper,

Just wondering: Was I wrong with how that flow I posted works? You need to double press the button to get the output to change?

I know I could check it myself, but I would like to be sure you got what I sent.

You can also put the icons you are using in/on the button. It is explained in the readme node.

The button only requires a double click to change the the output if you click it, move the mouse away, and click it again. If you press it twice without removing the mouse off the button, it will sometimes change from option 1-2 on the first click and back on the second. Does that make sense?

Your function node is not formatted correctly.
Compare it with my example....

Yes it does in a weird way.

The idea is that it prevents you accidentally pressing the button. You have to DOUBLE press it.
There is lee way that if you even DOUBLE press it by mistake, you can click it again to negate what you did.

There is a timeout on how long this works

It works for what I wrote it to do.

The example from post 4 has no code in it, so I'm not sure how to compare