Show select option text as label


#1

Hi folks,

The config screen of my custom node contains a dropdown:

<script type="text/x-red" data-template-name="math">
    <div class="form-row">
        <label for="node-input-operation"><i class="fa fa-calculator"></i> Operation</label>
        <select id="node-input-operation">
            <option value="value1">Some value</option>
            <option value="value2">Another value</option>
        </select>
    </div>
</script>

Depending on which value has been selected, I would like to show automatically the selected option TEXT as node label:
image

So I don't want to show the selected option VALUE:
image

Tried to accomplish that this way:

<script type="text/javascript">
    RED.nodes.registerType('math', {
        ...
        label: function() {
            var operationText = $("#node-input-operation option[value='" + this.operation + "']").text();
            return this.name || operationText || "Mathematics";
        },
        ...
    });
</script>

However I get no option text:

Does anybody have a clue how to solve this, or a another node that does a similar thing?

Thanks !
Bart


#2

I think the Inject node could be my starting point. Will have to figure out this evening how it works over there...


#3

@BartButenaers, it's interesting that you mention the inject node here. Its .html file could be a gold mine for beginning developers of contributed nodes, and it would be a great contribution if you or another NR guru could go through that file line by line and do a tutorial on how it does its magic. I've looked at it several times but always gotten lost before I could escape with anything useful.


#4

Hi Mike,

To be honest I have learned creating custom nodes by looking at the code of existing nodes. But indeed reading a step by step tutorial would have been easier. I haven't looked yet, but hasn't somebody meanwhile written some kind of developer guide for Node-RED already ??

About my issue. Don't think (?) the inject node can help me out.
But I think I'm already there. I'm unfamiliar with this kind of stuff, but I 'think' it works like this:

  1. The html part of the (custom) node is defined as an html template inside a <script> tag
  2. Since the script has a mime type type="text/x-red" unknown to the browser, it will not be loaded automatically in the DOM tree. Otherwise all config screens (from all installed nodes) would be visualized on top of each other, resulting in a complete mess.
  3. As soon as the node is double clicked, the html template content will be loaded (by Node-RED somewhere) in the browser's DOM tree.
  4. As a result, the node's config screen is visualised.

I might be mistaken by this, but when I execute this command in the 'Label' function:

$("script[data-template-name='math']")[0]

This way I search for a <script> tag with attribute data-template-name is equal to 'math'.
Then indeed the html content of my 'math' html template is displayed in my debugger:

image

Now I just need to get access to the list of available options from the <select> tag. But not quite sure I should load this into a temporary DOM tree or another way ...


#5

Why not just have a lookup object with the value to label pairs inside the label function? Mucking around with the Dom is needlessly complicated for what you're trying to do.


#6

Hey Nick,

I would like to maintain the value/description pairs only once (in html or in javascript). Therefore I wanted to search - from inside the Javascript functions - the descriptions that were defined in the html.

Do you mean I have to do it the other way around? I.e. create a map of key-value pairs in a Javascript variable, and afterwards (in oneditprepare) fill the html select options dynamically with the contents of that map?


#7

That's what the switch node does. https://github.com/node-red/node-red/blob/2f93bb969bd1a2130b942caedb098f303870d012/nodes/core/logic/10-switch.html#L81


#8

Hi Bart,

I've done pretty much the same thing. Some of the simpler nodes have taught me the basics, but it's been hard to find examples that help me learn more.

The NR documentation and Coursera videos are a great start. I wasn't looking for a node creation tutorial as much as a guide to using html/css effectively in the node edit dialog. I think I will just study some of core nodes with the W3schools tutorials at my side and pull myself up by the bootstraps.


#9

Mike,

Based on Nick's tip, it now seems to work fine...

Awaiting the printing company releasing my latest book "Developing Node-RED nodes for dummies", here is how this particular issue can be solved:

  1. Create an empty 'select' tag (without options):
    <script type="text/x-red" data-template-name="math">
       <div class="form-row">
         <label for="node-input-userValue"><i class="fa fa-calculator"></i> Value</label>
         <select id="node-input-userValue">
         </select>
       </div>
    </script>
    
  2. Create a (Javascript) variable containing an array with all value/description pairs:
    <script type="text/javascript">
       var values = [
         {v:"value1", t:"Some value"},
         {v:"value2", t:"Another value"},
       ];
    </script>
    
  3. As soon as a value is selected in the dropdown, the selected value needs to be stored in the node:
    defaults: {
        userValue: {value: ""}
    },
    
  4. As soon as the config screen is opened, the value/description pairs are dynamically added to that 'select' tag (as 'option' tags):
    oneditprepare: function() {             
        for (var i = 0; i < values.length; i++) {
           var value = values[i].v;
           var text = values[i].t;
           $('#node-input-userValue').append($("<option></option>").attr("value", value).text(text));
        }
             
        // Make sure the selected value is also selected in the <select> tag
        $('#node-input-userValue').val(this.userValue);
    }
    
  5. When the label is determined, we get the value description from that SAME array:
    label: function() {
       var valueText = "";
             
       for (var i = 0; i < values.length; i++) {
           if (values[i].v === this.userValue) {
               valueText = values[i].t;
               break;
           }
        }
    
        return this.name || valueText || "Mathematics";
    },
    

Bart


#10

Just a quick demo, to show how such a dynamic label can provide useful information to a user.
I have now published version 0.0.5 of node-red-contrib-msg-router to show the router type in the label:

router_label

Of course it is useles to reflect the content of every dropdown (on your config screen) in the node label.
But in this case, the dropdown content really changes the behaviour of the node...


#11

Wow! Great work. That sure looks nifty. Was needing to do something like this myself. If I could make a request, it would be to upload a barebones example project with this so new users can learn from it; rather than going through and picking out pieces of code from other nodes.


#12

I'd love to see the official docs improved, so if anyone want to funnel efforts in that direction rather than creating material outside of nodered.org, that would be great.