2015-02-20 02:17:24 +01:00
< script type = "text/x-red" data-template-name = "catch" >
2015-08-13 14:58:19 +02:00
< div class = "form-row" >
< label style = "width: auto" for = "node-input-scope" data-i18n = "catch.label.source" > < / label >
< select id = "node-input-scope-select" >
< option value = "all" data-i18n = "catch.scope.all" > < / option >
< option value = "target" data-i18n = "catch.scope.selected" > < / options >
< / select >
< / div >
2016-05-06 18:19:32 +02:00
< div class = "form-row node-input-target-row" style = "display: none;" >
< div id = "node-input-catch-target-container-div" style = "min-height: 100px;position: relative; box-sizing: border-box; border-radius: 2px; height: 180px; border: 1px solid #ccc;overflow:hidden; " >
2015-08-13 14:58:19 +02:00
< div style = "box-sizing: border-box; line-height: 20px; font-size: 0.8em; border-bottom: 1px solid #ddd; height: 20px;" >
< input type = "checkbox" data-i18n = "[title]catch.label.selectAll" id = "node-input-target-node-checkbox-all" style = "width: 30px; margin: 0 2px 1px 2px;" >
< div style = "display: inline-block;" > < a id = "node-input-target-sort-label" href = "#" data-i18n = "[title]catch.label.sortByLabel" > < span data-i18n = "catch.label.node" > < / span > < i class = "node-input-catch-sort-label-a fa fa-caret-down" > < / i > < i class = "node-input-catch-sort-label-d fa fa-caret-up" > < / i > < / a > < / div >
< div style = "position: absolute; right: 10px; width: 50px; display: inline-block; text-align: right;" > < a id = "node-input-target-sort-type" href = "#" data-i18n = "[title]catch.label.sortByType" > < i class = "node-input-catch-sort-sublabel-a fa fa-caret-down" > < / i > < i class = "node-input-catch-sort-sublabel-d fa fa-caret-up" > < / i > < span data-i18n = "catch.label.type" > < / span > < / a > < / div >
< / div >
< div style = "background: #fbfbfb; box-sizing: border-box; position:absolute; top:20px;bottom:0;left:0px;right:0px; overflow-y: scroll; overflow-x: hidden;" >
< ul id = "node-input-catch-target-container" style = " list-style-type:none; margin: 0;" > < / ul >
< / div >
< / div >
< / div >
2015-02-20 02:17:24 +01:00
< div class = "form-row" >
2015-05-10 22:47:22 +02:00
< label for = "node-input-name" > < i class = "fa fa-tag" > < / i > < span data-i18n = "common.label.name" > < / span > < / label >
2015-05-26 22:11:14 +02:00
< input type = "text" id = "node-input-name" data-i18n = "[placeholder]common.label.name" >
2015-02-20 02:17:24 +01:00
< / div >
< / script >
< script type = "text/x-red" data-help-name = "catch" >
2015-02-20 21:55:46 +01:00
< p > Catch errors thrown by nodes on the same tab.< / p >
2017-04-24 21:36:27 +02:00
< h3 > Outputs< / h3 >
< dl class = "message-properties" >
2017-05-23 18:26:23 +02:00
< dt > error.message < span class = "property-type" > string< / span > < / dt >
2017-04-24 21:36:27 +02:00
< dd > the error message.< / dd >
2017-05-23 18:26:23 +02:00
< dt > error.source.id < span class = "property-type" > string< / span > < / dt >
2017-04-24 21:36:27 +02:00
< dd > the id of the node that threw the error.< / dd >
2017-05-23 18:26:23 +02:00
< dt > error.source.type < span class = "property-type" > string< / span > < / dt >
2017-04-24 21:36:27 +02:00
< dd > the type of the node that threw the error.< / dd >
2017-05-23 18:26:23 +02:00
< dt > error.source.name < span class = "property-type" > string< / span > < / dt >
2017-04-24 21:36:27 +02:00
< dd > the name, if set, of the node that threw the error.< / dd >
< / dl >
< h3 > Details< / h3 >
2017-05-23 18:26:23 +02:00
< p > If a node throws an error whilst handling a message, the flow will typically
2015-02-20 21:55:46 +01:00
halt. This node can be used to catch those errors and handle them with a
dedicated flow.< / p >
2017-05-23 18:26:23 +02:00
< p > By default, the node will catch errors thrown by any node on the same tab. Alternatively
it can be targetted at specific nodes.< / p >
< p > When an error is thrown, all matching catch nodes will receive the message.< / p >
2015-02-20 21:55:46 +01:00
< p > If an error is thrown within a subflow, the error will get handled by any
2017-05-23 18:26:23 +02:00
catch nodes within the subflow. If none exists, the error will be propagated
2015-02-20 21:55:46 +01:00
up to the tab the subflow instance is on.< / p >
2017-05-23 18:26:23 +02:00
< p > If the message already has a < code > error< / code > property, it is copied to < code > _error< / code > .< / p >
2015-02-20 02:17:24 +01:00
< / script >
2015-08-13 14:58:19 +02:00
< style >
#node-input-catch-target-container {
position: relative;
}
#node-input-catch-target-container li {
padding: 2px 5px;
background: none;
font-size: 0.8em;
margin:0;
white-space: nowrap;
}
#node-input-catch-target-container li label {
margin-bottom: 0;
width: 100%;
}
#node-input-catch-target-container li label input {
vertical-align: top;
width:15px;
margin-right: 10px;
}
#node-input-catch-target-container li:hover,
#node-input-catch-target-container li:hover .node-input-target-node-sublabel {
background: #f0f0f0;
}
.node-input-target-node-sublabel {
position:absolute;
right: 0px;
padding-right: 10px;
padding-left: 10px;
font-size: 0.8em;
background: #fbfbfb;
}
< / style >
2015-02-20 02:17:24 +01:00
< script type = "text/javascript" >
RED.nodes.registerType('catch',{
category: 'input',
color:"#e49191",
defaults: {
2015-08-13 14:58:19 +02:00
name: {value:""},
scope: {value:null}
2015-02-20 02:17:24 +01:00
},
inputs:0,
outputs:1,
2015-02-20 21:55:46 +01:00
icon: "alert.png",
2015-02-20 02:17:24 +01:00
label: function() {
2016-03-01 22:58:57 +01:00
return this.name||(this.scope?this._("catch.catchNodes",{number:this.scope.length}):this._("catch.catch"));
2015-02-20 02:17:24 +01:00
},
labelStyle: function() {
return this.name?"node_label_italic":"";
2015-08-13 14:58:19 +02:00
},
oneditprepare: function() {
var nodeList = $("#node-input-catch-target-container");
var node = this;
2016-01-04 17:53:32 +01:00
this.resize = function() {
var rows = $("#dialog-form>div:not(.node-input-target-row)");
var height = $("#dialog-form").height();
for (var i=0;i< rows.size ( ) ; i + + ) {
height -= $(rows[i]).outerHeight(true);
}
var editorRow = $("#dialog-form>div.node-input-target-row");
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
$("#node-input-catch-target-container-div").css("height",height+"px");
2017-04-24 21:36:27 +02:00
};
2016-01-04 17:53:32 +01:00
2015-08-13 14:58:19 +02:00
function createNodeList() {
2015-08-24 15:47:17 +02:00
var scope = node.scope || [];
2015-08-13 14:58:19 +02:00
nodeList.empty();
var candidateNodes = RED.nodes.filterNodes({z:node.z});
var allChecked = true;
candidateNodes.forEach(function(n) {
if (n.id === node.id) {
return;
}
2015-08-24 15:47:17 +02:00
var isChecked = scope.indexOf(n.id) !== -1;
2015-08-13 14:58:19 +02:00
allChecked = allChecked & & isChecked;
var container = $('< li / > ',{class:"node-input-target-node"});
var row = $('< label / > ',{for:"node-input-target-node-"+n.id}).appendTo(container);
$('< input > ',{type:"checkbox",class:"node-input-target-node-checkbox",id:"node-input-target-node-"+n.id})
.data('node-id',n.id)
.prop('checked', isChecked)
.appendTo(row);
container.on('mouseover',function(e) {
n.highlighted = true;
n.dirty = true;
RED.view.redraw();
});
container.on('mouseout',function(e) {
n.highlighted = false;
n.dirty = true;
RED.view.redraw();
});
var labelSpan = $('< span > ');
var nodeDef = RED.nodes.getType(n.type);
var label;
var sublabel;
if (nodeDef) {
var l = nodeDef.label;
label = (typeof l === "function" ? l.call(n) : l)||"";
sublabel = n.type;
if (sublabel.indexOf("subflow:") === 0) {
var subflowId = sublabel.substring(8);
var subflow = RED.nodes.subflow(subflowId);
sublabel = "subflow : "+subflow.name;
}
}
if (!nodeDef || !label) {
label = n.type;
}
$('< span > ',{class:"node-input-target-node-label",style:"white-space:nowrap"}).text(label).appendTo(row);
if (sublabel) {
$('< span > ',{class:"node-input-target-node-sublabel"}).text(sublabel).appendTo(row);
}
container.appendTo(nodeList);
});
$(".node-input-target-node-checkbox").change(function() {
if (!this.checked) {
$("#node-input-target-node-checkbox-all").prop('checked',false);
}
});
$("#node-input-target-node-checkbox-all").prop('checked',allChecked);
sortNodeList('label');
}
function sortNodeList(sortOn) {
var currentSort = nodeList.data('currentSort');
var currentSortOrder = nodeList.data('currentSortOrder');
if (!currentSort) {
currentSort = sortOn;
currentSortOrder = 'a';
} else {
if (currentSort === sortOn) {
currentSortOrder = (currentSortOrder === 'a'?'d':'a');
} else {
currentSortOrder = 'a';
}
currentSort = sortOn;
}
nodeList.data('currentSort',currentSort);
nodeList.data('currentSortOrder',currentSortOrder);
$("#node-input-catch-target-container-div .fa").hide();
$(".node-input-catch-sort-"+currentSort+"-"+currentSortOrder).show();
var items = nodeList.find("li").get();
items.sort(function(a,b) {
var labelA = $(a).find(".node-input-target-node-"+currentSort).text().toLowerCase();
var labelB = $(b).find(".node-input-target-node-"+currentSort).text().toLowerCase();
if (labelA < labelB ) { return currentSortOrder = =='a'?-1:1; }
if (labelA > labelB) { return currentSortOrder==='a'?1:-1; }
return 0;
});
$.each(items, function(i, li){
nodeList.append(li);
});
}
$("#node-input-target-sort-label").click(function(e) {
e.preventDefault();
sortNodeList('label');
});
$("#node-input-target-sort-type").click(function(e) {
e.preventDefault();
2017-04-24 21:36:27 +02:00
sortNodeList('sublabel');
2015-08-13 14:58:19 +02:00
});
$("#node-input-target-node-checkbox-all").change(function() {
$(".node-input-target-node-checkbox").prop('checked',this.checked);
2017-04-24 21:36:27 +02:00
});
2015-08-13 14:58:19 +02:00
$("#node-input-scope-select").change(function(e) {
2016-07-04 12:21:58 +02:00
var scope = $(this).val();
2015-08-13 14:58:19 +02:00
if (scope === "target") {
createNodeList();
$(".node-input-target-row").show();
} else {
$(".node-input-target-row").hide();
}
2016-01-04 17:53:32 +01:00
node.resize();
2015-08-13 14:58:19 +02:00
});
2017-04-24 21:36:27 +02:00
if (this.scope === null) {
2015-08-13 14:58:19 +02:00
$("#node-input-scope-select").val("all");
} else {
$("#node-input-scope-select").val("target");
}
$("#node-input-scope-select").change();
},
oneditsave: function() {
2016-07-04 12:21:58 +02:00
var scope = $("#node-input-scope-select").val();
2015-08-13 14:58:19 +02:00
if (scope === 'all') {
this.scope = null;
} else {
var node = this;
node.scope = [];
$(".node-input-target-node-checkbox").each(function(n) {
if ($(this).prop("checked")) {
node.scope.push($(this).data('node-id'));
}
2017-04-24 21:36:27 +02:00
});
2015-08-13 14:58:19 +02:00
}
2016-01-04 17:53:32 +01:00
},
oneditresize: function(size) {
this.resize();
2015-02-20 02:17:24 +01:00
}
});
< / script >