Node-red-contrib-ui-svg create table by input message

@samuelbras,
I was wondering whether it would have been easier to add a HTML table as a foreign element inside the SVG drawing. So I am now talking about option 2 mentioned above.

Seemed tonight that this was not possible, because the add_element command only allowed to create SVG elements (which have their own namespace). I have added a fix on Github to allow non-SVG elements to be created, by adding a foreignElement=true to the input message. That allows to create standard HTML elements, like e.g. a <tr> element for a table row.

The example flow contains this SVG drawing of a board, and I have added a standard HTML table as a foreign object to that SVG drawing:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" height="263" viewBox="0 0 263 263" width="263">
  <g>
    <path d="M257.333,25.497h-32.867c0.124-0.48,0.196-0.98,0.196-1.499c0-3.313-2.687-6-6-6h-46.51
		c0.012-0.161,0.025-0.321,0.025-0.485c0-3.581-2.904-6.485-6.485-6.485h-68.05c-3.581,0-6.485,2.903-6.485,6.485
		c0,0.164,0.013,0.324,0.025,0.485h-46.51c-3.313,0-6,2.687-6,6c0,0.518,0.073,1.019,0.196,1.499H6c-3.314,0-6,2.686-6,6v148.492
		c0,3.313,2.686,6,6,6h115.926l-34.101,57.244c-1.696,2.847-0.763,6.53,2.084,8.226c2.848,1.696,6.53,0.763,8.226-2.084
		l27.532-46.217v33.019c0,3.313,2.687,6,6,6s6-2.687,6-6v-33.019l27.532,46.217c1.123,1.884,3.116,2.93,5.161,2.93
		c1.044,0,2.103-0.273,3.065-0.846c2.847-1.696,3.78-5.378,2.084-8.226l-34.101-57.244h115.926c3.314,0,6-2.687,6-6V31.497
		C263.333,28.183,260.647,25.497,257.333,25.497z M251.333,173.989H12V37.497h239.333V173.989z" />
  </g>
  <foreignObject x="30" y="50" width="200" height="110">
    <table style="width: 100%; border:2px solid;text-align:left">
      <colgroup>
        <col span="1" style="width: 70%;">
        <col span="1" style="width: 30%;">
      </colgroup>
      <tbody id="mytable">
        <tr>
          <th style="font-weight: bolder;text-decoration: underline">Room</th>
          <th style="font-weight: bolder;text-decoration: underline">°C</th>
        </tr>
        <tr>
          <td>Kitchen</td>
          <td>21</td>
        </tr>
      </tbody>
    </table>
  </foreignObject>
</svg>

Now we can add dynamically a table row, by injecting a message that creates a tr HTML element as a child of the table body (with id "mytable"). The table row (tr) contains two table cells (td):

{
    "command": "add_element",
    "elementType": "tr",
    "textContent": "<td>Bathroom</td><td>22</td>",
    "parentElementId": "mytable",
    "foreignElement": true
}

Which results in this:

svg_table

Here is the entire flow:

image

[{"id":"ac37cc973bbb46fe","type":"ui_svg_graphics","z":"3f01ab2a1bf97f25","group":"3ce32370.c60f1c","order":11,"width":"18","height":"10","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0\" y=\"0\" height=\"263\" viewBox=\"0 0 263 263\" width=\"263\">\n  <g>\n    <path d=\"M257.333,25.497h-32.867c0.124-0.48,0.196-0.98,0.196-1.499c0-3.313-2.687-6-6-6h-46.51\n\t\tc0.012-0.161,0.025-0.321,0.025-0.485c0-3.581-2.904-6.485-6.485-6.485h-68.05c-3.581,0-6.485,2.903-6.485,6.485\n\t\tc0,0.164,0.013,0.324,0.025,0.485h-46.51c-3.313,0-6,2.687-6,6c0,0.518,0.073,1.019,0.196,1.499H6c-3.314,0-6,2.686-6,6v148.492\n\t\tc0,3.313,2.686,6,6,6h115.926l-34.101,57.244c-1.696,2.847-0.763,6.53,2.084,8.226c2.848,1.696,6.53,0.763,8.226-2.084\n\t\tl27.532-46.217v33.019c0,3.313,2.687,6,6,6s6-2.687,6-6v-33.019l27.532,46.217c1.123,1.884,3.116,2.93,5.161,2.93\n\t\tc1.044,0,2.103-0.273,3.065-0.846c2.847-1.696,3.78-5.378,2.084-8.226l-34.101-57.244h115.926c3.314,0,6-2.687,6-6V31.497\n\t\tC263.333,28.183,260.647,25.497,257.333,25.497z M251.333,173.989H12V37.497h239.333V173.989z\" />\n  </g>\n  <foreignObject x=\"30\" y=\"50\" width=\"200\" height=\"110\">\n    <table style=\"width: 100%; border:2px solid;text-align:left\">\n      <colgroup>\n        <col span=\"1\" style=\"width: 70%;\">\n        <col span=\"1\" style=\"width: 30%;\">\n      </colgroup>\n      <tbody id=\"mytable\">\n        <tr>\n          <th style=\"font-weight: bolder;text-decoration: underline\">Room</th>\n          <th style=\"font-weight: bolder;text-decoration: underline\">°C</th>\n        </tr>\n        <tr>\n          <td>Kitchen</td>\n          <td>21</td>\n        </tr>\n      </tbody>\n    </table>\n  </foreignObject>\n</svg>","clickableShapes":[],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":true,"showBrowserEvents":true,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"noClickWhenDblClick":false,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"name":"","x":660,"y":80,"wires":[[]]},{"id":"41fc31c058631fe9","type":"inject","z":"3f01ab2a1bf97f25","name":"Add table row","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"command\":\"add_element\",\"elementType\":\"tr\",\"textContent\":\"<td>Bathroom</td><td>22</td>\",\"parentElementId\":\"mytable\",\"foreignElement\":true}","payloadType":"json","x":430,"y":80,"wires":[["ac37cc973bbb46fe"]]},{"id":"3ce32370.c60f1c","type":"ui_group","name":"Demo","tab":"d74bbed4.c2cfb","order":2,"disp":false,"width":"18","collapse":false},{"id":"d74bbed4.c2cfb","type":"ui_tab","name":"Demo","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Note that I quickly created this example flow, and I can improved a lot: scrollbars, fixed headers during scrolling, fixed number of visible rows ... So if anybody wants to improve the example flow and share it here, that would be nice!

P.S. The fix is not available on NPM yet. So if you want to test this, you need to install the fixed svg node directly from Github using this command (from within your .node-red folder):

npm install bartbutenaers/node-red-contrib-ui-svg
1 Like