Extract html input field value to payload

#1

Hey all,
I've created an input field in the template node and I just want to extract it to use in my flows.

Here's the basic input field (without the brackets): input type="text" name="joel"

And then I'd like to take the users input and do something with it. How can I access the value in the html input field and use it in my node-red flow logic?

Sending msg.payload inside template function
#2

So you have to send out a message from the template node. Whenever I want to send, I use the following line of code in my template nodes:

//Declare once to make scope available in functions
var theScope = scope;

//then use where needed
theScope.send({payload:'whatever'});

The message will appear on the output of the template node and from there you can continue with the next step in your flow

1 Like
#3

Thanks @krambriw that makes sense. But how do I reference the input field value in {payload: ${JSvariable??}}
I can't seem to find the correct method...

#4

I suppose you are inside the template nodes html code now? To send something initiated via the web page defined in the template node, I typically have html code when I click the mouse button like this:

onMouseDown="SendMessage('entrance lamp', this)"

This will call my javascript function

    function SendMessage(eventname, el){
        if(el.className == "on") {
            el.className="off";
            //writeToScreen(eventname+' turnoff');
            theScope.send({payload:eventname+' turnoff'});
            } 
        else {
            el.className="on";
            //writeToScreen(eventname+' turnon');
            theScope.send({payload:eventname+' turnon'});
            } 
        return false;
    }

To wait and listen to events coming into the template node, I have the following javascript code:

    scope.$watch('msg', function(msg) {
        //writeToScreen(msg.payload);
        inMessage(msg.payload);
    });

When an incoming message arrives, the function inMessage is called where you do whatever is needed based on the payload

Hope this helps

Kind regards, Walter

#5

Sorry @krambriw I'm missing something here, so would the template node look something like this?

<button onMouseDown="SendMessage()">SendVarToPayload</button>

<script>
    var eventname = 'hi';
    function SendMessage(){
        theScope.send({payload:eventname+' turnoff'});
    }
</script>

Assuming the resulting msg.payload = 'hi turnoff'

1 Like
#6

Correction!! I got it, was just missing the scope declaration.

Thanks again sir!

#7

Great, good to hear!
It is very powerful to use, I have built some nice web pages using template nodes, showing all kind of info including live videos, buttons to control lamps etc etc

#8

Indeed.

@krambriw hopefully last question - how would I pre-populate html input fields in a template node with variables from a javascript function? I am trying the following in an attempt to set the temp1 field with the value from an array payload[0].temp :

<head>
    <script>
        var test = {{payload[0].temp}};
        let fetchTemp = () => {
            document.getElementById("temp1").value = test;
        }
    </script>
</head>
<body>
    <button onMouseDown="fetchTemp()">Assign temp</button>
</body>
#9

I think you are very close, try just to add the id to the html code like this

<body>
    <button id="temp1" onMouseDown="fetchTemp()">Assign temp</button>
</body>

As example from my code, I have a typical line in the html to show the status of our home, "At home" or "Away". It looks like this:

<td><div style="text-align:center"><button id="emptyhouse" class="off" style="font-size:150%; background-color:black; height:60px; width:280px">&nbsp;AtHome</button></div></td>

When it is time to update, basically controlled by the state of our home alarm system, I use this javascript code:

        if (event === "Status.armed") {
            document.getElementById("emptyhouse").style.backgroundColor="#FBF14D";
            document.getElementById("emptyhouse").style.color ="black";
            document.getElementById("emptyhouse").className = "on";
            document.getElementById("emptyhouse").style.fontSize ="25";
            document.getElementById("emptyhouse").innerHTML = "&nbsp;Away";
        }
        if (event === "Status.unarmed"||event === "Status.armedhome") {
            document.getElementById("emptyhouse").style.backgroundColor="black";
            document.getElementById("emptyhouse").style.color ="white";
            document.getElementById("emptyhouse").className = "off";
            document.getElementById("emptyhouse").style.fontSize ="25";
            document.getElementById("emptyhouse").innerHTML = "&nbsp;AtHome";
        }

As you see, using document.getElementById you can control many other attributes as well

#10

As you have no doubt found out, you cannot substitute payload values into your <script> ... </script> elements. Instead, you need to use the scope.watch code that Walter provided earlier to get the msg and update the element with the new value.

Also, your template source is NOT a complete html page -- so any <head> ... </head> elements are ignored. Only the body portion of your template in inserted into the overall Dashboard page layout. If you really need something added to the head of the dashboard, put it into a separate ui_template and select Template Type: "Added to site <head> section"

#11

Ok cool thanks for the info @shrickus!

#12

I have looked for days how to do that
and everything refers to scope.$watch()
kind of things that never worked on what I want.
I can not believe it was so simple. Thank you very much.
This should be included in ui_template documentation instead of
the current example imho.

#13

If you can summarise the example you want to see we can certainly look to add/replace it.
(or indeed a Pull request would be welcome)

#14

thanks a lot for your code (simple idea and a good result)