diff --git a/docs/nodes/widgets/ui-number-input.md b/docs/nodes/widgets/ui-number-input.md index 280828f58..f14d21a65 100644 --- a/docs/nodes/widgets/ui-number-input.md +++ b/docs/nodes/widgets/ui-number-input.md @@ -15,6 +15,18 @@ props: Label: description: The number shown within the number input field. dynamic: true + Min: + description: Defines the minimum allowable value for the number input field. + dynamic: true + Max: + description: Defines the maximum allowable value for the number input field. + dynamic: true + Step: + description: Sets the increment/decrement step for adjusting the number value in the input field. + dynamic: true + Spinner: + description: Sets the layout of the spinners either as inline or stacked. + dynamic: true Tooltip: description: The number shown when hovering over the number input field. Passthrough: If this node receives a msg in Node-RED, should it be passed through to the output as if a new value was inserted to the input? @@ -42,9 +54,24 @@ dynamic: Icon Position: payload: msg.ui_update.iconPosition structure: ["String"] + examples: ["left", "right"] Icon Inner Position: payload: msg.ui_update.iconInnerPosition structure: ["String"] + examples: ["inside", "outside"] + Min: + payload: msg.ui_update.min + structure: ["Number"] + Max: + payload: msg.ui_update.max + structure: ["Number"] + Step: + payload: msg.ui_update.step + structure: ["Number"] + Spinner: + payload: msg.ui_update.spinner + structure: ["String"] + --- \ No newline at end of file diff --git a/nodes/widgets/ui_number_input.html b/nodes/widgets/ui_number_input.html index 4dace794a..b7a4bc8b5 100644 --- a/nodes/widgets/ui_number_input.html +++ b/nodes/widgets/ui_number_input.html @@ -27,7 +27,14 @@ topicType: { value: 'msg' }, min: { value: 0, required: true, validate: RED.validators.number() }, max: { value: 10, required: true, validate: RED.validators.number() }, - step: { value: 1 }, + step: { + value: 1, + validate: function (v) { + const isValid = RED.validators.number()(v) && v > 0 + $('#node-input-step').toggleClass('input-error', !isValid) + return isValid + } + }, tooltip: { value: '' }, passthru: { value: true }, sendOnBlur: { value: true }, @@ -36,7 +43,8 @@ clearable: { value: false }, icon: { value: '' }, iconPosition: { value: 'left' }, - iconInnerPosition: { value: 'inside' } + iconInnerPosition: { value: 'inside' }, + spinner: { value: 'default' } }, inputs: 1, outputs: 1, @@ -101,6 +109,10 @@ if (!this.iconInnerPosition) { $('#node-input-iconInnerPosition').val('inside') } + + if (!this.spinner) { + $('#node-input-spinner').val('default') + } }, label: function () { return this.name || (~this.label.indexOf('{' + '{') ? null : this.label) || this.mode + ' input' @@ -164,6 +176,13 @@ +
+ + +
diff --git a/nodes/widgets/ui_number_input.js b/nodes/widgets/ui_number_input.js index f2434e542..4fa727276 100644 --- a/nodes/widgets/ui_number_input.js +++ b/nodes/widgets/ui_number_input.js @@ -1,4 +1,6 @@ const datastore = require('../store/data.js') +const statestore = require('../store/state.js') +const { appendTopic } = require('../utils/index.js') module.exports = function (RED) { function NumberInputNode (config) { @@ -15,6 +17,37 @@ module.exports = function (RED) { const evts = { onChange: true, + beforeSend: async function (msg) { + const updates = msg.ui_update + if (updates) { + if (typeof updates.label !== 'undefined') { + // dynamically set "label" property + statestore.set(group.getBase(), node, msg, 'label', updates.label) + } + if (typeof updates.clearable !== 'undefined') { + // dynamically set "clearable" property + statestore.set(group.getBase(), node, msg, 'clearable', updates.clearable) + } + if (typeof updates.icon !== 'undefined') { + // dynamically set "icon" property + statestore.set(group.getBase(), node, msg, 'icon', updates.icon) + } + if (typeof updates.iconPosition !== 'undefined') { + // dynamically set "iconPosition" property + statestore.set(group.getBase(), node, msg, 'iconPosition', updates.iconPosition) + } + if (typeof updates.iconInnerPosition !== 'undefined') { + // dynamically set "iconInnerPosition" property + statestore.set(group.getBase(), node, msg, 'iconInnerPosition', updates.iconInnerPosition) + } + if (typeof updates.spinner !== 'undefined') { + // dynamically set "spinner" property + statestore.set(group.getBase(), node, msg, 'spinner', updates.spinner) + } + } + msg = await appendTopic(RED, config, node, msg) + return msg + }, onInput: function (msg, send) { // store the latest msg passed to node datastore.save(group.getBase(), node, msg) diff --git a/ui/src/widgets/ui-number-input/UINumberInput.vue b/ui/src/widgets/ui-number-input/UINumberInput.vue index 2b39b4a86..e845240f9 100644 --- a/ui/src/widgets/ui-number-input/UINumberInput.vue +++ b/ui/src/widgets/ui-number-input/UINumberInput.vue @@ -1,16 +1,18 @@