mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			327 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!--
 | |
|   Copyright 2016 IBM Corp.
 | |
| 
 | |
|   Licensed under the Apache License, Version 2.0 (the "License");
 | |
|   you may not use this file except in compliance with the License.
 | |
|   You may obtain a copy of the License at
 | |
| 
 | |
|   http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
|   Unless required by applicable law or agreed to in writing, software
 | |
|   distributed under the License is distributed on an "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|   See the License for the specific language governing permissions and
 | |
|   limitations under the License.
 | |
| -->
 | |
| 
 | |
| <script type="text/x-red" data-template-name="link in">
 | |
|     <div class="form-row">
 | |
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
 | |
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
 | |
|     </div>
 | |
|     <div class="form-row node-input-link-row"></div>
 | |
| </script>
 | |
| <script type="text/x-red" data-template-name="link out">
 | |
|     <div class="form-row">
 | |
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
 | |
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
 | |
|     </div>
 | |
|     <div class="form-row node-input-link-row"></div>
 | |
| </script>
 | |
| <script type="text/x-red" data-help-name="link in">
 | |
|     <p>Create virtual wires between flows.</p>
 | |
|     <p>The node can be connected to any <b>link out</b> node that exists on any tab.
 | |
|        Once connected, they behave as if they were wired together.</p>
 | |
|     <p>The wires between link nodes are only displayed when a link node is selected.
 | |
|        If there are any wires to other tabs, a virtual node is show that can be clicked
 | |
|        on to jump to the appropriate tab.</p>
 | |
|     <p>Links cannot be created going into, or out of, a subflow.</p>
 | |
| </script>
 | |
| <script type="text/x-red" data-help-name="link out">
 | |
|     <p>Create virtual wires between flows.</p>
 | |
|     <p>The node can be connected to any <b>link in</b> node that exists on any tab.
 | |
|        Once connected, they behave as if they were wired together.</p>
 | |
|     <p>The wires between link nodes are only displayed when a link node is selected.
 | |
|        If there are any wires to other tabs, a virtual node is show that can be clicked
 | |
|        on to jump to the appropriate tab.</p>
 | |
|     <p>Links cannot be created going into, or out of, a subflow.</p>
 | |
| </script>
 | |
| <style>
 | |
| #node-input-link-container {
 | |
|     position: relative;
 | |
| }
 | |
| #node-input-link-container li {
 | |
|     padding: 2px 5px;
 | |
|     background: none;
 | |
|     font-size: 0.8em;
 | |
|     margin:0;
 | |
|     white-space: nowrap;
 | |
| }
 | |
| #node-input-link-container li label {
 | |
|     margin-bottom: 0;
 | |
|     width: 100%;
 | |
| }
 | |
| #node-input-link-container li label input {
 | |
|     vertical-align: top;
 | |
|     width:15px;
 | |
|     margin-right: 10px;
 | |
| }
 | |
| #node-input-link-container li:hover,
 | |
| #node-input-link-container li:hover .node-input-target-node-sublabel {
 | |
|     background: #f0f0f0;
 | |
| }
 | |
| .node-input-link-node-sublabel {
 | |
|     position:absolute;
 | |
|     right: 0px;
 | |
|     padding-right: 10px;
 | |
|     padding-left: 10px;
 | |
|     font-size: 0.8em;
 | |
| }
 | |
| </style>
 | |
| 
 | |
| <script type="text/javascript">
 | |
| (function() {
 | |
| 
 | |
|     function sortNodeList(nodeList,sortOn,sortOnSecond) {
 | |
|         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-link-container-div .fa").hide();
 | |
|         $(".node-input-link-sort-"+currentSort+"-"+currentSortOrder).show();
 | |
| 
 | |
| 
 | |
|         var items = nodeList.find("li").get();
 | |
|         items.sort(function(a,b) {
 | |
|             var labelA = $(a).find(".node-input-link-node-"+currentSort).text().toLowerCase();
 | |
|             var labelB = $(b).find(".node-input-link-node-"+currentSort).text().toLowerCase();
 | |
|             if (labelA < labelB) { return currentSortOrder==='a'?-1:1; }
 | |
|             if (labelA > labelB) { return currentSortOrder==='a'?1:-1; }
 | |
| 
 | |
|             if (sortOnSecond) {
 | |
|                 labelA = $(a).find(".node-input-link-node-"+sortOnSecond).text().toLowerCase();
 | |
|                 labelB = $(b).find(".node-input-link-node-"+sortOnSecond).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);
 | |
|         });
 | |
|     }
 | |
|     function onEditPrepare(node,targetType) {
 | |
|         if (!node.links) {
 | |
|             node.links = [];
 | |
|         }
 | |
|         node.oldLinks = [];
 | |
| 
 | |
|         $('<div id="node-input-link-container-div" style="min-height: 100px;position: relative;   box-sizing: border-box; border-radius: 2px; height: 180px;  border: 1px solid #ccc;overflow:hidden; ">'+
 | |
|             '    <div style="box-sizing: border-box; line-height: 20px; font-size: 0.8em; border-bottom: 1px solid #ddd; height: 20px;">'+
 | |
|             '        <div style="display: inline-block;margin-left: 5px;"><a id="node-input-link-sort-label" href="#" data-i18n="[title]link.label.sortByLabel"><span data-i18n="link.label.node">name</span> <i class="node-input-link-sort-label-a fa fa-caret-down"></i><i class="node-input-link-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-link-sort-type" href="#" data-i18n="[title]link.label.sortByFlow"><i class="node-input-link-sort-sublabel-a fa fa-caret-down"></i><i class="node-input-link-sort-sublabel-d fa fa-caret-up"></i> <span data-i18n="link.label.type">flow</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-link-container" style=" list-style-type:none; margin: 0;"></ul>'+
 | |
|             '    </div>'+
 | |
|             '</div>').appendTo('.node-input-link-row');
 | |
| 
 | |
|         var nodeList = $("#node-input-link-container");
 | |
|         var candidateNodes = RED.nodes.filterNodes({type:targetType});
 | |
|         var inSubflow = (RED.nodes.subflow(node.z) != null);
 | |
|         candidateNodes.forEach(function(n) {
 | |
|             if (inSubflow) {
 | |
|                 if (n.z !== node.z) {
 | |
|                     return;
 | |
|                 }
 | |
|             } else {
 | |
|                 if (RED.nodes.subflow(n.z)!=null) {
 | |
|                     return;
 | |
|                 }
 | |
|             }
 | |
|             var isChecked = false;
 | |
| 
 | |
|             isChecked = (node.links.indexOf(n.id) !== -1) || (n.links||[]).indexOf(node.id) !== -1;
 | |
| 
 | |
|             if (isChecked) {
 | |
|                 node.oldLinks.push(n.id);
 | |
|             }
 | |
| 
 | |
|             var container = $('<li/>',{class:"node-input-link-node"});
 | |
|             var row = $('<label/>',{for:"node-input-link-node-"+n.id}).appendTo(container);
 | |
|             $('<input>',{type:"checkbox",class:"node-input-link-node-checkbox",id:"node-input-link-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 label = n.name||n.id;
 | |
|             var sublabel;
 | |
|             var tab = RED.nodes.workspace(n.z);
 | |
|             if (tab) {
 | |
|                 sublabel = tab.label||tab.id;
 | |
|             } else {
 | |
|                 tab = RED.nodes.subflow(n.z);
 | |
|                 sublabel = "subflow : "+tab.name;
 | |
|             }
 | |
|             $('<span>',{class:"node-input-link-node-label",style:"white-space:nowrap"}).text(label).appendTo(row);
 | |
|             if (sublabel) {
 | |
|                 $('<span>',{class:"node-input-link-node-sublabel"}).text(sublabel).appendTo(row);
 | |
|             }
 | |
|             container.appendTo(nodeList);
 | |
|         });
 | |
| 
 | |
|         sortNodeList(nodeList,'sublabel','label');
 | |
| 
 | |
|         $("#node-input-link-sort-label").click(function(e) {
 | |
|             e.preventDefault();
 | |
|             sortNodeList(nodeList,'label');
 | |
|         });
 | |
| 
 | |
|         $("#node-input-link-sort-type").click(function(e) {
 | |
|             e.preventDefault();
 | |
|             sortNodeList(nodeList,'sublabel');
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     function resizeNodeList() {
 | |
|         var rows = $("#dialog-form>div:not(.node-input-link-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-link-row");
 | |
|         height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
 | |
|         $("#node-input-link-container-div").css("height",height+"px");
 | |
|     }
 | |
| 
 | |
|     function onEditSave(node) {
 | |
|         node.links = [];
 | |
|         $(".node-input-link-node-checkbox").each(function(n) {
 | |
|             if ($(this).prop("checked")) {
 | |
|                 node.links.push($(this).data('node-id'));
 | |
|             }
 | |
|         })
 | |
|         node.oldLinks.sort();
 | |
|         node.links.sort();
 | |
|         var nodeMap = {};
 | |
|         var length = Math.max(node.oldLinks.length,node.links.length);
 | |
|         for (var i=0;i<length;i++) {
 | |
|             if (i<node.oldLinks.length) {
 | |
|                 nodeMap[node.oldLinks[i]] = nodeMap[node.oldLinks[i]]||{};
 | |
|                 nodeMap[node.oldLinks[i]].old = true;
 | |
|             }
 | |
|             if (i<node.links.length) {
 | |
|                 nodeMap[node.links[i]] = nodeMap[node.links[i]]||{};
 | |
|                 nodeMap[node.links[i]].new = true;
 | |
|             }
 | |
|         }
 | |
|         var n;
 | |
|         for (var id in nodeMap) {
 | |
|             if (nodeMap.hasOwnProperty(id)) {
 | |
|                 n = RED.nodes.node(id);
 | |
|                 if (n) {
 | |
|                     if (nodeMap[id].old && !nodeMap[id].new) {
 | |
|                         // Removed id
 | |
|                         i = n.links.indexOf(node.id);
 | |
|                         if (i > -1) {
 | |
|                             n.links.splice(i,1);
 | |
|                         }
 | |
|                     } else if (!nodeMap[id].old && nodeMap[id].new){
 | |
|                         // Added id
 | |
|                         i = n.links.indexOf(id);
 | |
|                         if (i === -1) {
 | |
|                             n.links.push(node.id);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function onAdd() {
 | |
|         for (var i=0;i<this.links.length;i++) {
 | |
|             var n = RED.nodes.node(this.links[i]);
 | |
|             if (n.links.indexOf(this.id) === -1) {
 | |
|                 n.links.push(this.id);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     RED.nodes.registerType('link in',{
 | |
|         category: 'input',
 | |
|         color:"#ddd",//"#87D8CF",
 | |
|         defaults: {
 | |
|             name: {value:""},
 | |
|             links: { value: [] }
 | |
|         },
 | |
|         inputs:0,
 | |
|         outputs:1,
 | |
|         icon: "link-out.png",
 | |
|         label: function() {
 | |
|             return this.name||this._("link.linkIn");
 | |
|         },
 | |
|         labelStyle: function() {
 | |
|             return this.name?"node_label_italic":"";
 | |
|         },
 | |
|         oneditprepare: function() {
 | |
|             onEditPrepare(this,"link out");
 | |
|         },
 | |
|         oneditsave: function() {
 | |
|             onEditSave(this);
 | |
|         },
 | |
|         onadd: onAdd,
 | |
|         oneditresize: resizeNodeList
 | |
|     });
 | |
| 
 | |
|     RED.nodes.registerType('link out',{
 | |
|         category: 'output',
 | |
|         color:"#ddd",//"#87D8CF",
 | |
|         defaults: {
 | |
|             name: {value:""},
 | |
|             links: { value: []}
 | |
|         },
 | |
|         align:"right",
 | |
|         inputs:1,
 | |
|         outputs:0,
 | |
|         icon: "link-out.png",
 | |
|         label: function() {
 | |
|             return this.name||this._("link.linkOut");
 | |
|         },
 | |
|         labelStyle: function() {
 | |
|             return this.name?"node_label_italic":"";
 | |
|         },
 | |
|         oneditprepare: function() {
 | |
|             onEditPrepare(this,"link in");
 | |
|         },
 | |
|         oneditsave: function() {
 | |
|             onEditSave(this);
 | |
|         },
 | |
|         onadd: onAdd,
 | |
|         oneditresize: resizeNodeList
 | |
|     });
 | |
| })();
 | |
| </script>
 |