diff --git a/editor/js/ui/typedInput.js b/editor/js/ui/typedInput.js
index 94abdb9a0..1fd63abc0 100644
--- a/editor/js/ui/typedInput.js
+++ b/editor/js/ui/typedInput.js
@@ -124,21 +124,11 @@
this.options.types = this.options.types||Object.keys(allOptions);
- var hasSubOptions = false;
- this.typeMap = {};
- this.types = this.options.types.map(function(opt) {
- var result;
- if (typeof opt === 'string') {
- result = allOptions[opt];
- } else {
- result = opt;
- }
- that.typeMap[result.value] = result;
- if (result.options) {
- hasSubOptions = true;
- }
- return result;
- });
+ this.selectTrigger = $('').prependTo(this.uiSelect);
+ $('').appendTo(this.selectTrigger);
+ this.selectLabel = $('').appendTo(this.selectTrigger);
+
+ this.types(this.options.types);
if (this.options.typeField) {
this.typeField = $(this.options.typeField).hide();
@@ -150,13 +140,6 @@
this.typeField = $("",{type:'hidden'}).appendTo(this.uiSelect);
}
- this.selectTrigger = $('').prependTo(this.uiSelect);
- $('').appendTo(this.selectTrigger);
- if (this.types.length === 1) {
- this.selectTrigger.addClass("disabled");
- }
- this.selectLabel = $('').appendTo(this.selectTrigger);
-
this.element.on('focus', function() {
that.uiSelect.addClass('red-ui-typedInput-focus');
});
@@ -166,36 +149,29 @@
this.element.on('change', function() {
that.validate();
})
- if (this.types.length > 1) {
- this.selectTrigger.click(function(event) {
- event.preventDefault();
+ this.selectTrigger.click(function(event) {
+ event.preventDefault();
+ if (that.typeList.length > 1) {
that._showMenu(that.menu,that.selectTrigger);
- });
- } else {
- this.selectTrigger.click(function(event) {
- event.preventDefault();
+ } else {
that.element.focus();
- })
- }
+ }
+ });
+ // explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
+ this.optionSelectTrigger = $('').appendTo(this.uiSelect);
+ this.optionSelectLabel = $('').prependTo(this.optionSelectTrigger);
+ this.optionSelectTrigger.click(function(event) {
+ event.preventDefault();
+ if (that.optionMenu) {
+ that.optionMenu.css({
+ minWidth:that.optionSelectLabel.width()
+ });
- if (hasSubOptions) {
- // explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
- this.optionSelectTrigger = $('').appendTo(this.uiSelect);
- this.optionSelectLabel = $('').prependTo(this.optionSelectTrigger);
- this.optionSelectTrigger.click(function(event) {
- event.preventDefault();
- if (that.optionMenu) {
- that.optionMenu.css({
- minWidth:that.optionSelectLabel.width()
- });
-
- that._showMenu(that.optionMenu,that.optionSelectLabel)
- }
- });
- }
- this.menu = this._createMenu(this.types, function(v) { that.type(v) });
- this.type(this.options.default||this.types[0].value);
+ that._showMenu(that.optionMenu,that.optionSelectLabel)
+ }
+ });
+ this.type(this.options.default||this.typeList[0].value);
},
_hideMenu: function(menu) {
$(document).off("mousedown.close-property-select");
@@ -278,7 +254,6 @@
return labelWidth;
},
_resize: function() {
-
if (this.typeMap[this.propertyType] && this.typeMap[this.propertyType].hasValue === false) {
this.selectTrigger.width(this.uiWidth+5);
} else {
@@ -298,6 +273,29 @@
_destroy: function() {
this.menu.remove();
},
+ types: function(types) {
+ var that = this;
+ var currentType = this.type();
+ this.typeMap = {};
+ this.typeList = types.map(function(opt) {
+ var result;
+ if (typeof opt === 'string') {
+ result = allOptions[opt];
+ } else {
+ result = opt;
+ }
+ that.typeMap[result.value] = result;
+ return result;
+ });
+ this.selectTrigger.toggleClass("disabled", this.typeList.length === 1);
+ if (this.menu) {
+ this.menu.remove();
+ }
+ this.menu = this._createMenu(this.typeList, function(v) { that.type(v) });
+ if (currentType && !this.typeMap.hasOwnProperty(currentType)) {
+ this.type(this.typeList[0].value);
+ }
+ },
width: function(desiredWidth) {
this.uiWidth = desiredWidth;
this._resize();
@@ -359,9 +357,14 @@
this.optionSelectTrigger.hide();
}
if (opt.hasValue === false) {
+ this.oldValue = this.element.val();
this.element.val("");
this.element.hide();
} else {
+ if (this.oldValue !== undefined) {
+ this.element.val(this.oldValue);
+ delete this.oldValue;
+ }
this.element.show();
}
this.element.trigger('change');
diff --git a/nodes/core/logic/17-split.html b/nodes/core/logic/17-split.html
index e847baf0d..5e0cb1a04 100644
--- a/nodes/core/logic/17-split.html
+++ b/nodes/core/logic/17-split.html
@@ -44,7 +44,7 @@
color:"#E2D96E",
defaults: {
name: {value:""},
- splt: {value:""}
+ splt: {value:"\\n"}
},
inputs:1,
outputs:1,
@@ -61,12 +61,12 @@
diff --git a/nodes/core/logic/17-split.js b/nodes/core/logic/17-split.js
index ece2d9b69..48d6314a2 100644
--- a/nodes/core/logic/17-split.js
+++ b/nodes/core/logic/17-split.js
@@ -68,6 +68,9 @@ module.exports = function(RED) {
function JoinNode(n) {
RED.nodes.createNode(this,n);
+ this.property = n.property||"payload";
+ this.propertyType = n.propertyType||"msg";
+ this.key = n.key||"topic";
this.timer = Number(n.timeout || 0);
this.timerr = n.timerr || "send";
this.count = Number(n.count || 0);
@@ -78,10 +81,6 @@ module.exports = function(RED) {
var misc = (this.build === "array") ? [] : {};
var tout;
- function isObject (item) {
- return (typeof item === "object" && !Array.isArray(item)&& ! Buffer.isBuffer(item) && item !== null);
- }
-
// if array came from a string then reassemble it and send it
var sendIt = function(m) {
if (inflight[m.parts.id].ch !== undefined) { // if it was a string - rejoin it using the split char
@@ -116,80 +115,93 @@ module.exports = function(RED) {
m.payload = misc.join(node.joiner.replace(/\\n/,"\n").replace(/\\r/,"\r").replace(/\\t/,"\t").replace(/\\e/,"\e").replace(/\\f/,"\c").replace(/\\0/,"\0"));
}
if (node.build === "array") { misc = []; }
- if (node.build === "object") { misc = {}; }
+ else if (node.build === "object") { misc = {}; }
node.send(m);
}
this.on("input", function(msg) {
- if (msg.hasOwnProperty("payload")) {
- if (msg.hasOwnProperty("parts")) { // only act if it has parts
- var count = node.count || msg.parts.count || 1;
- if (msg.parts.hasOwnProperty("index")) { // it's a numbered part (from a split node)
- if (!inflight[msg.parts.id]) { // New message - create new empty array of correct size
- if (msg.parts.type === "object") {
- inflight[msg.parts.id] = {i:0, a:{}, c:msg.parts.count, ch:msg.parts.ch, t:msg.parts.type};
- } else { // it's an array or string
- inflight[msg.parts.id] = {i:0, a:new Array(msg.parts.count), ch:msg.parts.ch, t:msg.parts.type};
- }
- if (node.timer !== 0) { // If there is a timer to set start it now
- inflight[msg.parts.id].timeout = setTimeout(function() {
- if (node.timerr === "send") { sendIt(msg); }
- if (node.timerr === "error") { node.error("Incomplete",msg); }
- delete inflight[msg.parts.id];
- }, node.timer);
- }
- }
+ var property;
+ if (node.propertyType == "full") {
+ property = msg;
+ } else {
+ try {
+ property = RED.util.getMessageProperty(msg,node.property);
+ } catch(err) {
+ node.warn("Message property "+node.property+" not found");
+ return;
+ }
+ }
+ if (msg.hasOwnProperty("parts")) {
+ // only act if it has parts
+ var count = node.count || msg.parts.count || 1;
+ if (msg.parts.hasOwnProperty("index")) {
+ // it's a numbered part (from a split node)
+ if (!inflight[msg.parts.id]) {
+ // New message - create new empty array of correct size
if (msg.parts.type === "object") {
- inflight[msg.parts.id].a[msg.parts.key] = msg.payload; // Add to the tracking array
- inflight[msg.parts.id].i = Object.keys(inflight[msg.parts.id].a).length;
- } else { // it's an array or string
- inflight[msg.parts.id].a[msg.parts.index] = msg.payload; // Add to the tracking array
- inflight[msg.parts.id].i += 1; // Increment the count
+ inflight[msg.parts.id] = {i:0, a:{}, c:msg.parts.count, ch:msg.parts.ch, t:msg.parts.type};
+ } else {
+ // it's an array or string
+ inflight[msg.parts.id] = {i:0, a:new Array(msg.parts.count), ch:msg.parts.ch, t:msg.parts.type};
}
- if (inflight[msg.parts.id].i >= count) { sendIt(msg); } // All arrived - send
- } // otherwise ignore it
- if (msg.hasOwnProperty("complete")) { // if set then send right away anyway...
- delete(msg.complete);
+ if (node.timer !== 0) { // If there is a timer to set start it now
+ inflight[msg.parts.id].timeout = setTimeout(function() {
+ if (node.timerr === "send") { sendIt(msg); }
+ else if (node.timerr === "error") { node.error("Incomplete",msg); }
+ delete inflight[msg.parts.id];
+ }, node.timer);
+ }
+ }
+ if (msg.parts.type === "object") {
+ // Add to the tracking array
+ inflight[msg.parts.id].a[msg.parts.key] = property;
+ inflight[msg.parts.id].i = Object.keys(inflight[msg.parts.id].a).length;
+ } else {
+ // it's an array or string
+ // Add to the tracking array
+ inflight[msg.parts.id].a[msg.parts.index] = property;
+ // Increment the count
+ inflight[msg.parts.id].i += 1;
+ }
+ if (inflight[msg.parts.id].i >= count) {
+ // All arrived - send
sendIt(msg);
}
+ } // otherwise ignore it
+ if (msg.hasOwnProperty("complete")) { // if set then send right away anyway...
+ delete(msg.complete);
+ sendIt(msg);
}
-
+ } else {
// The case for any messages arriving without parts - ie random messages you want to join.
- else {
- var l;
- if (node.build === "array") { // simple case of build the array
- misc.push(msg.payload); // Add the payload to an array
- l = misc.length;
- } else { // OK so let's build an object
- if ((msg.key === undefined) && ((msg.topic === undefined) || (msg.topic === ''))) {
- if (isObject(msg.payload)) { // if it's already an object (and no topic or key) just append it
- misc = Object.assign(misc,msg.payload);
- l = Object.keys(misc).length;
- }
- else { // if no topic or key and not an object then warn and drop it.
- node.warn("key or topic not defined");
- return;
- }
- }
- else { // if it's got a msg.key or msg.topic then use key||topic as the property name
- misc[ msg.key || msg.topic ] = msg.payload;
- //if (msg.topic) { msg.topic = (msg.topic.split('/')).slice(0,-1).join('/'); }
- l = Object.keys(misc).length;
- }
- }
- if (l >= node.count) { sendMisc(msg); } // if it's long enough send it
- else if (msg.hasOwnProperty("complete")) { // if set then send right away anyway...
- delete(msg.complete);
- sendMisc(msg);
- }
- else if ((node.timer !== 0) && !tout) { // if not start the timer if there is one.
- tout = setTimeout(function() {
- if (node.timerr === "send") { sendMisc(msg); }
- if (node.timerr === "error") { node.error("Timeout",msg); }
- if (node.build === "array") { misc = []; }
- if (node.build === "object") { misc = {}; }
- }, node.timer);
+ var l;
+ if (node.build === "array" || node.build === "string") {
+ // simple case of build the array
+ // Add the payload to an array
+ misc.push(property);
+ l = misc.length;
+ } else {
+ // OK so let's build an object
+ if (msg.hasOwnProperty(node.key) && msg[node.key] !== "") {
+ misc[msg[node.key]] = property;
}
+ l = Object.keys(misc).length;
+ }
+ if (l >= node.count) {
+ // if it's long enough send it
+ sendMisc(msg);
+ } else if (msg.hasOwnProperty("complete")) {
+ // if set then send right away anyway...
+ delete(msg.complete);
+ sendMisc(msg);
+ } else if ((node.timer !== 0) && !tout) {
+ // if not start the timer if there is one.
+ tout = setTimeout(function() {
+ if (node.timerr === "send") { sendMisc(msg); }
+ else if (node.timerr === "error") { node.error("Timeout",msg); }
+ if (node.build === "array") { misc = []; }
+ else if (node.build === "object") { misc = {}; }
+ }, node.timer);
}
}
});
diff --git a/test/nodes/core/logic/17-split_spec.js b/test/nodes/core/logic/17-split_spec.js
index cc34c3274..b77768b89 100644
--- a/test/nodes/core/logic/17-split_spec.js
+++ b/test/nodes/core/logic/17-split_spec.js
@@ -181,8 +181,9 @@ describe('JOIN node', function() {
msg.payload.should.have.property("b","2");
msg.payload.should.have.property("c",true);
msg.payload.should.have.property("d");
- msg.payload.d.should.have.property("e",5);
- msg.payload.should.have.property("f",6);
+ msg.payload.d.should.have.property("e",7);
+ msg.payload.should.have.property("g");
+ msg.payload.g.should.have.property("f",6);
done();
}
catch(e) { }//console.log(e); }
@@ -191,7 +192,8 @@ describe('JOIN node', function() {
n1.receive({payload:"2", topic:"b"});
n1.receive({payload:true, topic:"c"});
n1.receive({payload:{e:5}, topic:"d"});
- n1.receive({payload:{f:6}});
+ n1.receive({payload:{e:7}, topic:"d"});
+ n1.receive({payload:{f:6}, topic:"g"});
});
});