Uibuilder with Menu

Does anyone have a good way to menu a menu (in the html) using UI builder?

uibuilder v2 includes bootstrap-vue which already includes a nice menu. Check out the docs for bootstrap-vue.

If that doesn't meet your needs, there are plenty of other menu tools for vue. To include them you need to do one of the following:

  • Use a component that lets you load it from your html file (like the included bootstrap-vue or the chart examples in the WIKI)
  • Use http-vue-loader to dynamically load components
  • Use a build process to compile additional Vue components. Examples here or here.

Beyond just the core documentation, would you have any seriously intro level learning recommendations for web-dev novices (such as this weird bald guy I occasionally bump into when I pass by mirrors) to look into? I've been playing a bit with your default templates and while I've made some progress learning through reverse engineering the few things I've cooked up have been... amateurish at best.

Well, if you are happy to explore Vue, I would strongly recommend following some Vue tutorials.

uibuilder is nothing more (or less :smiley_cat:) than a tool to bind Node-RED processing with front-end tooling. The included Vue/bootstrap-vue is incredibly powerful and yet simple to use. Though of course, you can swap it out for any other front-end framework you want.

So the trick is to play with the front-end part and just let uibuilder be the glue that links you with Node-RED.

You might like to also check out the new flow I just created based on @bakman2's suggested simple example.

https://flows.nodered.org/flow/bbe6803d9daebda5c991336cf4e5e3e0/in/6c96b1c2350dcb4536903a3158d6254d

Then go back to the default template so that you build up a knowledge of Vue's processing.

I like Vue because simple things really are simple but it doesn't restrict you to simple. It is the fastest growing front-end framework with loads of examples and components. available.

Let me know if there is something specific you are wanting to do. I still want to find time to create some standardised components that will let you do things as easily as Dashboard does. The key I believe is to create some standards for the data sent from Node-RED to the front-end which would let you swap out components while keeping the data the same.

1 Like

That link's pulling a 404 for me.

I miss Microsoft Frontpage.

My bad. Copy/paste error.

https://flows.nodered.org/flow/bbe6803d9daebda5c991336cf4e5e3e0

Haha! I did my very first website in that! I don't miss it at all!!

What I do find odd is that the state of WYSIWYG HTML editing hasn't actually progressed very much.

2 Likes

Minor issue just pointed out by @bakman2 that the flow has the wrong index.js file in it since I stupidly forgot to paste the actual code back into the comment.

I will fix that when I get to work in an hour or so.

In case you need it before then, here it is:

/* jshint browser: true, esversion: 5, asi: true */
/*globals uibuilder, Vue */
// @ts-nocheck
/*
  Copyright (c) 2019 Julian Knight (Totally Information)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
'use strict'

/** @see https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki/Front-End-Library---available-properties-and-methods */

var app1 = new Vue({
    // The HTML element to attach to
	el: '#app',
	/** Pre-defined data
	 *  Anything defined here can be used in the HTML
	 *  if you update it, the HTML will automatically update
	 */
	data: {
		msg: '[Nothing Recieved Yet]',
	},

    // This is called when Vue is fully loaded
	mounted: function() {
	    // Start up uibuilder
		uibuilder.start()
		
		// Keep a convenient reference to the Vue app
		var vueApp = this

        /** Triggered when the node on the Node-RED server
         *  recieves a (non-control) msg
         */
		uibuilder.onChange('msg', function(msg) {
			vueApp.msg = msg
		})

		// Send message back to node-red
		// uibuilder.send({payload:'some message'})

		// Triggered on reciept of a control message from node-red
		//uibuilder.onChange('ctrlMsg', function(msg) {
		//    console.log(msg)
		//})
	},
	
}) // --- End of the Vue app definition --- //

// EOF

Note to self: post sample flow with menu and routing in a bit.
Note to others: if I don’t post it remind me please, I’ve a lot going on and I might forget it, not near my laptop atm

When using Vue, I usually put the menu I use in a component. That way if things change I can quickly find it to edit if needed. Beyond the actual menu itself I use vue-router to create smaller pages, each with content and the menu, and can create readable addresses in the uibuilder endpoint that way. These can be bookmarked and/or shared, and will allow you to get back to exactly that part of your interface again. Not dissimilar to node-red-dashboard, but you can configure the address and make it human readable.

On top of that, when using vue-bootstrap, it has builtin support for vue-router and you can use v-bind:to in links/nav links to specify how to get to that page.

Flow now updated with correct JavaScript.

Thanks Lena, great.

Just remember that vue-router creates a single-page app. This is great for some things but you shouldn't abuse it. Especially if creating for mobile use. with a single-page app, everything has to be loaded into memory. Use separate pages if needing to trim down loaded size. Trading off speed (of loading) for memory.

That depends on whether or not you succeed with lazy loading. It appears I have it working without a build step, but I need to verify it again to see if that is the case for real after some recent changes

Agree, but remember that bootstrap and vue-bootstrap on their own are the biggest usurpers of loading size. Those few things you add yourself are almost always smaller than those. The newest vue-cli has a pretty web interface, go play with a build step some day and see the analysis of sizes of things added to it :wink:
IIRC bootstrap plus vue-bootstrap was good for 200kb minified when using a build step, my own added code 50 kb or so at most.

1 Like

Good points.

But you can always not use them if you want to lighten the load :smile:

And if you really want light weight - go without any framework and just use uibuilder with some simple hand-crafted DOM manipulation. At some point, I'll try and do a demo of that.

Oh, I definitely agree there :stuck_out_tongue: if you however are already going the Vue way (and with Vue-boostrap available by default for you to use it's going to be easy to go that way for sure), vue-router and your construction being an SPA are unlikely to be the biggest hoggers of memory/bandwidth. Either way, that's when it's getting interesting to look at using an appcache manifest, while thinking of the risks of that thing too.

Fair enough.

Yes, that's why you will find the code in some of the index.html examples but commented out. The default template includes an appcache file as well. It makes a huge difference but is only really suitable if your code is reasonably stable. Without a build step, maintenance of the cache is a bit of a pain.

now I'm wondering if the appcache can be generated with a flow :wink:

Just realised that I'd got confused by what needs to change. It is only the file itself that needs to change in order to trigger a cache update.

To generate automatically, you would need to be able to work out what files (actually what resources) are going to be loaded. If you get it wrong, I think that you get an error (e.g. if you specified index.html but it wasn't there).

Some of that could perhaps be generated automatically - at least within the node, I don't think it would be very robust with just a flow.

The issue is - how do we know what files will be loaded? Also, that needs to work across potentially several html files. It also needs to take into account that users may have many libraries installed but may only use one or two in any particular instance of uibuilder. I don't differentiate those at present since all of the libraries are made available outside the instance code (e.g. only once for all instances).

What is the advantage for appcache ? I mean I only use it locally and no vue-bootstrap. I mean, don't only think about the css, but what about the DOM which is flooded by all kinds of classes on each element, unnecessary in my opinion. I use CSS grids and that can reduce class usage to a great extend. (never been a fan of css "frameworks" other than skeleton)

It makes everything listed in it available as part of a browser cache. That means that it is available even if you are offline. But more usefully, it means that the resources don't have to be downloaded again. Mega fast, especially with big libraries - Dashboard would be virtually unusable without it.

To fix that, you need a build step with tree shaking. A much more advanced process and beyond a lot of people.

This is the same with Dashboard.

Then uibiulder is just right for you! Get rid of everything (except uibuilderfe.js of course), uibuilder will still work!