Dynamic HTML content in ui-template

I have a code where I can download a file which is stored on the Node-Red server (not in the static folder).
In DB1, I had a template node, to which could pass a HTML code which triggered my file download:

    msg.template = "<script>window.open('" + encodeURIComponent(lastselected[0].downloadlink) + "', '_blank');</script>";
    return msg;

The download link points to a http-in endpoint which handles the file download.

In DB2, I only send the downloadlink in the in msg.payload, and I wanted to trigger the window.open like this. This is all the code in the template node:

<script>
    export default {
        data() {
            return {
            }
        },
        watch: {
            msg: function() {
                if(this.msg.payload != undefined){
                    this.window.open(this.msg.payload, '_blank');
                }
            }
        }
    }
</script>

Nothing happens. I can see an error in the debugger: "Cannot read properties of undefined (reading 'open')". So I guess window is not available in the script section?

Let me have a second question on this:
I want to display a text file in DB2. Back in DB1, I created the entire <div>...</div> source code in a function node, HTML encoded the text to be displayed and replaced the line feed to <br/>.

I would like to do the same in a template node, inside for example in a v-card. I added this

...
        <v-card-text>
            <div>{{ content }}</div>
        </v-card-text>
...

Vue takes care of the HTML encoding, but I cannot get it to add line breaks. If I just pass the file content, line break is ignored. If I replace the line break with <br/> it is printed on the screen as it is. Is there a trick for this?

And the last question:
I want to display an image in DB2, but the image file is not stored in the static folder. In DB1, I read the file, base64 encoded it and generated an 'img' tag with inline base 64 source of the image. Probably not nice, but got the job done.
Would anything like this would be remotely possible in Vue? I guess I cannot put the base64 source to the v-img tag?

The only time that window should be attached to a this should be globalThis. I assume that you already tried it without the this.

The alternative would be to use this example of raw javascript Text ui-template | Node-RED Dashboard 2.0. I have confirmed that it works well and you can easily listen to messages and handle them.

I do something similar in a "ui-scoped widget" so that when i send a custom message from my authentication middleware to the socket it can then respond by reloading the dashboard which will trigger a reroute to the login page.

<script>
  this.$socket.on('window.location.reload', (msg) => {
    window.location.reload(msg);
  });
</script>

To allow html tags such as <br/> in content use
<div v-html="content"></div>
where content is a computed function.

Thanks for the tip @Colin, this works just great!

Ups, I think I did not. Works just fine with this. Thanks for pointing this out.

1 Like

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