Hi all ,
In one of my flow, I use a UI template node, which is used for several things :
-
handle JS tabulator features , this part works well, either from a browser running on the same computer as NR, or from a remote browser.
-
copy content of a cvs passed as msg.data to the OS clipboard , using this piece of code :
case "copytoclipboard":
//$scope.send({payload: "this is copyclipboard"});
// Copy the text inside the text field
navigator.clipboard.writeText(msg.data);
// Alert the copied text
alert("Copied the text: " + msg.data);
break;
This works perfectly when using in the local browser ( same computer as the one running Node Red), but not from another browser over the network, I get the ierror in browser console :
Does anyone have any idea about where this problem come from ?
For reference if helpful, here is the full code of the UI template node :
<form>
<div id="gridExample" style="background-color:#000000;margin:0px;border:0px solid black"></div>
</form>
<script type="text/javascript">
var $scope = this.scope;
var grid = new Tabulator("#gridExample", {
rowFormatter : function(row){
// chnage row color based on mainDstIp specific value
if(row.getData()["vertexType"].includes("V")){
row.getElement().style.backgroundColor = "#b3ffb3";
row.getElement().style.color = "black";
}
if(row.getData()["vertexType"].includes("A")){
row.getElement().style.backgroundColor = "#ffb3cc";
row.getElement().style.color = "black";
}
if(row.getData()["vertexType"].includes("D")){
row.getElement().style.backgroundColor = "#b3daff";
row.getElement().style.color = "black";
}
},
layout:"fitColumns", //fitColumns
movableColumns: true,
headerVisible: true,
resizableColumns: true,
//selectable: 5,
//responsiveLayout: "collapse",
//autoResize: true,
pagination: "true",
paginationSizeSelector:[10, 25, 50, 100, true], //select list with an "all" option at the end of the list
height: "800px",
groupBy:["rxTx", "control"],
groupToggleElement:"header", //toggle group on click anywhere in the group header
// groupStartOpen: true,
data:[
],
columns:[/*
{formatter:"rowSelection", titleFormatter:"rowSelection", hozAlign:"center", headerSort:false, cellClick:function(e, cell){
cell.getRow().toggleSelect();
}}*/
{
formatter:"rowSelection",
titleFormatter:"rowSelection",
titleFormatterParams:{
rowRange:"active"
}, //only toggle the values of the active filtered rows
hozAlign:"center",
headerSort:false,
cellClick:function(e, cell){
cell.getRow().toggleSelect();
}},
//{title:"ID", field:"#", resizable: true, formatter:"textarea", width:200},
{title:"Factory label", field:"Factory label", resizable: true, formatter:"textarea", width:200},
{title:"Rx/Tx",
field:"rxTx",
resizable: true,
editor:"input",
headerFilter:true, //show header filter matching the cells editor,
width:100},
{title:"chNumber",
field:"chNumber",
resizable: true,
editor:"input",
headerFilter:true, //show header filter matching the cells editor,
width:100},
{title:"tags", field:"tags", resizable: true, width:250},
{title:"descriptor", field:"descriptor", resizable: true, width:300},
{title:"control", field:"control", resizable: true, width:100},
{title:"useAsEndpoint", field:"useAsEndpoint", formatter:"tickCross", resizable: true, width:100},
{title:"sdpSupport", field:"sdpSupport", formatter:"tickCross",resizable: true, width:120},
{title:"sipsMode", field:"sipsMode", resizable: true, width:100},
{title:"active", field:"active",formatter:"tickCross", resizable: true, width:100},
{title:"mainDstIp", field:"mainDstIp", resizable: true, width:100},
//{title:"mainDstPort", field:"mainDstPort", resizable: true, width:100},
{title:"spareDstIp", field:"spareDstIp", resizable: true, width:100}
//{title:"spareDstPort", field:"spareDstPort", resizable: true, width:100}
]
});
grid.on("tableBuilt", function(){
$scope.send({payload: "Grid is ready"});
});
grid.on("dataFiltered", function(filters, rows){
console.log(`Post-filter event: ${rows.length} rows`);
let data = [];
for (let i = 0 ; i < rows.length; i++)
data.push(rows[i]._row.data);
var msg = {};
msg.payload = data;
msg.topic = "filtered_content";
msg.length = rows.length;
$scope.send(msg);
//$scope.send({topic:"filtered_content"},{payload: "export" + data});
});
/*
grid.on("dataFiltered", function(filters, rows){
//filters - array of filters currently applied
//rows - array of row components that pass the filters
console.log(`Post-filter event: ${rows.length} rows`);
for (let i = 0 ; i < rows.length; i++)
console.log(Object.entries(rows[i]));
});
*/
grid.on("rowClick", function(e, row){
//alert("Row " + row.getData().descriptor + " Clicked!!!!");
$scope.send({payload: row.getData().descriptor + " Clicked!!!!"});
});
(function(scope) {
$scope.$watch('msg', function(msg)
{
if (msg)
switch (msg.payload)
{
case "setdata":
//grid.clearData();
grid.setData(msg.data);
$scope.send({payload: "Grid updated"});
break;
case "copytoclipboard":
navigator.clipboard.writeText(msg.data);
alert("Copied the text: " + msg.data);
break;
}
});
})(scope);
</script>
Thanks in advance,
Jerome