Read data from a table

I want to make a table on dashboard and allow user to input simple data such as dimension of boxes, eg,

           Length      Width     Height

Box 1 20 12 7
Box 2 23 9 6

Ideally there is a button to add lines after finishing last one. And after submitting, Node-red is able to read like
{
"Box 1":{
"Length" : 20,
"Width" : 12,
"Height" : 7},
"Box 2":{
"Length" : 23,
"Width" : 9,
"Height" : 6}
}

Is it possible to do it in Node-Red? or any workaround for this?

Hello Anguslou,

Your question is very generic and broad and you havent shared some example flow of what you have tried in order to give a person the motivation to help you with your question.

A quick search on the internet for programmatically adding rows to a table with input fields brings us to this interesting example.

With a few jquery code modifications and adding an extra button to send the data to Node-red ...

Example Flow :

[{"id":"2909790fd013a2b3","type":"ui_template","z":"4895ea10b4ee9ead","group":"fe8bd71ec6128157","name":"","order":0,"width":"27","height":"24","format":"<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <title>My Boxes</title>\n    <style>\n        form {\n            margin: 20px 0;\n        }\n\n        form input {\n            padding: 5px;\n        }\n\n        button {\n            padding: 5px;\n            width: 200px;\n        }\n\n        table {\n            width: 100%;\n            margin-bottom: 20px;\n            border-collapse: collapse;\n        }\n\n        table,\n        th,\n        td {\n            border: 1px solid #cdcdcd;\n        }\n\n        table th,\n        table td {\n            padding: 10px;\n            text-align: left;\n        }\n    </style>\n    <!-- <script src=\"https://code.jquery.com/jquery-3.5.1.min.js\"></script> -->\n    <script>\n\n        let nr = scope;\n\n        $(document).ready(function(){\n        $(\".add-row\").click(function(){\n            var id = $(\"#id\").val();\n            var length = $(\"#length\").val();\n          var width = $(\"#width\").val();\n          var height = $(\"#height\").val();\n            var markup = \"<tr><td><input type='checkbox' name='record'></td><td>\" + id + \"</td><td>\" + length + \"</td><td>\" + width + \"</td><td>\" + height + \"</td></tr>\";\n            $(\"table tbody\").append(markup);\n        });\n        \n        // Find and remove selected table rows\n        $(\".delete-row\").click(function(){\n            $(\"table tbody\").find('input[name=\"record\"]').each(function(){\n            \tif($(this).is(\":checked\")){\n                    $(this).parents(\"tr\").remove();\n                }\n            });\n        });\n\n        // Send data of selected table rows to Node-red\n        $(\".submit-btn\").click(function(){\n            let data = []\n            $(\"table tbody\").find('tr').each(function(tr){\n                  data.push( {\n                    id: Number(this.children[1].innerText),\n                    length: Number(this.children[2].innerText), \n                    width: Number(this.children[3].innerText), \n                    height: Number(this.children[4].innerText), })\n            });\n            console.log(data)\n            nr.send({payload: data})  // send to NR\n        });\n\n\n        \n    });    \n    </script>\n</head>\n\n<body>\n    <form>\n        <input type=\"number\" id=\"id\" placeholder=\"Box id\">\n        <input type=\"text\" id=\"length\" placeholder=\"Length\">\n        <input type=\"text\" id=\"width\" placeholder=\"Width\">\n        <input type=\"text\" id=\"height\" placeholder=\"Height\">\n        <input type=\"button\" class=\"add-row\" value=\"Add Box\">\n    </form>\n    <table>\n        <thead>\n            <tr>\n                <th>Select</th>\n                <th>Box id</th>\n                <th>Length</th>\n                <th>Width</th>\n                <th>Height</th>\n            </tr>\n        </thead>\n        <tbody>\n            <!-- \n             Rows will be injected here with jquery\n             -->\n        </tbody>\n    </table>\n    <div>\n        <button type=\"button\" class=\"delete-row\">Delete Selected Boxes</button>\n        <button type=\"button\" class=\"submit-btn\">Submit to Node Red</button>\n    </div>\n</body>\n\n</html>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":460,"y":640,"wires":[["086622824c1db941"]]},{"id":"086622824c1db941","type":"debug","z":"4895ea10b4ee9ead","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":690,"y":640,"wires":[]},{"id":"fe8bd71ec6128157","type":"ui_group","name":"Default","tab":"5276339eb38c4054","order":1,"disp":true,"width":"27","collapse":false},{"id":"5276339eb38c4054","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
1 Like

This is excellent, thank you.

Hi .. i worked a little bit more on the table layout to make it a little bit more presentable ..
here's a newer version

[{"id":"2909790fd013a2b3","type":"ui_template","z":"4895ea10b4ee9ead","group":"fe8bd71ec6128157","name":"","order":1,"width":30,"height":17,"format":"<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\" />\n    <title>My Boxes</title>\n    <style>\n        input {\n            padding: 5px;\n            width: 80%;\n        }\n\n        .warning {\n            border-bottom-color: red;\n            border-bottom-width: 3px;\n        }\n\n        button {\n            padding: 5px;\n            width: 200px;\n        }\n\n        table {\n            width: 100%;\n            margin-bottom: 20px;\n            border-collapse: collapse;\n        }\n\n        table,\n        th,\n        td {\n            border: 1px solid #cdcdcd;\n        }\n\n        table th,\n        table td {\n            padding: 10px;\n            text-align: center;\n        }\n    </style>\n    <script>\n        (function (scope) {\n        $(\".add-row\").click(function () {\n          var id = $(\"#id\").val();\n          var length = $(\"#length\").val();\n          var width = $(\"#width\").val();\n          var height = $(\"#height\").val();\n          var markup = `<tr>\n          <td><input type='checkbox' name='record'></td>\n            <td>${id}</td>\n            <td>${length}</td>\n            <td>${width}</td>\n            <td>${height}</td>\n            </tr>`;\n          $(\"table tbody\").append(markup);\n          $(\"input\").val(\"\"); // clear all inputs\n        });\n\n        // Find and remove selected table rows\n        $(\".delete-row\").click(function () {\n          $(\"table tbody\")\n            .find('input[name=\"record\"]')\n            .each(function () {\n              if ($(this).is(\":checked\")) {\n                $(this).parents(\"tr\").remove();\n              }\n            });\n        });\n\n        // Send data of selected table rows to Node-red\n        $(\".submit-btn\").click(function () {\n          let data = [];\n          $(\"table tbody\")\n            .find(\"tr\")\n            .each(function (tr) {\n              data.push({\n                id: Number(this.children[1].innerText),\n                length: Number(this.children[2].innerText),\n                width: Number(this.children[3].innerText),\n                height: Number(this.children[4].innerText),\n              });\n            });\n          console.log(data);\n          scope.send({ payload: data }); // send to NR\n        });\n      })(scope);\n    </script>\n</head>\n\n<body>\n    <button type=\"button\" class=\"add-row\" style=\"margin-bottom: 20px; margin-left: auto\">\n      <i class=\"fa fa-plus-circle\"></i>\n      Add Box\n    </button>\n    <!-- <input type=\"button\" class=\"add-row\" value=\"Add Box\"> -->\n    <table>\n        <thead>\n            <tr>\n                <th style=\"width: 50px\">Select</th>\n                <th><input type=\"number\" id=\"id\" placeholder=\"Box id\" /></th>\n                <th><input type=\"text\" id=\"length\" placeholder=\"Length\" /></th>\n                <th><input type=\"text\" id=\"width\" placeholder=\"Width\" /></th>\n                <th><input type=\"text\" id=\"height\" placeholder=\"Height\" /></th>\n            </tr>\n        </thead>\n        <tbody>\n            <!-- \n             Rows will be injected here with jquery\n             -->\n        </tbody>\n    </table>\n    <div>\n        <button type=\"button\" class=\"delete-row\">Delete Selected Boxes</button>\n        <button type=\"button\" class=\"submit-btn\">Submit to Node Red</button>\n    </div>\n</body>\n\n</html>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":340,"y":480,"wires":[["086622824c1db941"]]},{"id":"086622824c1db941","type":"debug","z":"4895ea10b4ee9ead","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":510,"y":480,"wires":[]},{"id":"fe8bd71ec6128157","type":"ui_group","name":"Boxes","tab":"5276339eb38c4054","order":1,"disp":true,"width":"30","collapse":false},{"id":"5276339eb38c4054","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

[EDIT] fixed scope

The codes work perfectly. However every time after deploying and I enter data, it doesn't update to the table by clicking "Add Box" until I restart Node-Red, any idea?

you are right .. i think it was related to the line var nr = scope; but on second deploy i noticed an error that the variable was already declared. anyway using the official way of using scope seems to fix the issue.
I edited my above post not to have yet another version.

1 Like

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