Uibuilder, dynamically add a component with Vue.js

Hi all,

maybe it's a silly question and it's quite easy, but I have absolutely zero knowledge about Vue.js.
Imagine I want to design a questionnaire with Node-Red and Uibuilder.

To achive this I have a state in my flow and according to that state I want to dynamically spawn different components for each state. So, my html / index.js should only be some kind of master template (the general layout), and I'd like to add components (buttons, textboxes, etc) at runtime.

Whats the right way to achive this?

Thanks!

Alex

Hi Alex, welcome to the community.

It isn't a silly question and it isn't that easy (to get your head around) and it does require some knowledge of VueJS.

However, this isn't really a Node-RED question.

I've not done it myself because the more common case is to have pre-defined components that you turn on/off dynamically which is very simple.

Try this article maybe:

Of course, uibuilder does not limit you to VueJS, that is merely a convenience for people who don't want to tweak things.

So you might find it easier in this case to use something like jQuery instead? You can install jQuery via uibuilder's library handler and then swap the front-end code in index.(html, js) over to the examples from the WIKI and then build from there.

1 Like

Are these components you'd like to add predefined somewhere, or do you plan on adding the code for those components at runtime/generate them too? I've been down that last route before, and my paper notebook was a big friend on that issue, but it's been a once-and-never-again approach for me. (Use case: a WebExtensions based browser extension that would insert a vue application into a specific webpage, and allow components to be added through an extension framework into the extension itself (stored in indexeddb of the browser), and the vue application extended that way. Note that this is a security risk, don't replicate this solution please, as I've since abandoned it for that exact same reason :slight_smile:)

It sounds like what you're doing could be accomplished through the use of dynamic components, or even easier, through components that are conditionally rendered.
Dynamic components are explained here in the Vue docs: https://vuejs.org/v2/guide/components.html#Dynamic-Components
The idea is that in your master template you define positions where components will be rendered, and these specific components can be switched up. The exact component that is stored is kept in variables on the Vue app.
The more advanced aspects of it are described here: https://vuejs.org/v2/guide/components-dynamic-async.html
That second page also show how to work with async components, which can be combined with the vue-http-loader.

In your situation of a questionnaire, I think you could accomplish this by using a combination of conditional rendering and the above dynamic/async components. The state in your flow can be connected to the Vue app through the mounted() function, in which you can listen to updates on uibuilder incoming messages, uibuilder.onChange('msg', function(newMsg) {...}) I believe it is (writing this from mind, please check it with the docs to confirm). newMsg here would contain the same properties the incoming message object into the uibuilder node would have, which you could manipulate. On runtime, pass the state in your flow as incoming message to uibuilder, and act on it by rendering parts of the page in a way you would like.

I hope that helps you a bit along.

2 Likes

Hi all,

thanks for your reply, I appreciate your effort to help me.
Well, the typ of component does exist (e.g. a button), but I'd like to create an instance of it during runtime, specify its position, color, and of course the callback for handlers etc.

Thats the simplest example I can think of, and thats what I basically need. I usually do application programming (win32) and it's just confusing to switch to web development, and maybe thats my problem here.

So, I checked the links both of you mentioned - and maybe it's indeed easier to have everything already in place and render it conditionally - or just show/hide components.

So, is that "good practice" in Vue.js (or other web development)? You layout everything, and just render (show/hide) components?

Thanks :wink:

Alex

Well, it works for certain types of interface and is doubtless the most common type. Completely dynamic interfaces are very hard to achieve which I guess is why many people try to avoid them. But certainly possible if that's what you need.

I think that I would try to build something a bit more static to start with and then use dynamic loading if/when you really need to and maybe have a little more experience. Or, if it just isn't working for you, don't battle on, it is easy enough to do a fully dynamic interface in jQuery as it isn't trying to force you into a particular framework as much. Of course, in that case, your JavaScript code is going to end up being much more complex over time - though it should start easily enough.

1 Like

Thanks, I'll try that and just figure out what fits best in my scenario.

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