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

**URL:** https://discourse.nodered.org/t/node-red-contrib-ui-svg-create-table-by-input-message/51004
**Category:** General
**Created:** [14 September 2021 10:04 UTC](https://discourse.nodered.org/t/node-red-contrib-ui-svg-create-table-by-input-message/51004 "2021-09-14T10:04:29Z")
**Posts on this page:** 1
**Showing post:** 11

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [6 October 2021 21:39 UTC](https://discourse.nodered.org/t/node-red-contrib-ui-svg-create-table-by-input-message/51004/11 "2021-10-06T21:39:12Z")

</div>

@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](https://www.svgrepo.com/svg/134455/board) SVG drawing of a board, and I have added a standard HTML table as a foreign object to that SVG drawing:

```auto
<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):

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

```

Which results in this:

![svg_table](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/0/c021d47f3c2329d9dea59577e68e8c8ce7a305f8.gif)

Here is the entire flow:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/9/0946932af0956287871b1a263cce17d6a9d70a3f.png)

```auto
[{"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):

```auto
npm install bartbutenaers/node-red-contrib-ui-svg

```

---

_[View the full topic](https://discourse.nodered.org/t/node-red-contrib-ui-svg-create-table-by-input-message/51004)._
