Uibuilder - extra vue enhancements

Hi i've installed the uibuilder node_module and have the default page up and running. I have also extended it to several pages using bootstrap-vue nav bar and other enhancements. each page has its own js file.

I would now like to add a vue based toggle-switch of which there are a number. i've installed the node(s) through the uibuilder editor and placed script references in the html files.

When I add the required JS entries in the local js file:

import { EnhancedCheck, EnhancedCheckGroup, EnhancedCheckRadio, EnhancedToggle } from 'vue-enhanced-check'
export default {
    components: { EnhancedCheck, EnhancedCheckGroup, EnhancedCheckRadio, EnhancedToggle },
}

I loose all formatting and and everything stops working. I get the following error message:

SyntaxError: import declarations may only appear at top level of a module.

So I suppose the question is what's the top level module>

kind regards daniel

@greenembrace Are you using a build step to compile the files down to a single bundle, or are you loading them from the HTML? In case of the second, you have to rely on the browser capabilities of ES6 imports and modules, which aren’t too great yet. Support for a build step in the node is coming in a future minor version.

Can you show how you link this in the HTML file (script tags and order of them), and how your JavaScript files are connected?

See the following links for more browser information


https://blogs.windows.com/msedgedev/2016/05/17/es6-modules-and-beyond/

Please note that imports with modules are so far untested with Uibuilder and Vue. I have a sample repository with experiments, but so far I haven’t put it to work yet.

Also have a look at my WIKI entries on chart tools and, in particular, the http-vue-loader.

You will see that there are alternatives to the import method that let you work without a build step.

http-vue-loader lets you load .vue files without a build step, the chart examples show you how to load custom tags purely by adding the .js library file - assuming that the author has written it in such a way as that will work.

If you let us know of specific packages that you are working with, we'd be happy to help you get them working.

Ultimately, I will be adding built capabilities to uibuilder so that you aren't forced to delve into the servers filing system to get things like that done.

Thanks for your comments, i'm trying to digest them.

I have tried not to modify the default scripts to much as i'm learning as i go. changing one thing at a time and making sure it works.

I'm loading from house.html, this is the bottom for the file:

   <!-- REQUIRED: Sets up Socket listeners and the msg object -->
    <script src="./uibuilderfe.min.js"></script> 
    <script src="../uibuilder/vendor/vue-enhanced-check/dist/vue-enhanced-check.js"></script>
    
    <!-- OPTIONAL: You probably want this. Put your custom code here -->
     <script src="./house.js"></script>

and the house.js :


import { EnhancedCheck, EnhancedCheckGroup, EnhancedCheckRadio, EnhancedToggle } from 'vue-enhanced-check'
'use strict'

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

import { EnhancedCheck, EnhancedCheckGroup, EnhancedCheckRadio, EnhancedToggle } from 'vue-enhanced-check'
export default {
    components: { EnhancedCheck, EnhancedCheckGroup, EnhancedCheckRadio, EnhancedToggle },
};

// eslint-disable-next-line no-unused-vars
var house = new Vue({
    el: '#app',
    data: {
        startMsg: 'Vue has started, waiting for messages',
        feVersion: '',
        centerLight: false,

the reset is the same as the default index.js

kind regards daniel

ps. i did look briefly @ the chart tools. but got a bit lost. I have been trying for a few days and don't like bothering you busy folk.

The first thing to do is to comment out all of the import and export statements and try adding the following to your main vue app code:

    /** Load external component files */
    components: {
        'enhanced-check': EnhancedCheck,
    }, // --- End of components --- //

Hopefully that will work. If so, you can add the other components similarly.

You can also register components globally rather than just for a single instance of Vue - obviously, this only makes a difference if you are using multiple Vue instances in a single page.

Vue.component( {'enhanced-check': EnhancedCheck} )

This will only work if the author of the package has written their components correctly so that they are added to the global namespace when loaded via a script link. So far, all except 1 component that I've tried have worked this way. vue-chartjs was the one that didn't work. However, I've not yet tried that many.

By the way, have you checked out the features of bootstrap-vue?

That has some really good switches, etc with the added advantage that you don't need to load anything extra.

1 Like

Hi thank-you, I will followup on all your comments. I see great potential in your hard work. and yes i have looked through the components of bootstrap-vue. i'm after a toggle like switch (for lights) that's one colour for ON and another for OFF so users can clearly see what's happening.

I will post an update when i get a chance.

Cheers daniel

I have one of those on my laptop, Apple settings style with bootstrap colours. Used it in vue projects before. Was planning on uploading when I have enough strength in my arms again to not drop that laptop :stuck_out_tongue:

This is the source of your issue. The from ‘vue-enhanced-check' to be specific.

When you are using a build step, such as webpack or browserify, these tools are aware that you have a node_modules folder that contains these packages that you are importing. The from <name> syntax would refer to either a folder with an index.js file inside that you are importing from/via, or a file called <name>.js. The build configuration knows how the structure works, and the file endings are often optional.

In your situation, or rather the Uibuilder v2 without a build step situation to make this more generic, this configuration is not known. What you have is JavaScript files that are being read by a web browser. One without knowledge of a node_modules directory or optional file types. So you will have to write the code in a way the browser will understand where to find these files. When using ES6 imports in a JavaScript file that you want available in the browser, you will have to declare it as a module in the html script tag. For a how-to, check the links from my previous post, the Microsoft one will explain this part the best, while the Mozilla link explains the JavaScript part of the story better.

Another option would be to check the :1880/uibindex link, this describes where vendor libraries are installed. Using this, you can include it directly into your HTML, which makes it available for usage in script tags in the html file itself. A third option is to use single file components, these might actually be present in the package (I would have to check the source of that but that’s a bit harder from my phone, so I’ll look that up later and edit once again), if so you can use the vendor based url combined with the vue-http-loader Julian mentioned before.

Have a look at:

I'm still working on it.

Thanks afelix that reply is rich in information. I will follow those thoughts up.
kind regards

Thanks also cflurin I will also look @ your work.

Thank you for your kind words. I note that the bootstrap-vue switch does change colour but I don't know if you can control the colours. I expect you can, usually some investigation using your browser's dev console will let you find the appropriate css classes that you can then over-ride.

For anyone curious, here's the switch I based my own component on: https://codepen.io/claviska/pen/KyWmjY
I'm trying to make it compatible to have it loaded through http-vue-loader. Colour switching has to be modded in through the scss code, which is what I did in the past, but obviously I can't find my modified version as I never checked that one into version control :woman_facepalming:
And in case you're curious, single file components with scss can in fact load, if you add a bit of additional boilerplate to the importing code. This is documented on the http-vue-loader readme page.

Did you see the switch on Bootstrap-vue?

### Individual checkbox switch style

A single checkbox can be rendered with a switch appearance by setting the prop  `switch`  to true

With the latest version 2.0.0-rc.28 you can also control the size:

e.g.

<b-form-checkbox v-model="at_home" v-on:change.native="switch_onChange('at_home', $event)" switch size="lg" class="mb-2">

switch

I did in fact not, thanks for the tip :slight_smile: According to the changelogs they got added in 2.0.0-rc.12. That's what you get for not updating beyond rc.3 I guess and writing components for that state :stuck_out_tongue:

I just went through the documentation, then the source code, it has 1 colour only that can't be changed, unless used in button mode rather than switch mode.

It's quite easy to update Bootstrap-vue in the node uibuilder. In Front-End Library Manager just add the library again.

1 Like

SCSS with imports on the other hand is a whole other mess that will require either jquery to streamline promises well if you have more than 1 import, or dropping browser support... neither are firmly to my liking and I had some playing with browser support and promises over christmas that was a whole other chaos (some ~4000 people who started to depend on a browser script I wrote, but had a small bug that had to be solved through promises to work around the beautiful async universe that is javascript; in the end I rewrote the browser script to a full on interface with Vue)

Sounds like an issue should be raised against that. Shouldn't be hard to add colour change to it.

Nope, because you already can using the standard Bootstrap theming. I’ve a webpack based sample for it that I’m trying to get working without a build step. Going to do another try today. To get it working with http-vue-loader you need Sass.js (placed those in the common folder, the node version won’t work from the frontend). Then add scss as language for styling, but before calling sass.compile() you need to make the bootstrap variables scss file available which is possible through an XHR call, but gets significantly harder if you need more than one import available.

For additional context, someone did: it became a WONTFIX

The idea is that while the custom switches got added, you can do the theming yourself following the bootstrap guidelines.

In case you don't want to mess with that, you can also override the CSS like this:

#myswitch + .custom-control-label::before { background-color:red ;}

With the HTML

<b-form-checkbox id="myswitch" switch size="lg" class="mb-2"></b-form-checkbox>

You would need to tweak that so that it only adds the class if the switch is on but the important point is that you can change the style but only if you know the structure that bootstrap-vue creates - the label is actually what contains the display and the actual visuals are contained in a ::before on the label element.