diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 1386a8ea5..ba7e48900 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -345,6 +345,47 @@ } } }; + + // For a type with options, check value is a valid selection + // If !opt.multiple, returns the valid option object + // if opt.multiple, returns an array of valid option objects + // If not valid, returns null; + + function isOptionValueValid(opt, currentVal) { + if (!opt.multiple) { + for (var i=0;i').appendTo(this.uiSelect); this.optionExpandButtonIcon = $('').appendTo(this.optionExpandButton); - // Used to remember selections per-type to restore them when switching between types - this.oldValues = {}; - this.type(this.options.default||this.typeList[0].value); }catch(err) { console.log(err.stack); @@ -859,22 +899,44 @@ return this.propertyType; } else { var that = this; + var previousValue = null; var opt = this.typeMap[type]; if (opt && this.propertyType !== type) { // If previousType is !null, then this is a change of the type, rather than the initialisation var previousType = this.typeMap[this.propertyType]; var typeChanged = !!previousType; + previousValue = this.input.val(); if (typeChanged) { if (previousType.options && opt.hasValue !== true) { - this.oldValues[previousType.value] = this.input.val(); + this.oldValues[previousType.value] = previousValue; } else if (previousType.hasValue === false) { - this.oldValues[previousType.value] = this.input.val(); + this.oldValues[previousType.value] = previousValue; } else { - this.oldValues["_"] = this.input.val(); + this.oldValues["_"] = previousValue; } if ((opt.options && opt.hasValue !== true) || opt.hasValue === false) { - this.input.val(this.oldValues.hasOwnProperty(opt.value)?this.oldValues[opt.value]:(opt.default||[]).join(",")) + if (this.oldValues.hasOwnProperty(opt.value)) { + this.input.val(this.oldValues[opt.value]); + } else { + // No old value for the option type. + // It is possible code has called 'value' then 'type' + // to set the selected option. This is what the Inject/Switch/Change + // nodes did before 2.1. + // So we need to be careful to not reset the value if it is a valid option. + var validOptions = isOptionValueValid(opt,previousValue); + if (previousValue && validOptions) { + this.input.val(previousValue); + } else { + if (typeof opt.default === "string") { + this.input.val(opt.default); + } else if (Array.isArray(opt.default)) { + this.input.val(opt.default.join(",")) + } else { + this.input.val(""); + } + } + } } else { this.input.val(this.oldValues.hasOwnProperty("_")?this.oldValues["_"]:(opt.default||"")) } @@ -951,22 +1013,12 @@ var op; if (!opt.hasValue) { - var validValue = false; - var currentVal = this.input.val(); + // Check the value is valid for the available options + var validValues = isOptionValueValid(opt,this.input.val()); if (!opt.multiple) { - for (var i=0;iThe Link Call node lets you call another flow that begins with a Link In node and get the result back when the message reaches a Link Out node.

' }, }, - + { + title: {"en-US":"MQTT nodes support dynamic connections"}, + prepare(done) { + $('[data-palette-type="mqtt out"]')[0].scrollIntoView({block:"center"}) + setTimeout(done,100); + }, + element: '[data-palette-type="mqtt out"]', + direction: "right", + description: { "en-US": '

The MQTT nodes now support creating their connections and subscriptions dynamically.

' }, + }, { title: {"en-US":"File nodes renamed"}, prepare(done) { $('[data-palette-type="file"]')[0].scrollIntoView({block:"center"}) setTimeout(done,100); }, + complete() { + if (this.paletteWasClosed) { + RED.actions.invoke("core:toggle-palette",false) + } + }, element: '[data-palette-type="file"]', direction: "right", description: { "en-US": '

The file nodes have been renamed to make it clearer which node does what.

' }, diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/node_modules/@node-red/nodes/core/common/20-inject.html index 41fa8b66f..bd17e1635 100644 --- a/packages/node_modules/@node-red/nodes/core/common/20-inject.html +++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.html @@ -539,12 +539,10 @@ var propertyValue = $('',{class:"node-input-prop-property-value",type:"text"}) .css("width","calc(70% - 30px)") .appendTo(row) - .typedInput({default:'str',types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']}); + .typedInput({default:prop.vt,types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']}); propertyName.typedInput('value',prop.p); - propertyValue.typedInput('value',prop.v); - propertyValue.typedInput('type',prop.vt); }, removable: true, sortable: true diff --git a/packages/node_modules/@node-red/nodes/core/function/10-switch.html b/packages/node_modules/@node-red/nodes/core/function/10-switch.html index e0827b40f..f6fc82f0a 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-switch.html +++ b/packages/node_modules/@node-red/nodes/core/function/10-switch.html @@ -117,30 +117,35 @@ return r; } - function createValueField(row){ - return $('',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + function createValueField(row, defaultType){ + return $('',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); } - function createNumValueField(row){ - return $('',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']}); + function createNumValueField(row, defaultType){ + return $('',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:defaultType||'num',types:['flow','global','num','jsonata','env']}); } function createExpValueField(row){ - return $('',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']}); + return $('',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:'jsonata',types:['jsonata']}); } - function createBtwnValueField(row){ - return $('',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + function createBtwnValueField(row, defaultType){ + return $('',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); } - function createBtwnValue2Field(row3, andLabel){ + function createBtwnValue2Field(row3, andLabel, defaultType){ $('
',{class:"node-input-rule-btwn-label", style:"width: 120px; text-align: right;"}).text(" "+andLabel+" ").appendTo(row3); var row3InputCell = $('
',{style:"flex-grow:1; margin-left: 5px;"}).appendTo(row3); - return $('',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + return $('',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell) + .typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); } - function createTypeValueField(){ - return $('',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'string',types:[ + function createTypeValueField(row, defaultType){ + return $('',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:defaultType || 'string',types:[ {value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"}, {value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"}, {value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"}, @@ -279,24 +284,12 @@ selectField.on("change", function() { var fieldToFocus; var type = selectField.val(); - if (valueField){ - valueField.typedInput('hide'); - } - if (expValueField){ - expValueField.typedInput('hide'); - } - if (numValueField){ - numValueField.typedInput('hide'); - } - if (typeValueField){ - typeValueField.typedInput('hide'); - } - if (btwnValueField){ - btwnValueField.typedInput('hide'); - } - if (btwnValue2Field){ - btwnValue2Field.typedInput('hide'); - } + if (valueField) { valueField.typedInput('hide'); } + if (expValueField) { expValueField.typedInput('hide'); } + if (numValueField) { numValueField.typedInput('hide'); } + if (typeValueField) { typeValueField.typedInput('hide'); } + if (btwnValueField) { btwnValueField.typedInput('hide'); } + if (btwnValue2Field) { btwnValue2Field.typedInput('hide'); } if ((type === "btwn") || (type === "index")) { if (!btwnValueField){ @@ -319,7 +312,7 @@ } else if (type === "istype") { if (!typeValueField){ - typeValueField = createTypeValueField(); + typeValueField = createTypeValueField(rowInputCell); } typeValueField.typedInput('show'); fieldToFocus = typeValueField; @@ -362,48 +355,26 @@ // } }); selectField.val(rule.t); - if ((rule.t == "btwn") || (rule.t == "index")) { - if (!btwnValueField){ - btwnValueField = createBtwnValueField(rowInputCell); - } - btwnValueField.typedInput('value',rule.v); - btwnValueField.typedInput('type',rule.vt||'num'); - if (!btwnValue2Field){ - btwnValue2Field = createBtwnValue2Field(row3, andLabel); - } + if ((rule.t == "btwn") || (rule.t == "index")) { + btwnValueField = createBtwnValueField(rowInputCell,rule.vt||'num'); + btwnValueField.typedInput('value',rule.v); + btwnValue2Field = createBtwnValue2Field(row3, andLabel,rule.v2t||'num'); btwnValue2Field.typedInput('value',rule.v2); - btwnValue2Field.typedInput('type',rule.v2t||'num'); } else if ((rule.t === "head") || (rule.t === "tail")) { - if (!numValueField){ - numValueField = createNumValueField(row); - } + numValueField = createNumValueField(rowInputCell,rule.vt||'num'); numValueField.typedInput('value',rule.v); - numValueField.typedInput('type',rule.vt||'num'); } else if (rule.t === "istype") { - if (!typeValueField){ - typeValueField =createTypeValueField(); - } + typeValueField = createTypeValueField(rowInputCell,rule.vt); typeValueField.typedInput('value',rule.vt); - typeValueField.typedInput('type',rule.vt); } else if (rule.t === "jsonata_exp") { - if (!expValueField){ - expValueField = createExpValueField(row); - } + expValueField = createExpValueField(rowInputCell,rule.vt||'jsonata'); expValueField.typedInput('value',rule.v); - expValueField.typedInput('type',rule.vt||'jsonata'); } else if (typeof rule.v != "undefined") { - if (!valueField){ - valueField = createValueField(rowInputCell); - } + valueField = createValueField(rowInputCell,rule.vt||'str'); valueField.typedInput('value',rule.v); - valueField.typedInput('type',rule.vt||'str'); - } - if (rule.case) { - caseSensitive.prop('checked',true); - } else { - caseSensitive.prop('checked',false); } + caseSensitive.prop('checked',!!rule.case); selectField.change(); var currentOutputs = JSON.parse(outputCount.val()||"{}"); diff --git a/packages/node_modules/@node-red/nodes/core/function/15-change.html b/packages/node_modules/@node-red/nodes/core/function/15-change.html index 80bba7361..b40039028 100644 --- a/packages/node_modules/@node-red/nodes/core/function/15-change.html +++ b/packages/node_modules/@node-red/nodes/core/function/15-change.html @@ -115,12 +115,12 @@ var regex = this._("change.label.regex"); var deepCopyLabel = this._("change.label.deepCopy"); - function createPropertyValue(row2_1,row2_2) { + function createPropertyValue(row2_1, row2_2, defaultType) { var propValInput = $('',{class:"node-input-rule-property-value",type:"text"}) .appendTo(row2_1) - .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']}); + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']}); - var dcLabel = $('').appendTo(row2_2); + var dcLabel = $('').appendTo(row2_2); var deepCopy = $('').appendTo(dcLabel) $('').text(deepCopyLabel).appendTo(dcLabel) @@ -129,20 +129,20 @@ }) return [propValInput, deepCopy]; } - function createFromValue(row3_1) { + function createFromValue(row3_1, defaultType) { return $('',{class:"node-input-rule-property-search-value",type:"text"}) .appendTo(row3_1) - .typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']}); + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','re','num','bool','env']}); } - function createToValue(row3_2) { + function createToValue(row3_2, defaultType) { return $('',{class:"node-input-rule-property-replace-value",type:"text"}) .appendTo(row3_2) - .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']}); + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','env']}); } - function createMoveValue(row4) { + function createMoveValue(row4, defaultType) { return $('',{class:"node-input-rule-property-move-value",type:"text"}) .appendTo(row4) - .typedInput({default:'msg',types:['msg','flow','global']}); + .typedInput({default:defaultType||'msg',types:['msg','flow','global']}); } $('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({ @@ -268,33 +268,22 @@ propertyName.typedInput('value',rule.p); propertyName.typedInput('type',rule.pt); if (rule.t == "set") { - if(!propertyValue) { - var parts = createPropertyValue(row2_1, row2_2); - propertyValue = parts[0]; - deepCopy = parts[1]; - } + var parts = createPropertyValue(row2_1, row2_2, rule.tot); + propertyValue = parts[0]; + deepCopy = parts[1]; propertyValue.typedInput('value',rule.to); - propertyValue.typedInput('type',rule.tot); deepCopy.prop("checked", !!rule.dc); } if (rule.t == "move") { - if(!moveValue) { - moveValue = createMoveValue(row4); - } + moveValue = createMoveValue(row4,rule.tot); moveValue.typedInput('value',rule.to); - moveValue.typedInput('type',rule.tot); } if (rule.t == "change") { - if(!fromValue) { - fromValue = createFromValue(row3_1); - } + fromValue = createFromValue(row3_1, rule.fromt); fromValue.typedInput('value',rule.from); - fromValue.typedInput('type',rule.fromt); - if (!toValue) { - toValue = createToValue(row3_2); - } + + toValue = createToValue(row3_2,rule.tot); toValue.typedInput('value',rule.to); - toValue.typedInput('type',rule.tot); } selectField.change(); container[0].appendChild(fragment);