# Reproducing a D1 Dashboard using UIBUILDER?

**URL:** <https://discourse.nodered.org/t/reproducing-a-d1-dashboard-using-uibuilder/99408>\
**Category:** Dashboard\
**Tags:** uibuilder\
**Created:** [15 October 2025 18:30 UTC](https://discourse.nodered.org/t/reproducing-a-d1-dashboard-using-uibuilder/99408 "2025-10-15T18:30:58Z")\
**Posts on this page:** 3\
**Page:** 2

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [25 October 2025 19:01 UTC](https://discourse.nodered.org/t/reproducing-a-d1-dashboard-using-uibuilder/99408/21 "2025-10-25T19:01:55Z")

</div>

> [@ChZeman](#):
>
> I have all my data showing and updating a single table. One of the things I need to figure out is how to set a dark theme, meaning I need to delve into css in uibuilder.

You can simply set your browser to prefer dark mode. Or simply add `class="dark"` to the `html` tag in your `index.html` file.

You might need to prompt me again in a few weeks to improve the documentation - screen time very limited for a couple of weeks while I recover from a 2nd eye operation (in the end, had ot have both eyes operated on).

> [@ChZeman](#):
>
> One question I have... Can I dynamically set data-row-name to the name of each ride instead of the row number? The reason I ask is because I have a number of rides I don't want to display unless a fault exists and my thought is that removing a row by name would be easier than determining what row number that ride is. I might be thinking about this the wrong way, too.

The easiest way to do that is to use an `object` as the input rather than an `array`. The input object's 1st level property names should appear in the resulting HTML. I think that is the case anyway, let me know if it isn't and I will fix in the next release.

> [@MyRandomThoughts](#):
>
> UIB just seems very complicated to me, and like OP it could just be mental block to get it working.

Have you watched any of the videoa or used either the new quick start or the previous first walkthrough in the documentation? The new [quick-start document](https://totallyinformation.github.io/node-red-contrib-uibuilder/#/using/quickstart) may be of particular help

> [@MyRandomThoughts](#):
>
> I do have some complex layouts though, so I am not even sure it's possible to replicated in UIB.

You can create far more complex layouts far easier than in D1 or D2 since you don't have to fight the frameworks. Of course, it does generally require a little HTML/CSS knowledge to do so. Some common example layouts are included in the documentation and example flows.

A dashboard style layout is one of the provided examples and I use it regularly myself. The trick is to use "semantic" style HTML and a couple of provided classes. You will find the standard `<article>` to be your special friend as the default CSS formats it as a _card_ that can hold any content. You can put that in a container tag such as `<main>` or `<section>` and tag it with a class to turn the container into a grid (or, of course, create your own custom grid style class)

> [@MyRandomThoughts](#):
>
> This is one of them, sized for mobile usage, it's a music controller.

That isn't especially complex and is perfect for a grid styled container. I would provide an example but unfortunatley,, I'm recovering from operations on both eyes just now. If you prompt me again in a couple of weeks, I will knock something up to help if you like.

> [@ChZeman](#):
>
> My only challenge now is figuring out how to play audio. I've been doing a lot of searching but coming up empty-handed.

> **[: The Embed Audio element - HTML | MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/audio)**
>
> The HTML element is used to embed sound content in documents. It may contain one or more audio sources, represented using the src attribute or the element: the browser will choose the most suitable one.
> It can also be the destination for streamed...

If using UIBUILDER, you can use the `uib-tag` node to help build that from Node-RED if you don't want to write any HTML directly. However, I would generally recommend that you simply write the HTML if it is static, the zero-code UIBUILDER nodes (rather like D1/D2) are great to quickly get going but eventually, you will generally find yourself simply wanting the simple code anyway (the big difference between uibuilder and D1/D2 is that its zero-code nodes result in actual native HTML which you can save into your static `index.html` file for ongoing amendments and best performance).

You can choose whether to send the audio as data from Node-RED to a uibuilder front-end (though take note of message sizes if your audio is long) or simply use the `uib-save` node to save an audio file from node-red to a static file that the front end can use.

> [@ChZeman](#):
>
> I used a read file node to read "alarm.wav" and sent it to an "audio out" D1 node while the error message text was sent to [elevenlabs.io](http://elevenlabs.io). The file returned by [elevenlabs.io](http://elevenlabs.io) was then read using another read file node and sent to the audio out node. The audio out node was the only D1-dependent part of the flow. It worked well. I just need to figure out how to control an audio element in uibuilder.

To translate that to uibuilder, you simply need to use the `uib-save` node to output the TTS file if it is too large to be sent as a message. THe standard alarm.wav should simply be put into the same folder as your index.html file (uib-save simply makes it easier to know where the folder is - there is nothing special other than that).

Triggering the play automatically generally requires that the user has taken some kind of action on the page - check out the link that I shared, it should have the details.

I think I shared an example using video a long time ago - it is basically the same as audio.

---

<div class="post-metadata">

**Author:** ![ChZeman](https://avatars.discourse-cdn.com/v4/letter/c/76d3ee/32.png) [@ChZeman](https://discourse.nodered.org/u/ChZeman)\
**Post date:** [25 October 2025 19:37 UTC](https://discourse.nodered.org/t/reproducing-a-d1-dashboard-using-uibuilder/99408/22 "2025-10-25T19:37:10Z")

</div>

I actually got the audio issue figured out shortly after I posted that, thanks to an AI summary during a [google search](https://www.google.com/search?client=firefox-b-1-d&q=uibuilder+node+red+Audio()&udm=50&fbs=AIIjpHxU7SXXniUZfeShr2fp4giZud1z6kQpMfoEdCJxnpm_3WBcADgXS0kQ7L92bqYkFCGs4piG0mmPDgZFV1TtUMvZh4b_hOslSO4BbJRk_Rm0e5nkOROTp-nvSsweko3de40ZvCbPf7ZhPfiXAADLufz7zIgFO1D2S8ntKfFlzOqCXF8hEU_ysGpw5LuBfi40A0ywRhjA05aD4GPvJ6DmkPcsOg1pQQ&ved=2ahUKEwiE5I6M4r-QAxUOv4kEHakSJSEQ0NsOegQIJhAA&aep=10&ntc=1&mstk=AUtExfBuVZYUPLywbU_tH4x87lt-iBGalP013EOfxSHObfOwYBsLrxtxciq28hPVdld5QH9V8_-NXw-A0-upnphLFHhrCfBDRzzXMNTeLmh46Uj6evB3my7hR7ICBVGNhTUb4vpr1wK8GbYad6oBPcF_SZ1LxQFElxetwmRp2RKcZrPulbBNDtRKuVqp7-wVKVzHOmP5uQ7-EBIieQy04-IIgsOiCAuSe_MxEQGAJJYJ_1uIboCgmlyl4dibPA&csuir=1). 😀 I just didn't have a chance to post the solution yet.

I switched to the Vue3 template and then added...

```auto
<audio id="myAudioPlayer"></audio>

```

...to index.html. I then added...

```auto
// Listen for incoming messages from the Node-RED server
uibuilder.onChange('msg', function (msg) {
    // Get a reference to the audio player
    const audioPlayer = document.getElementById('myAudioPlayer');

    // Check if the message has a specific topic and a payload
    if (msg.topic === 'play' && msg.payload) {
        // Set the audio source to the URL from the payload
        audioPlayer.src = msg.payload;
        // Play the audio
        audioPlayer.play();
    } else if (msg.topic === 'stop') {
        // Stop and clear the audio source
        audioPlayer.pause();
        audioPlayer.src = '';
    }
});

```

...to index.js.

I uploaded Alarm.wav to the src folder (as you indicated) and send...

```auto
msg.payload = "Alarm.wav"
msg.topic = "play"

```

...when a downtime occurs. I then send the alarm description to [elevenlabs.io](http://elevenlabs.io) using TTS-Ultimate, configured to save the files in a subdirectory of the src folder, parse the filename from the output and do the same thing I'm doing to play Alarm.wav. It's working really well!

I'll experiment tonight with sending the table data as an object instead of an array. Thanks again!

---

<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:** [24 November 2025 19:37 UTC](https://discourse.nodered.org/t/reproducing-a-d1-dashboard-using-uibuilder/99408/23 "2025-11-24T19:37:54Z")

</div>

Closed on 24 November 2025 19:37 UTC

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

[Previous page](https://discourse.nodered.org/t/reproducing-a-d1-dashboard-using-uibuilder/99408.md?page=1)
