Slider type of control with non-limited min and max

Just for fun. Nothing too fancy but may come useful for some edge cases :slight_smile:

Slide the ribbon to left or right to decrease or increase the desired change amount.
Sends payload on release.

[{"id":"13cbb8f5ac3261ed","type":"ui_template","z":"948c19fd.656978","group":"55888982bdd0637f","name":"ribbon controller","order":4,"width":0,"height":0,"format":"<style>\n    .wheel {\n        overflow: hidden;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n    }\n    \n    .wrapper{\n        display:flex;\n        position:relative;\n        overflow:hidden;\n        background:white;\n        width:100%;\n        height:20px;\n        \n\n    }\n    .wrapper:before {\n        background: linear-gradient(270deg, #000000b0, transparent 20%);\n    }\n    \n    .wrapper:after {\n        background: linear-gradient(90deg, #000000b0, transparent 20%);\n    }\n    .ribbon{\n        width:200%;\n        position:absolute;\n        height: 20px;       \n        left:-50%;\n        background: linear-gradient(to right,\n        #00000050,\n        #00000050 50%,\n        transparent 50%,\n        transparent),linear-gradient(to right,var(--nr-dashboard-widgetBgndColor), transparent, var(--nr-dashboard-widgetBgndColor)) ;\n        background-size: 0.6% 100%, 100% 100%;\n        cursor:grab;\n        \n    }\n    .needle{\n        position: absolute;\n        width: 4px;\n        height: 20px;\n        left: calc(50% - 2px);\n        background: linear-gradient(to right, gray,#d30000,gray);\n    }\n    #currentRibbonValue{\n        user-select:none;\n    }\n</style>\n<div id=\"currentRibbonValue\">0</div>\n<div class=\"wrapper\" ng-mousedown=\"start($event)\" ng-mousemove=\"drag($event)\" ng-mouseup=\"release($event)\" >\n    <div id=\"ribbon\" class=\"ribbon\" >\n        <div class=\"needle\"></div>\n    </div>\n</div>\n\n<script>\n    (function(scope) {\n    let dragging = false\n    let position = 0;\n    let sendValue = 0\n    addEventListener('mouseup', (event) => {\n        if(!dragging){\n            return\n        }\n        scope.release(null)\n    });\n\n    scope.start = function(event) {\n        let r = $(\"#ribbon\")[0]        \n = \"-50%\";\n = \"grabbing\"        \n        position = event.originalEvent.x\n        dragging = true        \n    }\n    scope.drag = function(event) {\n        if(!dragging){\n            return\n        }\n        let r = $(\"#ribbon\")[0]\n        let amount = (-50 + ((position - event.originalEvent.x)*-1)/2)\n        if(amount > 0){\n            amount = 0\n        }\n        if(amount < -100){\n            amount = -100\n        }\n        sendValue = amount + 50\n        let displayValue = sendValue > 0 ? \"+\"+sendValue : sendValue\n        $(\"#currentRibbonValue\").text(displayValue)\n = amount +'%'\n    }\n    scope.release = function(event) {\n        let r = $(\"#ribbon\")[0]       \n = \"-50%\";\n = \"grab\"\n        dragging = false;        \n        scope.send({payload:sendValue})\n        sendValue = 0\n        $(\"#currentRibbonValue\").text(sendValue)\n    }\n})(scope);\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"wheel","x":580,"y":580,"wires":[["cc2d313f98c86422"]]},{"id":"0a1672e9bb6e7140","type":"ui_text","z":"948c19fd.656978","group":"55888982bdd0637f","order":3,"width":0,"height":0,"name":"","label":"amount","format":"{{msg.payload}}","layout":"row-spread","className":"","x":960,"y":580,"wires":[]},{"id":"cc2d313f98c86422","type":"function","z":"948c19fd.656978","name":"controlled amount","func":"let controlledAmount = flow.get('controlledAmount') || 0\ncontrolledAmount += msg.payload\nflow.set('controlledAmount',controlledAmount)\nmsg.payload = controlledAmount\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":770,"y":580,"wires":[["0a1672e9bb6e7140"]]},{"id":"55888982bdd0637f","type":"ui_group","name":"1. group","tab":"62083694d0eab7ca","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"62083694d0eab7ca","type":"ui_tab","name":"Home","icon":"dashboard","order":1,"disabled":false,"hidden":false}]



anyway to make it work with left and right arrow keys ? similar to NR Dashboard slider .

I can't see any solution which would work on arrow keys and be:
a) reliable
b) intuitive

So no. I'll pass. But I don't say it is impossible.

1 Like

I am more of a keyboard person, yes i get it, this particular type of dial widget, indeed is much better this way. the slider widget in NR-Dashboard, once engaged with mouse continues to work with arrows and sends the payload, i can see the effect of the change in a graph and it does look better that way, in keyboard however i send steps of change rather than smooth continuous increase (or decrease).
I am sure it is possible as you said, I was never doubting your skills.

btw i am loving your mechanical counter display and all my dashboard displays are using them now.

1 Like

For accessibility purposes, you should be able to tab into the element and then use left/right keys to change the value.

You need to make the element keyboard focusable: Keyboard - Accessibility | MDN (

1 Like

If it ever gets out of prototype status ...

huh, this is a standard javascript key event. Prototype does not mean prototype as you may understand it.

Well, I don't need this widget. It is done by request and it does all what was requested. As it may come handy for people I share it as idea. And in this condition it is prototype. It is far from being ready made widget. Everybody with interest and skills can take it and make better. Why not even to published dashboard node. I just don't have enough time and interest to go with this route.


Nice tool for sensor corrections! I like it.

1 Like