Show two Payloads on a Website (Uibuilder)

Hello,
I don't know any way to display two received values in the appropriate place on the index1.html website. I am using uibuilder for this.

I currently receive both values under id="msg" but would like to display them in the correct place:

However, I would like to have the payload value of topic value1 displayed accordingly on the at id="Wert1" and the same for value2 (id="Wert2").

          <div class="inner">

            <h3 id="Wert1">Wert1</h3>

            <p>New Orders</p>

          </div>

          <div class="icon">

            <i class="ion ion-bag"></i>

          </div>

          <a href="#" class="small-box-footer">More info <i class="fas fa-arrow-circle-right"></i></a>

        </div>

      </div>

      <!-- ./col -->

      <div class="col-lg-3 col-6">

        <!-- small box -->

        <div class="small-box bg-success">

          <div class="inner">

            <h3 id="Wert2">Wert2</h3>

Do I have to put this in the index.js file or on the website index1.html to be displayed.

Current index.js

// run this function when the document is loaded

window.onload = function() {

// Start up uibuilder - see the docs for the optional parameters

uibuilder.start()

// Listen for incoming messages from Node-RED

uibuilder.onChange('msg', function(msg){

    console.info('[indexjs:uibuilder.onChange] msg received from Node-RED server:', msg)

    // dump the msg as text to the "msg" html element

    const eMsg = document.getElementById('msg')

    eMsg.innerHTML = syntaxHighlight(msg)

})

}

Thanks a lot.

you can try to dynamically getElementById based on topic
im not exactly sure where you want the payload to appear but here's an example

// Listen for incoming messages from Node-RED
    uibuilder.onChange('msg', function(msg){
        console.info('[indexjs:uibuilder.onChange] msg received from Node-RED server:', msg)

        // dump the msg as text to the "msg" html element
        const eMsg = document.getElementById(`${msg.topic}`) // dynamically getElementById based on topic 
        eMsg.innerHTML = `${msg.topic} - ${msg.payload}`  // format string
    })
1 Like

Hey, thanks for your answer.
I want to insert the payload from topic = Wert1 on the website under
id="Wert1"

With your help I have completed the code and now it works :slight_smile:

// Listen for incoming messages from Node-RED

    uibuilder.onChange('msg', function(msg){

        console.info('[indexjs:uibuilder.onChange] msg received from Node-RED server:', msg)

        // dump the msg as text to the "msg" html element

        const eMsg = document.getElementById('msg')

        eMsg.innerHTML = syntaxHighlight(msg)

        // fill Wert1
        if (msg.topic == "Wert1")
        {
            Wert1.innerHTML = `${msg.payload}`; 
        }

    })

Do you have anywhere in your html an element with id 'msg' ?
i dont see one .. so the above line doesnt select any element.

you do have two h3 elements with id "Wert1" and "Wert2" respectively

so with the code i sent you that uses javascript template literals
const eMsg = document.getElementById(`${msg.topic}`)
we are dynamically selecting an element based on the received msg.topic

for example :
if the received msg has a topic "Wert1"
the above line would translate to
const eMsg = document.getElementById('Wert1')

[EDIT]
i see that you edited your post .. well .. i hope the above explanation clarifies things a bit more

1 Like

Thanks @UnborN for your detailed answer and help.

Yes, now with your explanation some things become clearer to me :).

What is wrong with document.getElementById(msg.topic)? :slight_smile:

Wert1.innerHTML = msg.payload;

No need to wrap the msg.payload in a template string,

indeed .. hehe .. i dont know why i complicated the syntax for no reason :upside_down_face:

@TotallyInformation thanks for the tip.

Do you know how I know what syntax to use?

Sorry, not sure what you mean?

msg.topic is a property within a JavaScript variable. As such you don't need to wrap it in a template string in order to use it, just use it direct. You only want the template string if you wanted to add some additional text around the variable.

I often have the problem that I generally do not know which correct syntax I have to use. In the function or also in the template node it is different than e.g. in uibuilder.
Therefore my question was, if there is a documentation for this in general, so that I can also come to this notation in Template Node by myself for example: {{msg.payload ? 'white' : 'red'}}

It isn't uibuilder that is defining the syntax, it is whatever framework you are using.

The core template node uses Mustache, the ui_template node uses Angular v1. The help information for these nodes tells you what is used.

Many of the uibuilder examples use VueJS.

However, many frameworks use syntax similar to Mustache and typically the {{ ..... }} syntax in HTML indicates that the framework is allowing you to use a single JavaScript statement or the name of a defined framework variable.

Great, thanks for the information. This info helps me a lot.

Would you recommend vue.js as a current framework if none is used yet?

BR

Yes, VueJS is pretty friendly and relatively easy to pick up. It is also (last I looked) the fasted growing framework. I have noticed even in the last week, at least 2 major enterprise suppliers using VueJS for their new user interfaces - I'm even in a procurement meeting with one of them as I type this :grinning:. You can also get going without needing a build process. Though for production use, you will most likely want to add a build so that your UI has the best performance. uibuilder currently also has some built-in helpers for VueJS such as a way to automatically show a notification in the front-end simply by sending the right data in a msg from Node-RED.

However, if you wanted to keep closer to the latest web standards, Svelte would be also a good option even though it requires a build process. It is well placed to use browser components which are a new web standard that lets you do things that previously were only possible in Node.js and/or via a build process. Both the build process and the dev server for Svelte are uibuilder friendly. It is the only dev server I've yet found that is uibuilder friendly. Though I'll be adding to the auto-refresh option in uibuilder (that currently only works when you edit from within the uibuilder node) at some point so that issue will go away eventually.

thank you very much for all the information.

Yes, the more I read in, the more I also think that it is currently the right framework for me. And if even big suppliers rely on it, it can't be a mistake. :slight_smile:

What exactly does that mean I need an additional build for the UI?
Where can I find these helpful built-in helpers?

A build process is sometimes mistakenly called a "compile" step. It is a process where you use a tool to convert some code that the framework understands but a browser does not into something that the browser understands directly. You will see this a lot in most of the frameworks. There is information on the WIKI but as you start to learn VueJS, you will see code that, for example uses file names ending with .vue and that contain statements such as import x from 'y' - neither of which are directly understood by browsers.

The build process can include other steps as well such as "minifying" your code to make it smaller and so quicker to load. It can even include a step so that you can write the latest JavaScript syntax that isn't understood by older browsers and have it converted to code that will be understood.

In these cases, you set up a build tool such as webpack or more general tools such as gulp with suitable extensions to make sense of the VueJS code and to convert it. This is why uibuilder nodes have two folders for each node - the src folder is where you keep the source and the dist folder is where your tools put the built (distributable) code.

The uibuilder WIKI has an example configuration for doing this with VueJS and webpack (I think, a while since I looked at it).

They are documented in the "Tech Docs" that you can see online or you can view via the appropriate button in a uibuilder node.

Thanks for the information to understand in a simple way what is behind Build.

I will also have a closer look at the docs.

This should be the page in the tech docs that you want:

Vue Components (totallyinformation.github.io)

Thanks for the Link.

Do you know by heart how I can create a button with on-off and a toggle button (if on, then off and reverse)?
Is this to be realized with "v-on:click.ctrl" but if so, how do I realize a toggle button? I only found this so far: Event Handling — Vue.js

Or is there a possibility, if the bit is set externally in Node-Red, to pass this signal to uibuilder and have it act on the button (a kind of external toggle).

The bootstrap-vue library has a few nice toggle-buttons

1 Like

Indeed. bootstrap-vue was chosen to use with my VueJS examples and templates because it provides a really nice environment and visuals with minimal boilerplate code. It can also be used without a build step so is really easy to use, great for people just getting going.