Ok - Been following this thread for sometime.
@BartButenaers - Great tutorial
One thing I find great for sidebar is the use of the stack panels & tree views!
I use them in my ZWave plugin a fair bit
Ok - Been following this thread for sometime.
@BartButenaers - Great tutorial
One thing I find great for sidebar is the use of the stack panels & tree views!
I use them in my ZWave plugin a fair bit
Really nice layout
Are you building those by hand or using a library?
I do have a hint for sidebar - which may help others in easing the design
I use https://handlebarsjs.com - to design the skeleton of the layout (1 in a million ways of course)
And use its JSON data processing features to fill in the data placeholders
A Breif example
HTML Template
(held in a plugin html file)
<!-- Side Panel Template-->
<!-- prettier-ignore -->
<template id="TPL_SidePanel">
<!--Network Selector-->
<div class="red-ui-sidebar-header" id="zwave-js-network-header" style="display: none; text-align: center; height: 20px">
<i class="fa fa-cog" aria-hidden="true"></i>
Network/Runtime :
<select id="zwave-js-network" onchange="NetworkSelected()" style="height: 25px; vertical-align: baseline">
<option>Select Network</option>
{{#each Networks}}
<option value="{{this.id}}">{{this.name}}></option>
{{/each}}
</select>
</div>
</template>
JS
- loaded by plugin html (using the resources
API)
const Content = $('<div>')
const Template = Handlebars.compile($('#TPL_SidePanel').html());
const Data = {Networks:[{id: 4, name: "Some Network"}]}
Content.append(Template(Data))
RED.sidebar.addTab({
....
content: Content,
...
});
@TotallyInformation
For the stacks I use the Node RED CSS classes, and for the tree views, use the built in methods.
Undoubtedly, you have a better memory than me and probably know the core code better as well - do you have a hint?
That is interesting because I've started using templates in the html file for uibuilder as well. Just in the uib-element
node and they are all fairly blank right now but will be used dynamically to swap the Element Config tab depending on the selected element type:
Allowing for different advanced config settings by element type.
I like using templates - to aid in the detachment between the developer and the designer
(but in this case - I'm both ) - but it helps (a lot) to get focus on the design.
And yes - it nice being able to empty()
and re-populate based on a template for the selection
For a tree view, here is an example from my code base.
const TreeData = [];
ZWNodes.forEach((N) => {
const Label = $('<div>');
Label.append(`<span class="zwave-js-node-id-list">${N.nodeId}</span> `);
Label.append(N.nodeName || 'No Name');
TreeData.push({
element: Label,
nodeData: N
});
});
$('#zwave-js-node-list').treeList('data', TreeData);
Note the custom property nodeData
the element with id zwave-js-node-list
is of course in my template html
$('#zwave-js-node-list').on('treelistselect', nodeSelected);
const nodeSelected = (event, item) => {
//item.nodeData.nodeName etc etc
}
One more question, in this setup for a sidebar panel, where can I setup a http admin post point for retrieving data from the server?
I tried adding the server part to the .js file for the config node:
module.exports = function (RED) {
function ConfigservercommfromsidebarFunctionality(config) {
RED.nodes.createNode(this, config)
}
RED.nodes.registerType('servercommfromsidebarCfg', ConfigservercommfromsidebarFunctionality);
console.error( "starting listener") // seen in the server logs
RED.httpAdmin.post("/servercommfromsidebar",
RED.auth.needsPermission("servercommfromsidebar.write"),
(req, res) => {
console.error("REQUEST RECIEVED")
res.status(200).send({
"status": "ok",
})
});
}
The starting listener stanza is to be found in the log but the httpAdmin endpoint is 404, not found.
So the idea is that when I open the sidebar and hit the button, it sends a request to the server and then something else happens. Unfortunately the server part isn't working yet.
I have been caught here in the past, I found my error was I was adding a slash at the start in client code
Bad
getJSON("/servercommfromsidebar")
Good
getJSON("servercommfromsidebar")
might be worth checking
yes the slash prevents httpAdminRoot
configuration from settings.js having an effect on the frontend request
Note that I have updated my original code above, based on some feedback from @gregorius
The original sidebar was initialized every time the 'Deploy' button was clicked. Because the wrong 'runtime-state' event handler was removed, e.g. the handler of another sidebar.
The code is now refactored to something like this, to make sure our sidebar event handler function is only called once (i.e. when all the nodes have been loaded):
var initializeSidebar = function( ) {
// Remove the event handler, to avoid that the sidebar is initialized at every deploy
RED.events.off('runtime-state', initializeSidebar);
...
}
// Add your plugin as a new tabsheet in the right sidebar AFTER the flow editor is completely started
RED.events.on('runtime-state', initializeSidebar);
This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.