### Node-RED Dashboard Developer Setup
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Commands to clone the Node-RED Dashboard repository, install dependencies, and prepare for development.
```bash
cd ~\.node-red\node_modules
git clone https://github.com/node-red/node-red-dashboard.git
cd node-red-dashboard
npm install
```
--------------------------------
### Install Latest Version from GitHub
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Install the latest development version of node-red-dashboard directly from its GitHub repository using npm.
```bash
npm i node-red/node-red-dashboard
```
--------------------------------
### Install Node-RED Dashboard
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Install the stable version of node-red-dashboard via the Node-RED Manage palette or using npm. Restart Node-RED after installation.
```bash
npm i node-red-dashboard
```
--------------------------------
### Widget Resize Start Event
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Handles the start of a widget resize operation within a group. It resets the group width to maintain layout integrity.
```javascript
var resizeGroupWidget = function(id) {
var gridID = '#grid'+id;
var grid = $(gridID+'.grid-stack').data('gridstack');
$(gridID+'.grid-stack').on('resizestart', function(event, ui) {
// Reset group width
grid.setColumn(tabDatas.groups[id].width, true);
});
}
```
--------------------------------
### Set Unique ID and Watch for Messages
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/locales/en-US/ui_template.html
This example demonstrates setting a unique ID for a template element, applying a default theme color, and updating the element's content when a new message arrives.
```html
Some text
```
--------------------------------
### Styling Notification Widget with CSS
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Applies custom styles to the notification widget using CSS classes. This example demonstrates how to override default styles for warning toasts.
```html
```
--------------------------------
### Combine Configuration Properties
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Demonstrates how to combine multiple UI configuration properties within the settings.js file for comprehensive customization.
```javascript
ui: {
path: "ui",
middleware: function (req, res, next) {
console.log('LOGGED')
next()
},
ioMiddleware: function (socket, next) {
console.log('HELLO')
next()
},
readOnly: true,
defaultGroup: "Better Default"
}
```
--------------------------------
### Initialize Form Options
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_form.html
Iterates through existing options and calls generateOption for each to populate the form. Also initializes the topic typed input.
```javascript
for (var i=0; i
```
--------------------------------
### Widget Drag Start Event
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Handles the start of a widget drag operation within a group. It resets the group width to ensure consistent behavior.
```javascript
var dragGroupWidget = function(id) {
var gridID = '#grid'+id;
var grid = $(gridID+'.grid-stack').data('gridstack');
$(gridID+'.grid-stack').on('dragstart', function(event, ui) {
// Reset group width
grid.setColumn(tabDatas.groups[id].width, true);
});
}
```
--------------------------------
### Get Base Font Name
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Returns the name of the base font.
```javascript
calculate_base_font: function(base) {
return baseFontName;
}
```
--------------------------------
### Widget Placement and Grid Initialization
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Calculates widget positions and initializes the grid stack for a group. Handles auto-sizing widgets and determines placement points.
```javascript
var widgets = groups[cnt].widgets;
widgets.sort(compareOrder);
var tbl = {};
for (var cnt2 = 0; cnt2 < widgets.length; cnt2++) {
// Set default value when there is auto width
if (widgets[cnt2].auto == true) {
widgets[cnt2].width = groupWidth;
// Adjust to the group width
} else if (widgets[cnt2].width > groupWidth) {
widgets[cnt2].width = groupWidth;
}
// Auto support
if (widgets[cnt2].auto === true || widgets[cnt2].type === 'ui_form') {
widgets[cnt2].height = getDefaultHeight(widgets[cnt2].id, groupWidth);
}
// Calculate coordinates to be placed
var point = search_point(Number(widgets[cnt2].width), Number(widgets[cnt2].height), groupWidth, 256, tbl);
if (point) {
widgets[cnt2].x = point.x;
widgets[cnt2].y = point.y;
}
}
```
--------------------------------
### Display Icofont Icon in Template
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Example of displaying an Icofont icon using an tag within an HTML template, with custom styling.
```html
```
--------------------------------
### Use Iconify Icons in HTML
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Example of using Iconify icons within an HTML span element. The 'iconify-' prefix is required.
```html
```
--------------------------------
### Configure Text Input Class and Name
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_text_input.html
HTML for the 'Class' and 'Name' input fields in the node editor.
```html
```
--------------------------------
### Include Iconify Library
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Add this script to a ui_template node to load the Iconify library for general use.
```html
```
--------------------------------
### Fill Matrix Position
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Marks a rectangular area in the matrix (tbl) as occupied, starting from position (px, py) with the given dimensions (width, height).
```javascript
function fill_matrix(px, py, width, height, maxWidth, tbl) {
for (var y=py; y < py+height; y++) {
for (var x=px; x < px+width; x++) {
tbl[maxWidth*y+x] = 1;
}
}
}
```
--------------------------------
### Configure Widget Options
Source: https://github.com/node-red/node-red-dashboard/wiki/Creating-New-Dashboard-Widgets
Defines basic widget properties like inputs, outputs, icon, and label. The `oneditprepare` function is used to initialize UI elements for widget configuration, such as size and group selection.
```javascript
inputs:1,
outputs:1,
icon: ICON,
paletteLabel: NAME,
label: function() { return this.name || NAME; },
oneditprepare: function() {
$("#node-input-size").elementSizer({
width: "#node-input-width",
height: "#node-input-height",
group: "#node-input-group"
});
},
oneditsave: function() {
},
oneditresize: function(size) {
}
};
return conf;
};
RED.nodes.registerType('ui_cal', mk_conf('cal'));
```
--------------------------------
### Check Node Type for Layout Tool Support
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Determines if a given node type is supported by the dashboard layout tools. Only nodes starting with 'ui_' are considered.
```javascript
function isLayoutToolSupported(nodeType) {
if (nodeType.indexOf("ui_") !== 0) {
return false;
} else {
return true;
}
}
```
--------------------------------
### Create Prompts with ui_toast
Source: https://context7.com/node-red/node-red-dashboard/llms.txt
Use `ui_toast` to create prompt dialogs for user confirmation. The user's choice ('Confirm' or 'Abort') is returned to the flow. If the user cancels, no message is emitted.
```javascript
// ── Prompt (returns user choice to output) ────────────────────────────────
// Node configured: position="prompt", ok="Confirm", cancel="Abort"
msg.payload = "Delete all historical data?";
msg.topic = "Confirm Action";
return msg;
// On OK: { payload: { msg: } }
// On Cancel: nothing emitted
```
--------------------------------
### Get Tab Data From Nodes
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Retrieves tab and group information from the Node-RED node set. This function is used to build the data structure for dashboard layout editing.
```javascript
function getTabDataFromNodes(tabID) {
var nodes = RED.nodes.createCompleteNodeSet(false);
var tab = {};
// Tab information
for (var cnt = 0; cnt < nodes.length; cnt++) {
if (nodes[cnt].id == tabID) {
if (nodes[cnt].type == "ui_tab" || nodes[cnt].type == "ui_link") {
tab = { id: nodes[cnt].id, name: nodes[cnt].name, type: nodes[cnt].type, order: nodes[cnt].order, groups: [] };
break;
}
}
}
// Group information
for (var cnt = 0; cnt < nodes.length; cnt++) {
if (nodes[cnt].type == "ui_group" && nodes[cnt].tab == tabID) {
var group = { id: nodes[cnt].id, name: nodes[cnt].name, type: nodes[cnt].type, order: nodes[cnt].order, width: nodes[cnt].width, widgets: [] };
tab.groups.push
```
--------------------------------
### Configure Text Input Payload and Topic
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_text_input.html
HTML for configuring the payload and topic sent by the text input node. Includes a typed input for the topic.
```html
```
--------------------------------
### Get Current UI Layout Structure
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Retrieves the current hierarchical structure of the UI, including tabs, groups, and the widgets within each group. This is useful for saving or serializing the dashboard layout.
```javascript
function getCurrentList() {
var currentList = [];
var tabs = tabContainer.editableList('items');
var open = false;
tabs.each(function(i,el) {
var tabData = el.data('data');
var tab = [];
var groups = el.find('.nr-db-sb-group-list').editableList('items');
groups.each(function(j,el) {
var group = [];
var groupData = el.data('data');
var widgets = el.find('.nr-db-sb-widget-list').editableList('items');
widgets.each(function(k,el) {
var widgetData = el.data('data');
group.push(widgetData.id);
})
tab.push({id:groupData.node.id, widgets:group});
});
currentList.push({id:tabData.node.id,groups:tab});
});
return currentList;
}
```
--------------------------------
### Initialize and Update Theme Settings
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Initializes the theme settings in the UI and handles updates when the theme is customized. It uses jQuery to interact with form elements and the ACE editor for theme configuration.
```javascript
if (editor === undefined) {
editor = RED.editor.createEditor({
id: 'nr-db-field-format-editor',
mode: 'ace/mode/javascript',
value: JSON.stringify({theme:globalDashboardNode.theme.themeState, site:globalDashboardNode.site})
});
RED.library.create({
url:"themes", // where to get the data from
type:"theme", // the type of object the library is for
editor: editor, // the field name the main text body goes to
mode:"ace/mode/javascript",
fields:['name'],
elementPrefix:"ui-sidebar-"
});
}
editor.on('input', function() {
// Check for any changes on the editor object
// i.e. has the theme been customised compared // to what is stored
var editorObject = JSON.parse(editor.getValue());
//Update theme object if necessary
if (JSON.stringify(editorObject.theme) !== JSON.stringify(globalDashboardNode.theme.themeState)) {
globalDashboardNode.theme.themeState = editorObject.theme;
if ($("#ui-sidebar-name").val() !== globalDashboardNode.theme.customTheme.name) {
globalDashboardNode.theme.customTheme.name = $("#ui-sidebar-name").val();
globalDashboardNode.theme.customTheme.baseColor = globalDashboardNode.theme.themeState["base-color"].value;
setColourPickerColour("base-color", globalDashboardNode.theme.customTheme.baseColor);
generateColours(globalDashboardNode.theme.themeState["base-color"].value);
RED.nodes.dirty(true);
}
}
if (JSON.stringify(aTheme) !== JSON.stringify(globalDashboardNode.theme.angularTheme)) {
globalDashboardNode.theme.angularTheme = aTheme;
}
//Update site object if necessary
if (JSON.stringify(editorObject.site) !== JSON.stringify(globalDashboardNode.site)) {
globalDashboardNode.site = editorObject.site;
$("#nr-db-field-title").val(globalDashboardNode.site.name);
$("#nr-db-field-hideToolbar").val(globalDashboardNode.site.hideToolbar);
$("#nr-db-field-allowSwipe").val(globalDashboardNode.site.allowSwipe);
$("#nr-db-field-allowTempTheme").val(globalDashboardNode.site.allowTempTheme);
$("#nr-db-field-dateFormat").val(globalDashboardNode.site.dateFormat);
$("#nr-db-field-sx").val(globalDashboardNode.site.sizes.sx);
$("#nr-db-field-sy").val(globalDashboardNode.site.sizes.sy);
$("#nr-db-field-px").val(globalDashboardNode.site.sizes.px);
$("#nr-db-field-py").val(globalDashboardNode.site.sizes.py);
$("#nr-db-field-gx").val(globalDashboardNode.site.sizes.gx);
$("#nr-db-field-gy").val(globalDashboardNode.site.sizes.gy);
$("#nr-db-field-cx").val(globalDashboardNode.site.sizes.cx);
$("#nr-db-field-cy").val(globalDashboardNode.site.sizes.cy);
RED.nodes.dirty(true);
}
});
```
--------------------------------
### Get Default Widget Height
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Calculates the default height for various Node-RED Dashboard widget types based on the group's width. This is used for widgets with automatic sizing enabled.
```javascript
function getDefaultHeight(nodeID, groupWidth) {
var redNode = RED.nodes.node(nodeID);
var height = 1;
if (redNode.type === 'ui_gauge') {
if (redNode.gtype === 'gage') {
height = Math.round(groupWidth/2)+1;
} else if (redNode.gtype === 'wave') {
if (groupWidth < 3) {
height = 1;
} else {
height = Math.round(groupWidth*0.75);
}
} else {
// donut or compass
if (groupWidth < 3) {
height = 1;
} else if (groupWidth < 11) {
height = groupWidth - 1;
} else {
height = Math.round(groupWidth*0.95);
}
}
} else if (redNode.type === 'ui_chart') {
height = Math.floor(groupWidth/2)+1;
} else if (redNode.type === 'ui_form') {
// var optNum = redNode.options.length;
// Sub widget number
// if (redNode.label) {
// height = optNum + 2;
// Label and Button
// } else {
// height = optNum + 1;
// Button only
// }
height = redNode.rowCount
} else if (redNode.type === 'ui_lineargauge') {
if (redNode.unit && redNode.name) {
height = 5;
} else {
height = 4;
}
} else if (redNode.type === 'ui_list') {
height = 5;
} else if (redNode.type === 'ui_vega') {
height = 5;
}
return height;
}
```
--------------------------------
### Justgage Gauge Configuration
Source: https://github.com/node-red/node-red-dashboard/blob/master/config-fields.md
Configure Justgage parameters for a gauge widget. Use this to customize pointer visibility, gauge width, and direction.
```json
{"options":{"pointer":false,"gaugeWidthScale":1.5}}
```
```json
{"options":{"pointer":true,"gaugeWidthScale":0.4,"reverse":true}}
```
--------------------------------
### Configure Text Input Mode and Delay
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_text_input.html
Provides a select dropdown for choosing the input mode (e.g., text, email, password) and a text input for setting the delay in milliseconds.
```html
```
--------------------------------
### Dynamically Apply CSS Class
Source: https://context7.com/node-red/node-red-dashboard/llms.txt
Apply custom CSS classes to any widget by setting the `msg.className` property. Ensure the corresponding CSS rules are defined, for example, via a `ui_template` node.
```javascript
// ── Dynamically apply a CSS class to any widget ───────────────────────────
msg.className = "alert highlight";
// With a head-injected style:
// md-card.alert { border: 2px solid red; }
// md-card.highlight button { font-weight: bold; }
```
--------------------------------
### Configure Widget Sizing and Spacing
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Dynamically updates widget size and spacing parameters (sx, sy, cx, cy, px, py, gx, gy) based on user input. Ensures changes are saved to the Node-RED configuration.
```javascript
$("#nr-db-field-sx").val(48).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.sx=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-sy").val(48).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.sy=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-cx").val(6).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.cx=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-cy").val(6).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.cy=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-px").val(0).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.px=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-py").val(0).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.py=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-gx").val(6).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.gx=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
$("#nr-db-field-gy").val(6).css("width","20%")
.on("change", function() {
globalDashboardNode.site.sizes.gy=Number($(this).val());
RED.nodes.dirty(true);
})
.appendTo(divSetSizes);
```
--------------------------------
### Clear Local Storage and AJAX Logout
Source: https://github.com/node-red/node-red-dashboard/blob/master/src/logout.html
Clears Node-RED specific items from local storage and attempts an AJAX GET request to the current page. If the request fails, it redirects to the base URL after a delay.
```javascript
for (var key in localStorage) { if (localStorage.hasOwnProperty(key)) { if (key.indexOf("nr-") === 0) { localStorage.removeItem(key); } } } $.ajax({ type: "GET", url: window.location.href, async: true, username: "some_non_user_name", password: "a_not_valid_password" })
.done(function() { alert('Error!') })
.fail(function() { var url = window.location.href.split("logout")[0]; setTimeout(function() { window.location.href = url; }, 1000); });
```
--------------------------------
### ui_toast - Notifications and Dialogs
Source: https://context7.com/node-red/node-red-dashboard/llms.txt
Demonstrates various ways to use the ui_toast node to display temporary notifications, modal dialogs, and prompts to the user. It covers basic messages, styled messages with custom CSS, modal alerts, and interactive prompts that return user input.
```APIDOC
## ui_toast
### Description
Displays toast notifications, modal alert dialogs, or prompt dialogs. Prompts return the user's choice to the flow. Notifications can be styled via CSS class names and targeted to individual clients.
### Usage Examples
#### Basic Toast Notification
```javascript
msg.payload = "File saved successfully";
msg.topic = "✓ Success";
return msg;
```
#### Toast with Custom Styling
```javascript
msg.payload = "High temperature warning!";
msg.topic = "⚠ Warning";
msg.highlight = "darkorange";
msg.className = "warn-toast";
return msg;
```
#### Modal Dialog (OK Button)
```javascript
msg.payload = "Firmware update complete. Please restart.";
msg.topic = "System Notice";
return msg;
```
#### Prompt Dialog (Confirm/Abort)
```javascript
msg.payload = "Delete all historical data?";
msg.topic = "Confirm Action";
return msg;
// On OK: { payload: { msg: } }
// On Cancel: nothing emitted
```
#### Targeting a Specific Client
```javascript
msg.payload = "Your timer has expired";
msg.socketid = "zXq8k..."; // from ui_ui_control connect event
msg.timeout = 0; // 0 = permanent until dismissed
return msg;
```
```
--------------------------------
### Formatting Gauge Value with Angular Filter
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/locales/en-US/ui_gauge.html
Use Angular filters within the 'Value Format' field to format the displayed gauge value. For example, `{{value | number:1}}%` rounds the value to one decimal place and appends a percentage sign.
```HTML
{{value | number:1}}%
```
--------------------------------
### Load TinyColor Library
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_base.html
Dynamically loads the TinyColor JavaScript library. It attempts to load from a local path first and falls back to a vendor path if the initial load fails.
```javascript
var loadTinyColor = function(path) {
$.ajax({
url: path,
success: function (data) {
var jsScript = document.createElement("script");
jsScript.type = "application/javascript";
jsScript.src = path;
document.body.appendChild(jsScript);
//console.log('Tiny Color Loaded:',path);
},
error: function (xhr, ajaxOptions, thrownError) {
if (xhr.status === 404 && !attemptedVendorLoad) {
loadTinyColor('/'+uip+'/vendor/tinycolor2/dist/tinycolor-min.js');
attemptedVendorLoad = true;
}
//console.log('Tiny Color Failed to load:',path);
}
});
}
// Try to load dist version first
// then if fails, load non dist version
loadTinyColor('ui_base/js/tinycolor-min.js');
```
--------------------------------
### Text Input Delay Tip
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_text_input.html
Provides a tip regarding the 'Delay' setting for the text input node, explaining its behavior when set to 0.
```html
Setting Delay to 0 waits for Enter or Tab key, to send input.
```
--------------------------------
### Lint and Check JS Styles
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Run Gulp tasks to check code quality and JavaScript style consistency.
```bash
gulp lint
gulp jscs
```
--------------------------------
### Configure ui_form with Fields and Pre-fill Values
Source: https://context7.com/node-red/node-red-dashboard/llms.txt
Defines the structure of a multi-field form and pre-fills its values. The form submits all field values as a single object keyed by the field's 'value' property.
```javascript
// Form configured with three fields:
// [
// { value: "name", label: "Full Name", type: "text", required: true },
// { value: "email", label: "Email", type: "email", required: true },
// { value: "age", label: "Age", type: "number", required: false },
// { value: "notes", label: "Notes", type: "multiline", rows: 3 }
// ]
// Pre-fill form fields:
msg.payload = {
name: "Alice Smith",
email: "alice@example.com",
age: 30
};
return msg;
// Output on submit:
// { payload: { name: "Alice Smith", email: "alice@example.com", age: 30, notes: "" } }
// Output on cancel:
// { payload: {} }
```
--------------------------------
### Rebuild Dashboard Files with Gulp
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Use Gulp to update and rebuild minified files and the appcache manifest after making changes to the front-end code.
```bash
gulp
```
--------------------------------
### Serve Custom Icofont CSS Locally
Source: https://github.com/node-red/node-red-dashboard/blob/master/README.md
Link to a locally served Icofont CSS file within a ui_template node's header.
```html
```
--------------------------------
### Type Initialization for Custom Widget
Source: https://github.com/node-red/node-red-dashboard/wiki/Creating-New-Dashboard-Widgets
Initializes the configuration for a custom widget type in Node-RED. This includes setting the category, color, default properties, and validation logic for widget dimensions.
```javascript
function mk_conf(NAME) {
var ICON = "icon.png";
var conf = {
category: 'dashboard',
color: 'rgb( 63, 173, 181)',
defaults: {
group: {type: 'ui_group', required:false},
name: {value: ''},
order: {value: 0},
width: {
value: 0,
validate: function(v) {
var valid = true
var width = v||0;
var currentGroup = $('#node-input-group').val()|| this.group;
var groupNode = RED.nodes.node(currentGroup);
valid = !groupNode || +width <= +groupNode.width;
$("#node-input-size").toggleClass("input-error",!valid);
return valid;
}},
height: {value: 0}
},
```
--------------------------------
### Configure Text Input Pass-through and Send on Blur
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_text_input.html
HTML for checkboxes controlling whether messages arriving on the input are passed through to the output and whether the value is sent when the input loses focus.
```html
```
--------------------------------
### UI Text Node Configuration Form
Source: https://github.com/node-red/node-red-dashboard/blob/master/nodes/ui_text.html
HTML structure for the configuration form of the ui_text node, including input fields for group, size, label, format, layout, and styling.
```html