as i recently switched my home automation from mysensors to node red (and node red dashboard), i stumbled over this thread. as i have implemented iro.js in mysensors as a component previously, i wanted to use this library on my new dashboard as well.
as this was the first thread listed in googles search results, i wanted to share my solution, for those of you who are not satisfied with the default color picker node.
i added a "template" node to my flow, unticked "Pass through messages from input" and wrote the following code into it.
beware: you need to change some bits, if you want to use multiple instances of this on your dashboard.
<script src="https://cdn.jsdelivr.net/npm/@jaames/iro/dist/iro.min.js"></script>
<script>
var theScope = scope;
var storedStateColor = getLastColor(theScope);
var colorPicker;
/**
* initialize iro.js component
*/
function initIroJs()
{
//wait for iro library to be loaded
if(typeof(iro) === 'object')
{
//and initialize component
colorPicker = new iro.ColorPicker(
"#color-picker-container",
{
width: 300,
color: fixColorString(storedStateColor),
}
);
colorPicker.on('input:change', onColorChange);
}
else
{
setTimeout(function() { initIroJs(); }, 250);
}
}
function onColorChange()
{
theScope.send({ payload: colorPicker.color.hexString });
}
/**
* update colorPicker state if msg.payload is received
*
* @param {string} payload - hex color string
*/
function messageReceived(payload)
{
if(typeof(colorPicker) === 'object')
{
colorPicker.color.hexString = fixColorString(payload);
}
}
/**
* prefix hex color strings with # if not present
*
* @param {string} color - hex color string
*/
function fixColorString(color)
{
return color.startsWith('#') ? color : '#' + color;
}
/**
* checks for stored msg object and returns the last set color, if present
*
* @param {object} theScope
*/
function getLastColor(theScope)
{
//check if stored state has a msg object
if(typeof(theScope.msg) === 'object')
{
//check if payload is a hex color string
if(typeof(theScope.msg.payload) === 'string' &&
theScope.msg.payload.match(/^#?[A-Fa-f0-9]{6}$/))
{
return theScope.msg.payload;
}
}
return '#000000';
}
theScope.$watch('msg.payload', messageReceived); //listen for incoming messages
initIroJs();
</script>
<div id="color-picker-container" style="min-height: 350px;"></div>
i am currently learning how to make this a completely functional and publishable node.