-
-
Notifications
You must be signed in to change notification settings - Fork 85
Example: JQuery
This is an example of using uibuilder with just JQuery. JQuery is included in the node installation by default. These are, in fact, the default master template files that are copied into your local folder.
For simple use, JQuery is adequate to enable you to dynamically update the UI as messages come into the node and across to the front end over Socket.IO. For more advanced use, consider using a front-end library such as Moon or Riot, there are examples for these in the uibuilder WIKI.
Note that I will assume your userDir
is at ~/.node-red
which is the default.
Open a terminal/command prompt, cd to ~/.node-red
(most platforms including Windows PowerShell, %USERPROFILE%\.node-red
for Windows cmd prompt).
npm install node-red-contrib-uibuilder --save
After restarting Node-RED, import the flow given below and deploy. Note that the instance of the uibuilder
node in the example flow has its URL set to uibuilder
which is the default.
You should now have a folder ~/.node-red/uibuilder/uibuilder/src
. You need to copy over the files
shown below into that folder. You will be replacing the files that the deployment of the node has copied over for you.
Note that you are generally better off using the default master files rather than the ones here as those are more likely to be the latest versions.
In your favourite browser, navigate to the /uibuilder
url. If you are using default settings and running Node-RED
on the same machine as the browser, this will be http://localhost:1880/uibuilder
.
Now you can use the button in the web page to send a message back to Node-RED, the data will appear in the debug output pane. Then you can use the Inject node to send a message to the browser.
Import this to Node-RED and deploy.
[{"id":"56888c14.108754","type":"inject","z":"106ba95c.ff91e7","name":"","topic":"","payload":"{\"fred\":\"jim\", \"billy\": 500}","payloadType":"json","repeat":"","crontab":"","once":false,"x":130,"y":160,"wires":[["36210ab8.3e1b76"]]},{"id":"c60764c8.90faa8","type":"debug","z":"106ba95c.ff91e7","name":"uibuilder-debug","active":true,"console":"false","complete":"true","x":480,"y":160,"wires":[]},{"id":"36210ab8.3e1b76","type":"uibuilder","z":"106ba95c.ff91e7","name":"a","url":"uibuilder","fwdInMessages":false,"x":280,"y":160,"wires":[["c60764c8.90faa8"]]}]
These go in ~/.node-red/uibuilder/uibuilder/src
<!doctype html>
<html lang="en">
<!--
This is the default, template html for uibuilder.
It is only meant to demonstrate the use of JQuery to dynamically
update the ui based on incoming/outgoing messages from/to the
Node-RED server.
You will want to alter this to suite your own needs. To do so,
copy this file to <userDir>/uibuilder/<url>/src.
-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
<!-- See https://goo.gl/OOhYW5 -->
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#3f51b5">
<!-- Used if adding to homescreen for Chrome on Android. Fallback for manifest.json -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="Node-RED UI Builder">
<!-- Used if adding to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Node-RED UI Builder">
<!-- Homescreen icons for Apple mobile use if required
<link rel="apple-touch-icon" href="/images/manifest/icon-48x48.png">
<link rel="apple-touch-icon" sizes="72x72" href="/images/manifest/icon-72x72.png">
<link rel="apple-touch-icon" sizes="96x96" href="/images/manifest/icon-96x96.png">
<link rel="apple-touch-icon" sizes="144x144" href="/images/manifest/icon-144x144.png">
<link rel="apple-touch-icon" sizes="192x192" href="/images/manifest/icon-192x192.png">
-->
<title>Node-RED UI Builder</title>
<meta name="description" content="Node-RED UI Builder">
<link rel="icon" href="images/node-blue.ico">
<!-- OPTIONAL: Normalize is used to make things the same across browsers. Index is for your styles -->
<link rel="stylesheet" href="vendor/normalize.css/normalize.css">
<link rel="stylesheet" href="index.css">
</head>
<body>
<!-- The "app" element is where the code for dynamic updates is attached -->
<div id="app">
<h1>
Welcome to UIbuilder for Node-RED
</h1>
<p>
This is the default web page. If you open the developer console, you will see some debug output.
You can also see some dynamic data updating below, thanks to JQuery.
</p>
<p>
Please see the README for the
<a href="https://github.com/TotallyInformation/node-red-contrib-uibuilder">node-red-contrib-uibuilder</a>
node for details on how to use UIbuilder.
</p>
<h2>Dynamic Data (via JQuery)</h2>
<p>UIBuilder Front-End Version: <span id="feVersion"></span></p>
<p>Websocket State: <span id="socketConnectedState"></span></p>
<p>Messages Received: <span id="msgsReceived"></span></p>
<p>Control Messages Received: <span id="msgsControl"></span></p>
<p>Messages Sent: <span id="msgsSent"></span></p>
<p>Last Message Received:</p>
<code id="showMsg"></code>
<p>Last Control Message Received:</p>
<code id="showCtrlMsg"></code>
<p>Last Message Sent:</p>
<code id="showMsgSent"></code>
</div>
<!-- These MUST be in the right order. Note no leading / -->
<!-- REQUIRED: Socket.IO is loaded only once for all instances
Without this, you don't get a websocket connection -->
<script src="/uibuilder/socket.io/socket.io.js"></script>
<!-- Note no leading / -->
<!-- OPTIONAL: JQuery can be removed if not required -->
<script src="vendor/jquery/dist/jquery.min.js"></script>
<!-- REQUIRED: Sets up Socket listeners and the msg object -->
<script src="uibuilderfe.js"></script>
<!-- OPTIONAL: You probably want this. Put your custom code here -->
<script src="index.js"></script>
</body>
</html>
body {font-family: sans-serif;}
div, p, code { margin:0.3em; padding: 0.3em;}
/*global document,$,window,uibuilder */
/*
Copyright (c) 2017 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.
*/
/**
* This is the default, template Front-End JavaScript for uibuilder
* It is usable as is though you will want to add your own code to
* process incoming and outgoing messages.
*
* uibuilder: The main global object containing the following...
* Methods:
* .onChange(attribute, callbackFn) - listen for changes to attribute and execute callback when it changes
* .get(attribute) - Get any available attribute
* .set(attribute, value) - Set any available attribute (can't overwrite internal attributes)
* .msg - Shortcut to get the latest value of msg. Equivalent to uibuilder.get('msg')
* .send(msg) - Shortcut to send a msg back to Node-RED manually
* .debug(true/false) - Turn on/off debugging
* .uiDebug(type,msg) - Utility function: Send debug msg to console (type=[log,info,warn,error,dir])
* Attributes with change events (only accessible via .get method except for msg)
* .msg - Copy of the last msg sent from Node-RED over Socket.IO
* .send - Copy of the last msg sent by us to Node-RED
* .ctrlMsg - Copy of the last control msg received by us from Node-RED (Types: ['shutdown','server connected'])
* .msgsReceived - How many standard messages have we received
* .msgsSent - How many messages have we sent
* .msgsCtrl - How many control messages have we received
* .ioConnected - Is Socket.IO connected right now? (true/false)
* Attributes without change events
* (only accessible via .get method, reload page to get changes, don't change unless you know what you are doing)
* .debug - true/false, controls debug console logging output
* ---- You are not likely to need any of these ----
* .version - check the current version of the uibuilder code
* .ioChannels - List of the channel names in use [uiBuilderControl, uiBuilderClient, uiBuilder]
* .retryMs - starting retry ms period for manual socket reconnections workaround
* .retryFactor - starting delay factor for subsequent reconnect attempts
* .ioNamespace - Get the namespace from the current URL
* .ioPath - make sure client uses Socket.IO version from the uibuilder module (using path)
* .ioTransport - ['polling', 'websocket']
*
* makeMeAnObject(thing, attribute='payload') - Utility function: make sure that 'thing' is an object
*/
// When JQuery is ready, update
$( document ).ready(function() {
// Initial set
$('#msgsReceived').text( uibuilder.get('msgsReceived') )
$('#msgsControl').text( uibuilder.get('msgsCtrl') )
$('#msgsSent').text( uibuilder.get('msgsSent') )
$('#socketConnectedState').text( uibuilder.get('ioConnected') )
$('#feVersion').text( uibuilder.get('version') )
// Turn on debugging (default is off)
uibuilder.debug(true)
// If msg changes - msg is updated when a standard msg is received from Node-RED over Socket.IO
// Note that you can also listen for 'msgsReceived' as they are updated at the same time
// but newVal relates to the attribute being listened to.
uibuilder.onChange('msg', function(newVal){
console.info('property msg changed!')
console.dir(newVal)
$('#showMsg').text(JSON.stringify(newVal))
//uibuilder.set('msgCopy', newVal)
})
// You can get attributes manually. Non-existent attributes return 'undefined'
//console.dir(uibuilder.get('msg'))
// You can also set things manually. See the list of attributes top of page.
// You can add arbitrary attributes to the object, you cannot overwrite internal attributes
// Try setting a restricted, internal attribute - see the warning in the browser console
uibuilder.set('msg', 'You tried but failed!')
// Remember that onChange functions don't trigger if you haven't set them
// up BEFORE an attribute change.
uibuilder.onChange('msgCopy', function(newVal){
console.info('msgCopy changed. New value: ', newVal)
})
// Now try setting a new attribute - this will be an empty object because
// msg won't yet have been received
uibuilder.set('msgCopy', uibuilder.msg)
// Hint: Try putting this set into the onChange for 'msg'
// As noted, we could get the msg here too
uibuilder.onChange('msgsReceived', function(newVal){
console.info('New msg sent to us from Node-RED over Socket.IO. Total Count: ', newVal)
$('#msgsReceived').text(newVal)
// uibuilder.msg is a shortcut for uibuilder.get('msg')
//$('#showMsg').text(JSON.stringify(uibuilder.msg))
})
// If Socket.IO connects/disconnects
uibuilder.onChange('ioConnected', function(newVal){
console.info('Socket.IO Connection Status Changed: ', newVal)
$('#socketConnectedState').text(newVal)
})
// If a message is sent back to Node-RED
uibuilder.onChange('msgsSent', function(newVal){
console.info('New msg sent to Node-RED over Socket.IO. Total Count: ', newVal)
$('#msgsSent').text(newVal)
$('#showMsgSent').text(JSON.stringify(uibuilder.get('sentMsg')))
})
// If we receive a control message from Node-RED
uibuilder.onChange('msgsCtrl', function(newVal){
console.info('New control msg sent to us from Node-RED over Socket.IO. Total Count: ', newVal)
$('#msgsControl').text(newVal)
$('#showCtrlMsg').text(JSON.stringify(uibuilder.get('ctrlMsg')))
})
//Manually send a message back to Node-RED after 2 seconds
window.setTimeout(function(){
console.info('Sending a message back to Node-RED - after 2s delay')
uibuilder.send( { 'topic':'uibuilderfe', 'payload':'I am a message sent from the uibuilder front end' } )
}, 2000)
}) // --- End of JQuery Ready --- //
// EOF
This is the magic that allows you to have a much simplified index.js. It does all the heavy lifting with Socket.IO and gives you an onChange
function to listen for changes to key variables so that you can update the UI.
Normally, you wouldn't have this file in your local src
folder, it would be picked up from the master folder.
If you want to see what it does, please use the version in the repo.
Please feel free to add comments to the page (clearly mark with your initials & please add a commit msg so we know what has changed). You can contact me in the Discourse forum, or raise an issue here in GitHub! I will make sure all comments & suggestions are represented here.
-
Walkthrough 🔗 Getting started
-
In Progress and To Do 🔗 What's coming up for uibuilder?
-
Awesome uibuilder Examples, tutorials, templates and references.
-
How To
- How to send data when a client connects or reloads the page
- Send messages to a specific client
- Cache & Replay Messages
- Cache without a helper node
- Use webpack to optimise front-end libraries and code
- How to contribute & coding standards
- How to use NGINX as a proxy for Node-RED
- How to manage packages manually
- How to upload a file from the browser to Node-RED
-
Vanilla HTML/JavaScript examples
-
VueJS general hints, tips and examples
- Load Vue (v2 or v3) components without a build step (modern browsers only)
- How to use webpack with VueJS (or other frameworks)
- Awesome VueJS - Tips, info & libraries for working with Vue
- Components that work
-
VueJS v3 hints, tips and examples
-
VueJS v2 hints, tips and examples
- Dynamically load .vue files without a build step (Vue v2)
- Really Simple Example (Quote of the Day)
- Example charts using Chartkick, Chart.js, Google
- Example Gauge using vue-svg-gauge
- Example charts using ApexCharts
- Example chart using Vue-ECharts
- Example: debug messages using uibuilder & Vue
- Example: knob/gauge widget for uibuilder & Vue
- Example: Embedded video player using VideoJS
- Simple Button Acknowledgement Example Thanks to ringmybell
- Using Vue-Router without a build step Thanks to AFelix
- Vue Canvas Knob Component Thanks to Klaus Zerbe
-
Examples for other frameworks (check version before trying)
- Basic jQuery example - Updated for uibuilder v6.1
- ReactJS with no build - updated for uibuilder v5/6
-
Examples for other frameworks (may not work, out-of-date)
-
Outdated Pages (Historic only)
- v1 Examples (these need updating to uibuilder v2/v3/v4/v5)