UNPKG

node-red-contrib-routing

Version:

A Node-RED node to route incoming messages based on their topics.

153 lines (146 loc) 6.88 kB
<script type="text/javascript"> RED.nodes.registerType('routing',{ category: 'function', color: '#E9967A', defaults: { name: {value:""}, rules: {value: [{v: ""}]}, outputs: {value: 1} }, inputs:1, outputs:1, outputLabels: function(index) { var rule = this.rules[index]; if (rule.v) { return rule.v.length > 15 ? rule.v.substring(0,15) + " …" : rule.v; } else { return "Default route"; } }, icon: 'switch.png', label: function() { return this.name||'routing'; }, oneditprepare: function() { var node = this; var outputCount = $("#node-input-outputs").val("{}"); function resizeRule(rule) { var newWidth = rule.width(); var valueField = rule.find(".node-input-rule-value"); valueField.css("width",(newWidth-70)); } $("#node-input-rule-container").css('min-height','250px').css('min-width','450px').editableList({ addItem: function(container,i,opt) { if (!opt.hasOwnProperty('r')) { opt.r = {}; } var rule = opt.r; if (!opt.hasOwnProperty('i')) { opt._i = Math.floor((0x99999-0x10000)*Math.random()).toString(16); } var row = $('<div/>').appendTo(container); var row2 = $('<div/>',{style:"padding-top: 5px; padding-left: 175px;"}).appendTo(container); var row3 = $('<div/>',{style:"padding-top: 5px; padding-left: 102px;"}).appendTo(container); var valueField = $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row); var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row); finalspan.append(' &#8594; <span class="node-input-rule-index">'+(i+1)+'</span> '); resizeRule(container); if (typeof rule.v != "undefined") { valueField.val(rule.v); } var currentOutputs = JSON.parse(outputCount.val()||"{}"); currentOutputs[opt.hasOwnProperty('i')?opt.i:opt._i] = i; outputCount.val(JSON.stringify(currentOutputs)); }, removeItem: function(opt) { var currentOutputs = JSON.parse(outputCount.val()||"{}"); if (opt.hasOwnProperty('i')) { currentOutputs[opt.i] = -1; } else { delete currentOutputs[opt._i]; } var rules = $("#node-input-rule-container").editableList('items'); rules.each(function(i) { $(this).find(".node-input-rule-index").html(i+1); var data = $(this).data('data'); currentOutputs[data.hasOwnProperty('i')?data.i:data._i] = i; }); outputCount.val(JSON.stringify(currentOutputs)); }, resizeItem: resizeRule, sortItems: function(rules) { var currentOutputs = JSON.parse(outputCount.val()||"{}"); var rules = $("#node-input-rule-container").editableList('items'); rules.each(function(i) { $(this).find(".node-input-rule-index").html(i+1); var data = $(this).data('data'); currentOutputs[data.hasOwnProperty('i')?data.i:data._i] = i; }); outputCount.val(JSON.stringify(currentOutputs)); }, sortable: true, removable: true }); for (var i=0;i<this.rules.length;i++) { var rule = this.rules[i]; $("#node-input-rule-container").editableList('addItem',{r:rule,i:i}); } }, oneditsave: function() { var rules = $("#node-input-rule-container").editableList('items'); var node = this; node.rules = []; rules.each(function(i) { var value = $(this).find(".node-input-rule-value").val(); node.rules.push({ v: value }); }); this.propertyType = $("#node-input-property").typedInput('type'); }, oneditresize: function(size) { var rows = $("#dialog-form>div:not(.node-input-rule-container-row)"); var height = size.height; for (var i=0;i<rows.size();i++) { height -= $(rows[i]).outerHeight(true); } var editorRow = $("#dialog-form>div.node-input-rule-container-row"); height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); $("#node-input-rule-container").editableList('height',height); } }); </script> <script type="text/x-red" data-template-name="routing"> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> <input type="hidden" id="node-input-outputs"/> </div> <div class="form-row node-input-rule-container-row"> <ol id="node-input-rule-container"></ol> </div> </script> <script type="text/x-red" data-help-name="routing"> <p>Route messages based on their topics.</p> <h3>Details</h3> <p>When a message arrives, the node will forward the message according to its topic and the defined routes.</p> <p>Order of route declaration doesn't matter, the most specific route wins. It parses query strings and supports wildcard.</p> <h3>Examples</h3> <ol class="node-ports"> <dl class="message-properties"> <dt> (empty) <dd> Default route</dd> </dt> <dt>temperature <dd> Simple match</dd> </dt> <dt>iot/:sensor/temperature <dd> <code>iot/AJ08/temperature</code> will match and <code>msg.params.sensor</code> will be <code>AJ08</code></dd> </dt> <dt>iot/*path <dd> <code>iot/AJ08/humidity</code> will match and <code>msg.params.path</code> will be <code>AJ08/humidity</code></dd> </dt> </dl> </ol> <p>Check <a href="https://github.com/chrisdavies/rlite" target="_blank">rlite's documentation</a> for more information.</p> </script>