# How to send a message out of ui\_template using tabulator

**URL:** <https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789>\
**Category:** Dashboard\
**Created:** [6 December 2022 19:33 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789 "2022-12-06T19:33:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bs-eng](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bs-eng/32/51470_2.png) [@bs-eng](https://discourse.nodered.org/u/bs-eng)\
**Post date:** [6 December 2022 19:33 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789/1 "2022-12-06T19:33:55Z")

</div>

Hi there!

Yes, I searched the forum for similar answer and did not find one - at least none that worked on my code.  
In fact I took quite some inspiration from the ui\_table node of @knolleary .

What I want to achieve is to send messages out of the ui\_template. In that template I have inserted tabulator (latest version:5.4). the reason I do not use the ui\_table node (anymore) is that I need a lot more functionality of tabulator that ui\_table does not (yet?) gives access to.

This is the bare bone example of my issue:

```auto
[{"id":"b84fd2f0.2ecab","type":"tab","label":"Tabulator-Example","disabled":false,"info":""},{"id":"6c38b40a.49b5ec","type":"debug","z":"b84fd2f0.2ecab","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":910,"y":260,"wires":[]},{"id":"474bdcb4.3b7cc4","type":"ui_button","z":"b84fd2f0.2ecab","name":"get table data","group":"1bbe4d3.9a59cb3","order":9,"width":"4","height":"1","passthru":false,"label":"get table data","tooltip":"","color":"","bgcolor":"","icon":"save","payload":"{\"cmd\":\"getTableData\",\"arg\":\"\"}","payloadType":"json","topic":"","topicType":"str","x":340,"y":320,"wires":[["5a7106fb.ba3f58"]]},{"id":"88f06ecd.2f8c9","type":"inject","z":"b84fd2f0.2ecab","name":"trigger","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"cmd\":\"getLastId\",\"arg\":\"\"}","payloadType":"json","x":370,"y":260,"wires":[["5a7106fb.ba3f58"]]},{"id":"5a7106fb.ba3f58","type":"ui_template","z":"b84fd2f0.2ecab","group":"955ee4fa.99cfb8","name":"Tabulator","order":7,"width":"16","height":"8","format":"<div id=\"example-table2\"></div>\n<script>\n var tabledata = [\n {id:0, pos:0, age:\"1\"},\n {id:1, pos:1, age:\"12\"},\n {id:2, pos:2, age:\"1\"},\n {id:3, pos:3, age:\"42\"},\n {id:4, pos:4, age:\"11\"},\n];\n \n var table = new Tabulator(\"#example-table2\", {\n \tdata:tabledata, //assign data to table\n \tindex:\"id\", // set the field which serves as index for tabulator\n \tlayout:\"fitColumns\", //fit columns to width of table (optional)\n \tcolumns:[//Define Table Columns\n \t {title:\"ID\", field:\"id\", width:60},\n \t \t{title:\"Position\", field:\"pos\", width:150},\n \t \t{title:\"Age\", field:\"age\", hozAlign:\"left\", formatter:\"progress\",headerSort:false,cellClick:function(e,cell){\n \t \t this.send({payload:\"testcell\"});\n \t \t}\n \t \t}\n \t]\n });\n \n //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n // CUSTOM FUNCTIONS\n function getLastTableIndex(myTable){\n var last_id = Math.max.apply(Math, myTable.getRows().map(function(o) { return o.getIndex(); }));\n if(!Number.isFinite(last_id)) last_id = -1;\n \n return last_id;\n };\n \n \n //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n // INTERACTION FUNCTIONS\n //This is needed to interact with Node-Red when a message is sent to the ui-template.\n (function(scope){\n \n // // TODO replace with code that does what you want ot happen everytime you click anywhere in a row\n // table.on(\"rowClick\", function(e, row){ \n // \tscope.send({payload:\"test\"});\n // });\n \n scope.$watch('msg', function(msg){\n if(msg){\n //do something here when a message arrives like table.setData();\n if(msg.hasOwnProperty(\"payload\")){\n if(msg.payload.hasOwnProperty(\"cmd\") && msg.payload.hasOwnProperty(\"arg\")){\n switch(msg.payload.cmd){\n case \"getTableData\":\n scope.send({payload:table.getData()});\n break;\n case \"getLastId\":\n scope.send({payload:getLastTableIndex(table)});\n break;\n }\n }\n }\n }\n });\n \n })(scope);\n</script>","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","x":680,"y":260,"wires":[["6c38b40a.49b5ec"]]},{"id":"7008b521.2c90bc","type":"ui_template","z":"b84fd2f0.2ecab","group":"d386fb82fa5ef195","name":"Header","order":6,"width":0,"height":0,"format":"<link href=\"https://unpkg.com/tabulator-tables/dist/css/tabulator_midnight.min.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables/dist/js/tabulator.min.js\"></script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":680,"y":200,"wires":[[]]},{"id":"1bbe4d3.9a59cb3","type":"ui_group","name":"commands","tab":"752d9f37.ffa91","order":2,"disp":false,"width":"16","collapse":false},{"id":"955ee4fa.99cfb8","type":"ui_group","name":"table","tab":"752d9f37.ffa91","order":1,"disp":true,"width":"16","collapse":false},{"id":"d386fb82fa5ef195","type":"ui_group","name":"Tabulator Example","tab":"d0ef1a9bfa867de7","order":2,"disp":true,"width":"16","collapse":true},{"id":"752d9f37.ffa91","type":"ui_tab","name":"Tabulator_Example","icon":"fa-table","disabled":false,"hidden":false},{"id":"d0ef1a9bfa867de7","type":"ui_tab","name":"KnobConfig2","icon":"adjust","order":1,"disabled":false,"hidden":false}]

```

It works very well to receive a msg, act upon it and send a message back to node-red-  
What does not work is the send function inside the cellClick-event of the 'age' column. The code I copied from the ui\_table node. I also tried many other setups like putting the send function inside the `(function(scope){ myFu(){scope.send()} })` and then use myFu in the cellclick event handler. No matter what I seem to not be able to properly access the send() function.  
Am I missing something on how to define the table in the template in order to be able to access send()?

I am grateful for any pointer!  
Cheers  
JR

---

<div class="post-metadata">

**Author:** ![knoepsche](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knoepsche/32/69450_2.png) [@knoepsche](https://discourse.nodered.org/u/knoepsche)\
**Post date:** [12 December 2022 21:23 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789/2 "2022-12-12T21:23:47Z")

</div>

One way to get `scope.send()` is to define the click handler inside the `(function(scope){...})(scope)` code:

```auto
<div id="example-table2"></div>
<script>
    var tabledata = [
        {id:0, pos:0, age:"1"},
        {id:1, pos:1, age:"12"},
        {id:2, pos:2, age:"1"},
        {id:3, pos:3, age:"42"},
        {id:4, pos:4, age:"11"},
    ];
    
    var table = new Tabulator("#example-table2", {
     	data:tabledata, //assign data to table
     	index:"id", // set the field which serves as index for tabulator
     	layout:"fitColumns", //fit columns to width of table (optional)
     	columns:[ //Define Table Columns
     	    {title:"ID", field:"id", width:60},
    	 	{title:"Position", field:"pos", width:150},
    	 	{title:"Age", field:"age", hozAlign:"left", formatter:"progress",headerSort:false}
     	]
    });
    
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // CUSTOM FUNCTIONS
    function getLastTableIndex(myTable){
        var last_id = Math.max.apply(Math, myTable.getRows().map(function(o) { return o.getIndex(); }));
        if(!Number.isFinite(last_id)) last_id = -1;
        
        return last_id;
    };
    
    
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // INTERACTION FUNCTIONS
    //This is needed to interact with Node-Red when a message is sent to the ui-template.
    (function(scope){
        
        // // TODO replace with code that does what you want ot happen everytime you click anywhere in a row
        table.on("cellClick", function(e, cell){ 
         	scope.send({topic:"cellClick", payload:cell.getData()});
        });

        
        scope.$watch('msg', function(msg){
            if(msg){
                //do something here when a message arrives like table.setData();
                if(msg.hasOwnProperty("payload")){
                    if(msg.payload.hasOwnProperty("cmd") && msg.payload.hasOwnProperty("arg")){
                        switch(msg.payload.cmd){
                            case "getTableData":
                                scope.send({payload:table.getData()});
                                break;
                            case "getLastId":
                                scope.send({payload:getLastTableIndex(table)});
                                break;
                        }
                    }
                }
            }
        });
        
    })(scope);
</script>

```

---

<div class="post-metadata">

**Author:** ![bs-eng](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bs-eng/32/51470_2.png) [@bs-eng](https://discourse.nodered.org/u/bs-eng)\
**Post date:** [13 December 2022 13:08 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789/3 "2022-12-13T13:08:50Z")

</div>

Hi Knoepsche!  
Does that mean that once I define the click handler, that I get scope.send() also in other sections of the code?  
My target was to use the send funtion inside the tabulator event-handlers, like cellEdited.  
How would I achieve that?  
Thanks!

---

<div class="post-metadata">

**Author:** ![knoepsche](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knoepsche/32/69450_2.png) [@knoepsche](https://discourse.nodered.org/u/knoepsche)\
**Post date:** [13 December 2022 18:32 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789/4 "2022-12-13T18:32:28Z")

</div>

How about packing your whole code into the scope? This way you always get the scope from inside your table:

```auto
<div id="example-table2"></div>
<script>
    
    (function(scope){
    
    // // TODO replace with code that does what you want ot happen everytime you click anywhere in a row
    // table.on("rowClick", function(e, row){
    // scope.send({payload:"test"});
    // });
    
    scope.tabledata = [
        {id:0, pos:0, age:"1"},
        {id:1, pos:1, age:"12"},
        {id:2, pos:2, age:"1"},
        {id:3, pos:3, age:"42"},
        {id:4, pos:4, age:"11"},
    ];
    
    scope.table = new Tabulator("#example-table2", {
        data:scope.tabledata, //assign data to table
        index:"id", // set the field which serves as index for tabulator
        layout:"fitColumns", //fit columns to width of table (optional)
        columns:[ //Define Table Columns
            {title:"ID", field:"id", width:60},
            {title:"Position", field:"pos", width:150},
            {title:"Age", field:"age", hozAlign:"left",
            formatter:"progress",headerSort:false,cellClick:function(e,cell){scope.send({payload:"testcell"})}}
        ],
    });
    
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // CUSTOM FUNCTIONS
    scope.getLastTableIndex = function(myTable){
        var last_id = Math.max.apply(Math, myTable.getRows().map(function(o) { return o.getIndex(); }));
        if(!Number.isFinite(last_id)) last_id = -1;
        return last_id;
    };
    
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // INTERACTION FUNCTIONS
    //This is needed to interact with Node-Red when a message is sent to the ui-template.
    
        scope.$watch('msg', function(msg){
            if(msg){
                //do something here when a message arrives like table.setData();
                if(msg.hasOwnProperty("payload")){
                    if(msg.payload.hasOwnProperty("cmd") && msg.payload.hasOwnProperty("arg")){
                        switch(msg.payload.cmd){
                            case "getTableData":
                                scope.send({payload:scope.table.getData()});
                                break;
                            case "getLastId":
                                scope.send({payload:scope.getLastTableIndex(scope.table)});
                                break;
                        }
                    }
                }
            }
        });
        
    })(scope);
</script>

```

---

<div class="post-metadata">

**Author:** ![bs-eng](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bs-eng/32/51470_2.png) [@bs-eng](https://discourse.nodered.org/u/bs-eng)\
**Post date:** [14 December 2022 11:32 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789/5 "2022-12-14T11:32:26Z")

</div>

Thank you so much!  
I totally overlooked this simple approach.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [13 January 2023 11:32 UTC](https://discourse.nodered.org/t/how-to-send-a-message-out-of-ui-template-using-tabulator/71789/6 "2023-01-13T11:32:56Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
