Is it possible to add an action in response to a double click (distinct from single click) to a plain ui-button?
I also have the same question about a ui-list element.
Thanks for any help, pointers ...
chris
Is it possible to add an action in response to a double click (distinct from single click) to a plain ui-button?
I also have the same question about a ui-list element.
Thanks for any help, pointers ...
chris
Welcome to the forum. Please remember there is a search function here.
These are current topics about similar queries
There might be some function code or some other hints that will help guide you to what you need.
Also, search the palette for keywords, a little reading of the resultant pages may turn up a gem or two
I wasn't aware of this node-contrib until I searched, due this topic.
It might be able to work with an input from a ui_button
as well?? Test and see.
Hi @Gunner,
I wrote that node for physical buttons, e.g. read via a GPIO pin. Seems that this question is about double clicks on a ui-button in the dashboard.
I assume double clicks events are not handled at the moment? Have to leave for work (first day in 1,5 year not working from home) so cannot quickly test...
Not that I have implemented recently something similar in svg.
Bart
Yes, I did see that, but figured an input trigger is an input trigger.... but then later realized, as I was testing, that a ui_button
, while visually acting like it would, doesn't seem to have an option for triggering on a "release"... which, belatedly, seems a very strange omission as it could otherwise easily be used as a "proper" multi-click button.
I have experimented with faked a release using a timed 0 inject, and that works for some of your node options, but getting the timing just right for a click or double click is a bit more difficult.
Actually, it doesn't trigger on the "press", rather it triggers on the "release"... strange that I never noted that before. It clearly detects the press visually, so why not trigger on both?
I did some searching before posting but almost everything that turned up seemed aimed at physical buttons. The only one related to a dashboard button (which you linked above earlier) seemed a bit flakey - author still working on detecting a single press vs the 4 he had achieved already.
If a double click isn't built into the ui-button (from replies so far I'm assuming it's not) I was hoping it could be done fairly easily with perhaps a function node following the ui-button and doing some sort of timing of successive clicks passed to it. I had a quick go at that myself but my node-red skills are still quite young so unsuccessful so far. I was hoping this was such an obvious need that someone had already implemented something or other.
here is a simple example hope it helps
[{"id":"f44c4a9.93ec0b8","type":"debug","z":"b779de97.b1b46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":680,"y":2160,"wires":[]},{"id":"eeee73a8.90d11","type":"function","z":"b779de97.b1b46","name":"","func":"let time_then = context.get(\"button.\"+msg.topic) || 0;\nlet time_now = new Date().valueOf();\ncontext.set(\"button.\"+msg.topic, time_now)\nlet gap = 1000 // half a second\nif (time_now-time_then < gap){\n return msg;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":520,"y":2420,"wires":[["f44c4a9.93ec0b8"]]},{"id":"51790b02.54047c","type":"ui_button","z":"b779de97.b1b46","name":"","group":"8b5cde76.edd58","order":8,"width":0,"height":0,"passthru":true,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"str","topic":"topic","topicType":"str","x":340,"y":2420,"wires":[["eeee73a8.90d11"]]},{"id":"305cb4a0.ab8554","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":2420,"wires":[["51790b02.54047c"]]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
I thought there was a multi-press dashboard node that someone had contributed, but I can't find it on the flows site. It did single, double, long press. Possibly more.
Here is something I got working using @BartButenaers contrib-button-events
with ui_button
Since the button only triggers a 1 on release, the delay and function send a 0 50ms after, thus the button event node just gets the expected 1/0 pulse. I turned off debounce in that node.
[{"id":"51790b02.54047c","type":"ui_button","z":"f55aff94e50a53a7","name":"","group":"8b5cde76.edd58","order":8,"width":0,"height":0,"passthru":true,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"str","topic":"topic","topicType":"str","x":450,"y":440,"wires":[["7f44dff2bf42afe3","cfeb5a66fbec53e2"]]},{"id":"305cb4a0.ab8554","type":"inject","z":"f55aff94e50a53a7","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":290,"y":440,"wires":[["51790b02.54047c"]]},{"id":"7f44dff2bf42afe3","type":"button-events","z":"f55aff94e50a53a7","name":"","outputs":2,"inputField":"payload","inputFieldType":"msg","outputField":"payload","outputFieldType":"msg","downValue":"1","downValueType":"num","upValue":"0","upValueType":"num","idleValue":"1","clickedInterval":200,"pressedInterval":200,"debounceInterval":"","events":[{"type":"clicked"},{"type":"double_clicked"}],"x":700,"y":440,"wires":[["6c10a4584f7552e0"],["fe75590b63d8f503"]]},{"id":"cfeb5a66fbec53e2","type":"delay","z":"f55aff94e50a53a7","name":"","pauseType":"delay","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"x":470,"y":500,"wires":[["b244b62de007c19e"]]},{"id":"b244b62de007c19e","type":"function","z":"f55aff94e50a53a7","name":"","func":"msg.payload = 0;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":500,"wires":[["7f44dff2bf42afe3"]]},{"id":"6c10a4584f7552e0","type":"counter","z":"f55aff94e50a53a7","name":"","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":2,"x":900,"y":400,"wires":[["891967f5f46d8ec6"],[]]},{"id":"891967f5f46d8ec6","type":"ui_text","z":"f55aff94e50a53a7","group":"8b5cde76.edd58","order":17,"width":0,"height":0,"name":"","label":"Clicked","format":"{{msg.payload}}","layout":"row-center","x":1060,"y":400,"wires":[]},{"id":"fe75590b63d8f503","type":"counter","z":"f55aff94e50a53a7","name":"","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":2,"x":900,"y":460,"wires":[["0600be2dabfbb429"],[]]},{"id":"0600be2dabfbb429","type":"ui_text","z":"f55aff94e50a53a7","group":"8b5cde76.edd58","order":18,"width":0,"height":0,"name":"","label":"Dbl Clicked","format":"{{msg.payload}}","layout":"row-center","x":1070,"y":460,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
And right after that... I saw a post by @UnborN that simply creates a dashboard button with proper press and release
I have added that to my flow... no need for the timer for that button
[{"id":"81fc920712f2501c","type":"ui_template","z":"4895ea10b4ee9ead","group":"e68f0343d6bbfce5","name":"","order":0,"width":0,"height":0,"format":"<button id=\"myBtn\">Click Me</button>\n\n<script>\n(function(scope) {\n\nlet myBtn = document.getElementById('myBtn')\n\nmyBtn.addEventListener('mousedown', e => {\nscope.send({payload: 1})\n});\n\nmyBtn.addEventListener('mouseup', e => {\nscope.send({payload: 0})\n});\n\n})(scope);\n\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":650,"y":660,"wires":[["d53f0843a11651ea"]]},{"id":"d53f0843a11651ea","type":"debug","z":"4895ea10b4ee9ead","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":830,"y":660,"wires":[]},{"id":"e68f0343d6bbfce5","type":"ui_group","name":"Default","tab":"773981483ece4bf8","order":1,"disp":true,"width":"6","collapse":false},{"id":"773981483ece4bf8","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
Thanks for that Gunner- easily modified to detect click & dblclick events.
Also a good demo for node-red noob like me on how to use template node with javascript for ui elements.
Thanks for the example E1cid. It's good in that it detects double click just fine; however it doesn't signal single click. Simply modifying the function node to generate a second output for single clicks (anything not a double click) doesn't work because (I guess) the first click of a double is also interpreted as a single click on its own.
Just add a trigger node e.g
[{"id":"305cb4a0.ab8554","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":2420,"wires":[["51790b02.54047c"]]},{"id":"51790b02.54047c","type":"ui_button","z":"b779de97.b1b46","name":"","group":"8b5cde76.edd58","order":8,"width":0,"height":0,"passthru":true,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"str","topic":"topic","topicType":"str","x":340,"y":2420,"wires":[["eeee73a8.90d11","d5219e44.4149c8"]]},{"id":"eeee73a8.90d11","type":"function","z":"b779de97.b1b46","name":"","func":"let time_then = context.get(\"button.\"+msg.topic) || 0;\nlet time_now = new Date().valueOf();\ncontext.set(\"button.\"+msg.topic, time_now)\nlet gap = 500 // half a second\nif (time_now-time_then < gap){\n msg.reset = true;\n return msg;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":520,"y":2420,"wires":[["f44c4a9.93ec0b8","d5219e44.4149c8"]]},{"id":"d5219e44.4149c8","type":"trigger","z":"b779de97.b1b46","name":"","op1":"","op2":"","op1type":"nul","op2type":"pay","duration":"600","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":540,"y":2360,"wires":[["c1b26c81.635b7"]]},{"id":"c1b26c81.635b7","type":"debug","z":"b779de97.b1b46","name":"one","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":710,"y":2360,"wires":[]},{"id":"f44c4a9.93ec0b8","type":"debug","z":"b779de97.b1b46","name":"two","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":650,"y":2200,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
Great! Works with trigger node added. I'll mark this one as the solution because it works using the ui-button node as originally requested.
Here is a better one that will do 1 to nth clicks depending on delay
[{"id":"305cb4a0.ab8554","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":2420,"wires":[["51790b02.54047c"]]},{"id":"51790b02.54047c","type":"ui_button","z":"b779de97.b1b46","name":"","group":"8b5cde76.edd58","order":8,"width":0,"height":0,"passthru":true,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"str","topic":"topic","topicType":"str","x":300,"y":2460,"wires":[["eeee73a8.90d11","1425d47b.a983bc"]]},{"id":"eeee73a8.90d11","type":"function","z":"b779de97.b1b46","name":"","func":"let count = flow.get(\"button_count\") || 0;\nflow.set(\"button_count\", count+1);\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":520,"y":2420,"wires":[[]]},{"id":"1425d47b.a983bc","type":"trigger","z":"b779de97.b1b46","name":"","op1":"","op2":"","op1type":"nul","op2type":"pay","duration":"600","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"topic","topic":"topic","outputs":1,"x":230,"y":2500,"wires":[["591f7ae8.8f36c4"]]},{"id":"591f7ae8.8f36c4","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"move","p":"button_count","pt":"flow","to":"button_count","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":2500,"wires":[["c987027d.3e03f"]]},{"id":"c987027d.3e03f","type":"switch","z":"b779de97.b1b46","name":"","property":"button_count","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"gte","v":"4","vt":"num"}],"checkall":"false","repair":false,"outputs":4,"x":600,"y":2500,"wires":[["c1b26c81.635b7"],["f44c4a9.93ec0b8"],["b303a5f2.fd925"],["84d1ac47.6f4678"]]},{"id":"c1b26c81.635b7","type":"debug","z":"b779de97.b1b46","name":"one","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":2460,"wires":[]},{"id":"f44c4a9.93ec0b8","type":"debug","z":"b779de97.b1b46","name":"two","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":2500,"wires":[]},{"id":"b303a5f2.fd925","type":"debug","z":"b779de97.b1b46","name":"three","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":2540,"wires":[]},{"id":"84d1ac47.6f4678","type":"debug","z":"b779de97.b1b46","name":"otherwise","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":770,"y":2580,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
[change delay for trigger]
Hmmm... After a few failed attempts of my own, I had actually tried the flow from @E1cid before I had made the one I posted above. But couldn't get anything but a "1" out of it.
Same with this last one... What gives? I am clicking fast, clicking slow, clicking with and without looking, I think I tried once with my forehead... but that might have been counter-productive
EDIT... ahhh forget it... I was looking at the payload, not the payload's node of source.
I fixed that
Just for info
I found that it was slightly unstable with repeated operations in quick sucsession, So I did the context storage with a change node, this seems more stable. Seems the change node is faster at context storage than the function node.
[{"id":"305cb4a0.ab8554","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":2420,"wires":[["51790b02.54047c"]]},{"id":"51790b02.54047c","type":"ui_button","z":"b779de97.b1b46","name":"","group":"8b5cde76.edd58","order":8,"width":0,"height":0,"passthru":true,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"str","topic":"topic","topicType":"str","x":340,"y":2420,"wires":[["1425d47b.a983bc","2d6f28b0.9130e8"]]},{"id":"1425d47b.a983bc","type":"trigger","z":"b779de97.b1b46","name":"","op1":"","op2":"click","op1type":"nul","op2type":"str","duration":"300","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":230,"y":2580,"wires":[["591f7ae8.8f36c4"]]},{"id":"2d6f28b0.9130e8","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"set","p":"button_count","pt":"flow","to":"$flowContext(\"button_count\") ? $flowContext(\"button_count\")+1 : 1","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":570,"y":2380,"wires":[[]]},{"id":"591f7ae8.8f36c4","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"move","p":"button_count","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":2580,"wires":[["c987027d.3e03f"]]},{"id":"c987027d.3e03f","type":"switch","z":"b779de97.b1b46","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"gte","v":"4","vt":"num"}],"checkall":"false","repair":false,"outputs":4,"x":600,"y":2500,"wires":[["c1b26c81.635b7"],["f44c4a9.93ec0b8"],["b303a5f2.fd925"],["84d1ac47.6f4678"]]},{"id":"c1b26c81.635b7","type":"debug","z":"b779de97.b1b46","name":"one","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":2460,"wires":[]},{"id":"f44c4a9.93ec0b8","type":"debug","z":"b779de97.b1b46","name":"two","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":2500,"wires":[]},{"id":"b303a5f2.fd925","type":"debug","z":"b779de97.b1b46","name":"three","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":2540,"wires":[]},{"id":"84d1ac47.6f4678","type":"debug","z":"b779de97.b1b46","name":"otherwise","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":770,"y":2580,"wires":[]},{"id":"eeee73a8.90d11","type":"function","z":"b779de97.b1b46","name":"","func":"let count = flow.get(\"button_count\") || 0;\nflow.set(\"button_count\", count+1);\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":590,"y":2420,"wires":[[]]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
Able to lower the delay to 300 ms with the change node.
[edit]
here it is in series so no cloning msg
[{"id":"bb1e93fd.77c1c8","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":310,"y":2340,"wires":[["f5b92924.1ec458"]]},{"id":"f5b92924.1ec458","type":"ui_button","z":"b779de97.b1b46","name":"","group":"8b5cde76.edd58","order":9,"width":0,"height":0,"passthru":true,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"str","topic":"topic","topicType":"str","x":480,"y":2340,"wires":[["3ad88553.1142ba"]]},{"id":"3ad88553.1142ba","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"set","p":"button_count","pt":"flow","to":"$flowContext(\"button_count\")+1","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":2340,"wires":[["28de7702.0fe7b8"]]},{"id":"28de7702.0fe7b8","type":"trigger","z":"b779de97.b1b46","name":"","op1":"","op2":"button_count","op1type":"nul","op2type":"flow","duration":"300","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":330,"y":2460,"wires":[["24e7e11b.be52c6"]]},{"id":"24e7e11b.be52c6","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"set","p":"button_count","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":2460,"wires":[["7a2bf890.c32e48"]]},{"id":"7a2bf890.c32e48","type":"switch","z":"b779de97.b1b46","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"gte","v":"4","vt":"num"}],"checkall":"false","repair":false,"outputs":4,"x":751.3333129882812,"y":2468.333251953125,"wires":[["20756b78.8afdbc"],["c9dd4afe.854dc"],["d6b0378d.f72988"],["e4799362.09814"]]},{"id":"20756b78.8afdbc","type":"debug","z":"b779de97.b1b46","name":"one","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":891.3333129882812,"y":2428.333251953125,"wires":[]},{"id":"c9dd4afe.854dc","type":"debug","z":"b779de97.b1b46","name":"two","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":891.3333129882812,"y":2468.333251953125,"wires":[]},{"id":"d6b0378d.f72988","type":"debug","z":"b779de97.b1b46","name":"three","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":891.3333129882812,"y":2508.333251953125,"wires":[]},{"id":"e4799362.09814","type":"debug","z":"b779de97.b1b46","name":"otherwise","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":2540,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"12","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
First time used will set context, then functions as normal
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.