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}]