Template UI fed by template node msg.template - how to make it appear?

I use Template UI node a lot
image

and instead of entering code directly, I sometimes like to feed it from the Template node:

Sometimes I will like to put the Template node (the brown one) into a subflow along with some function nodes, so it can be re-used with multiple instances. The Template UI node (cyan colour) must stay outside of the subflow, so I can set the location of the template node (i.e. where it lives on the Dashboard):

I have done this quite a lot in the past and I have existing ones that work fine. But the one I just created now has a problem. It doesn't show on the dasboard. Well, sometimes it shows, but when I refresh the page, it disappears. Sometimes I can get it to show again by removing connections between nodes, and re-adding them, and hitting deploy. Then it shows on the dashboard, but again disappears when I refresh the dash. And then it stays gone and won't come back again.

(Note this happens when I use a subflow AND when I don't use a subflow.)

I have posted the example here, I wonder if someone can replicate the problem?

[{"id":"3d8b6d50.81d902","type":"subflow","name":"Multisensor","info":"","category":"","in":[{"x":60,"y":80,"wires":[{"id":"51791c41.49b794"}]}],"out":[{"x":700,"y":80,"wires":[{"id":"6d74ffdf.4d7e1","port":0}]}],"env":[{"name":"sensorid","type":"str","value":""}],"meta":{},"color":"#DDAA99"},{"id":"51791c41.49b794","type":"function","z":"3d8b6d50.81d902","name":"","func":"if (typeof msg.payload.Switch1.Action != undefined) {\n    if (msg.payload.Switch1.Action == \"ON\") {\n    // PIR on\n        \n    } else if (msg.payload.Switch1.Action == \"OFF\") {\n    // PIR off\n        \n    }\n} \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":80,"wires":[["6d74ffdf.4d7e1"]]},{"id":"6d74ffdf.4d7e1","type":"template","z":"3d8b6d50.81d902","name":"Sensor UI","field":"template","fieldType":"msg","format":"handlebars","syntax":"plain","template":"<style>\n    input {\n        width:150px;\n        margin:0 22px 0 0;\n        display:inline;\n        border-color: #eeeeee;\n        color: #eeeeee;\n        border-bottom-width: 1px;\n        font-family: inherit;\n        background: none;\n        padding: 2px 2px 1px;\n        border-width: 0 0 1px;\n        line-height: 26px;\n        height: 40px;\n        -ms-flex-preferred-size: 26px;\n        border-radius: 0;\n        border-style: solid;\n        box-sizing: border-box;\n        float: left;\n    }\n    md-select span {\n        color:#eee;\n    }\n    md-select .md-select-value.md-select-placeholder  {\n        border-bottom-color: #eee;\n    }\n    .md-select-value .md-select-icon:after {\n        border-bottom-color: #eee;\n        color:#eee;\n    }\n    md-select.md-default-theme .md-select-value, md-select .md-select-value {\n        border-bottom-color: #eee;\n    }\n    md-select.md-default-theme:not([disabled]):focus .md-select-value, md-select:not([disabled]):focus .md-select-value {\n        border-bottom-color: #0eb8c0;\n        border-bottom-width: 1px;\n    }\n    .md-button {\n        height:38px;\n    }\n    .md-container {\n    }\n    .sensorbutton {\n        display:inline !important;\n        padding:0px;height:38px !important;\n        width:85px;\n        margin:0 6px 0 0 !important;\n        background-color: #3b3b3b !important;\n    }\n    .triggered {\n        border-width:2px !important;\n        border-style:solid !important;\n    }\n    .pir {\n        background-color:rgb(33, 109, 55) !important;\n        border-color:rgb(99,200,100);\n        border-style: none;\n    }\n    .microwave {\n        background-color:rgb(134, 54, 54) !important;\n        border-color:rgb(241, 110, 110);\n        border-style: none;\n    }\n    .audiotrig {\n        background-color:rgb(153, 71, 0) !important;\n        border-color:rgb(244, 152, 73);\n        border-style: none;\n    }\n    .audioextend {\n        background-color:rgb(153, 144, 0) !important;\n        border-color:rgb(236,228,99);\n        border-style: none;\n    }\n    .leds {\n        background: -webkit-linear-gradient(left, orange , yellow, green, cyan, blue, violet); /* For Safari 5.1 to 6.0 */\n        background: -o-linear-gradient(right, orange, yellow, green, cyan, blue, violet); /* For Opera 11.1 to 12.0 */\n        background: -moz-linear-gradient(right, orange, yellow, green, cyan, blue, violet); /* For Firefox 3.6 to 15 */\n        background: linear-gradient(to right, #a52a2a, #ff8c00, #006400); /* Standard syntax (must be last) */\n    }\n    .control-row {\n        display:inline-flex; margin: 10px 0 10px 0\n    }\n\n</style>\n\n<!--New Scene-->\n<div class=\"control-row\">\n    <!-- classes as follows: sensorbutton is a button. pir/microwave/etc lights it up. triggered gives it a border -->\n    <md-button class=\"sensorbutton pir triggered\" ng-click=\"send({action: 'toggle_arm_pir', sensorid: msg.sensorid})\">PIR</md-button>\n    <md-button class=\"sensorbutton microwave triggered\" ng-click=\"send({action: 'toggle_arm_microwave', sensorid: msg.sensorid})\">Micro</md-button>\n    <md-button class=\"sensorbutton audiotrig triggered\" ng-click=\"send({action: 'toggle_arm_audiotrig', sensorid: msg.sensorid})\">Aud Trig</md-button>\n    <md-button class=\"sensorbutton audioextend triggered\" ng-click=\"send({action: 'toggle_arm_audioextend', sensorid: msg.sensorid})\">Aud Ext</md-button>\n    <md-button class=\"sensorbutton leds triggered\" ng-click=\"send({action: 'toggle_arm_leds', sensorid: msg.sensorid})\">LEDS</md-button>\n</div>\n\n\n<div class=\"slider-container\">\n    \n</div>\n","output":"str","x":520,"y":80,"wires":[[]]},{"id":"c25b3610.bca118","type":"subflow:3d8b6d50.81d902","z":"a0c2f06d.bcd7a","name":"","env":[{"name":"sensorid","value":"multisensor-003","type":"str"},{"name":"zonename","value":"3f_bedroom","type":"str"}],"x":750,"y":780,"wires":[["4b825b88.78ecf4"]]},{"id":"4b825b88.78ecf4","type":"ui_template","z":"a0c2f06d.bcd7a","group":"363d1eb5.19b652","name":"","order":13,"width":0,"height":0,"format":"","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","x":900,"y":780,"wires":[[]]},{"id":"26b3f65a.a8338a","type":"inject","z":"a0c2f06d.bcd7a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":".1","topic":"","payload":"","payloadType":"date","x":590,"y":780,"wires":[["c25b3610.bca118"]]},{"id":"363d1eb5.19b652","type":"ui_group","name":"Sense","tab":"79f7425a.a73e1c","order":3,"disp":true,"width":"6","collapse":false},{"id":"79f7425a.a73e1c","type":"ui_tab","name":"Bedroom","icon":"dashboard","order":2}]

I have currently not the possibillity to try to reproduce this, but this sounds to me like there is a Problem in the creation and deletion of some routes.

I experienced similar problems when i was creating a node with http functionality.
So what i observed was:
After restart of nodered everything was working.
After deploy, my node was not reachable.
In my case the cleanup function of the http route was not well implemented.
Maybe something in your case needs to be freed in the onclose method?

In your function, you compare the typeof msg.payload.Switch1.Action without verifying that msg.payload is an object or that msg.payload has a property called Switch1 - could it be some msg you send does not contain these properties and the function errors (thus not sending an output & therefore not populating the template node?)

Perhaps you should monitor the situation...

if(typeof msg.payload != "object") {
  node.warn("Subflow 'Multisensor' - Expected msg.payload to be an object");
}
if(typeof msg.payload.Switch1 != "object") {
  node.warn("Subflow 'Multisensor' - Expected msg.payload.Switch1 to be an object");
}
if (typeof msg.payload.Switch1.Action != undefined) {
    if (msg.payload.Switch1.Action == "ON") {
    // PIR on
        
    } else if (msg.payload.Switch1.Action == "OFF") {
    // PIR off
        
    }
}

Even if I take out the function node, and remove from the subflow, I still have the same problem:

[{"id":"26b3f65a.a8338a","type":"inject","z":"a0c2f06d.bcd7a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":".1","topic":"topic","payload":"","payloadType":"date","x":560,"y":860,"wires":[["e730cac9.350ea8"]]},{"id":"bd2337e2.e34758","type":"ui_template","z":"a0c2f06d.bcd7a","group":"363d1eb5.19b652","name":"","order":13,"width":0,"height":0,"format":"","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","x":900,"y":860,"wires":[[]]},{"id":"e730cac9.350ea8","type":"template","z":"a0c2f06d.bcd7a","name":"Sensor UI","field":"template","fieldType":"msg","format":"handlebars","syntax":"plain","template":"<style>\n    input {\n        width:150px;\n        margin:0 22px 0 0;\n        display:inline;\n        border-color: #eeeeee;\n        color: #eeeeee;\n        border-bottom-width: 1px;\n        font-family: inherit;\n        background: none;\n        padding: 2px 2px 1px;\n        border-width: 0 0 1px;\n        line-height: 26px;\n        height: 40px;\n        -ms-flex-preferred-size: 26px;\n        border-radius: 0;\n        border-style: solid;\n        box-sizing: border-box;\n        float: left;\n    }\n    md-select span {\n        color:#eee;\n    }\n    md-select .md-select-value.md-select-placeholder  {\n        border-bottom-color: #eee;\n    }\n    .md-select-value .md-select-icon:after {\n        border-bottom-color: #eee;\n        color:#eee;\n    }\n    md-select.md-default-theme .md-select-value, md-select .md-select-value {\n        border-bottom-color: #eee;\n    }\n    md-select.md-default-theme:not([disabled]):focus .md-select-value, md-select:not([disabled]):focus .md-select-value {\n        border-bottom-color: #0eb8c0;\n        border-bottom-width: 1px;\n    }\n    .md-button {\n        height:38px;\n    }\n    .md-container {\n    }\n    .sensorbutton {\n        display:inline !important;\n        padding:0px;height:38px !important;\n        width:85px;\n        margin:0 6px 0 0 !important;\n        background-color: #3b3b3b !important;\n    }\n    .triggered {\n        border-width:2px !important;\n        border-style:solid !important;\n    }\n    .pir {\n        background-color:rgb(33, 109, 55) !important;\n        border-color:rgb(99,200,100);\n        border-style: none;\n    }\n    .microwave {\n        background-color:rgb(134, 54, 54) !important;\n        border-color:rgb(241, 110, 110);\n        border-style: none;\n    }\n    .audiotrig {\n        background-color:rgb(153, 71, 0) !important;\n        border-color:rgb(244, 152, 73);\n        border-style: none;\n    }\n    .audioextend {\n        background-color:rgb(153, 144, 0) !important;\n        border-color:rgb(236,228,99);\n        border-style: none;\n    }\n    .leds {\n        background: -webkit-linear-gradient(left, orange , yellow, green, cyan, blue, violet); /* For Safari 5.1 to 6.0 */\n        background: -o-linear-gradient(right, orange, yellow, green, cyan, blue, violet); /* For Opera 11.1 to 12.0 */\n        background: -moz-linear-gradient(right, orange, yellow, green, cyan, blue, violet); /* For Firefox 3.6 to 15 */\n        background: linear-gradient(to right, #a52a2a, #ff8c00, #006400); /* Standard syntax (must be last) */\n    }\n    .control-row {\n        display:inline-flex; margin: 10px 0 10px 0\n    }\n\n</style>\n\n<!--New Scene-->\n<div class=\"control-row\">\n    <!-- classes as follows: sensorbutton is a button. pir/microwave/etc lights it up. triggered gives it a border -->\n    <md-button class=\"sensorbutton pir triggered\" ng-click=\"send({action: 'toggle_arm_pir', sensorid: msg.sensorid})\">PIR</md-button>\n    <md-button class=\"sensorbutton microwave triggered\" ng-click=\"send({action: 'toggle_arm_microwave', sensorid: msg.sensorid})\">Micro</md-button>\n    <md-button class=\"sensorbutton audiotrig triggered\" ng-click=\"send({action: 'toggle_arm_audiotrig', sensorid: msg.sensorid})\">Aud Trig</md-button>\n    <md-button class=\"sensorbutton audioextend triggered\" ng-click=\"send({action: 'toggle_arm_audioextend', sensorid: msg.sensorid})\">Aud Ext</md-button>\n    <md-button class=\"sensorbutton leds triggered\" ng-click=\"send({action: 'toggle_arm_leds', sensorid: msg.sensorid})\">LEDS</md-button>\n</div>\n\n\n<div class=\"slider-container\">\n    \n</div>\n","output":"str","x":740,"y":860,"wires":[["bd2337e2.e34758","b2f6f91c.544838"]]},{"id":"b2f6f91c.544838","type":"debug","z":"a0c2f06d.bcd7a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":800,"wires":[]},{"id":"363d1eb5.19b652","type":"ui_group","name":"Sense","tab":"79f7425a.a73e1c","order":3,"disp":true,"width":"6","collapse":false},{"id":"79f7425a.a73e1c","type":"ui_tab","name":"Bedroom","icon":"dashboard","order":2}]

It's weird. Whenever I edit the brown template node and deploy, it works. Then after a single refresh, it disappears!

Add this css to your template and its working :slight_smile:
Dunno why the md card opacity is zero on refresh but this fixed it.

    .md-card{
        opacity:100;
    }

EDIT:
well not really. now its just working in 5 out of 10 tries.
seems like a bug.

the nr-dashboard-cardcontainer and the nr-dashboard-template css class sometimes generate a height of 0px.
The interesting part here is that i could not reproduce it when my developer console was on in the browser. so i had to close it and then pressing several times F5 and then it disapeared.

Sounds like a rendering problem to me. Like the Template node tries to determine the size of the container before the childs have been inserted.

You can even remove the complete Style tag and content to reproduce it

here the quellcode copy from my browser

<div class="nr-dashboard-cardcontainer" id="Bedroom_Sense_cards" ng-transclude="" ng-style="{width:ctrl.width, height:ctrl.height}" style="width: 318px; height: 0px;"> <!----><!----><md-card ui-template="me.item.format" ui-card-size="6x0" class="nr-dashboard-template " ng-class="{'nr-dashboard-disabled':me.item.disabled}" ng-show="true" node-id="bd2337e2.e34758" aria-hidden="false" style="left: 0px; top: 0px; width: 318px; height: 0px;">
    <div>
        <button class="sensorbutton pir triggered md-button md-ink-ripple" type="button" ng-transclude="" ng-click="send({action: 'toggle_arm_pir', sensorid: msg.sensorid})">PIR</button>
        <button class="sensorbutton microwave triggered md-button md-ink-ripple" type="button" ng-transclude="" ng-click="send({action: 'toggle_arm_microwave', sensorid: msg.sensorid})">Micro</button>
        <button class="sensorbutton audiotrig triggered md-button md-ink-ripple" type="button" ng-transclude="" ng-click="send({action: 'toggle_arm_audiotrig', sensorid: msg.sensorid})">Aud Trig</button>
        <button class="sensorbutton audioextend triggered md-button md-ink-ripple" type="button" ng-transclude="" ng-click="send({action: 'toggle_arm_audioextend', sensorid: msg.sensorid})">Aud Ext</button>
        <button class="sensorbutton leds triggered md-button md-ink-ripple" type="button" ng-transclude="" ng-click="send({action: 'toggle_arm_leds', sensorid: msg.sensorid})">LEDS</button>
    </div>
    
    
    <div class="slider-container">
        
    </div>

</md-card><!----> </div>

I investigated a bit more.
after changing the template to something completly different

<div>
<button class="md-button">1</button>
<button class="md-button">2</button>
<button class="md-button">3</button>
<button class="md-button">4</button>
<button class="md-button">5</button>
<button class="md-button">6</button>
</div>

and hitting the deploy it still shows me the old content. After F5 the new content is there. With a new Deploy the old content ? this seems a bit suspicious

opera_bug_nodered_dashboard

Yes, this is similar to the problem I am having.

I re-added the UI Template node (blue one) and this time kept its original content (last time I removed it):

and then the HTML showed up all the time in dashboard.

However now when I want to change the content, it does not show the new version. I have tried to inject a message into the template node, to see if it re-sends msg.template to the UI template node but it doesn't update it.

I don't have the expertise to understand whether this is a buy, or a rendering/ caching issue.

I'm using Chrome for Windows, Node-RED 1.3.4

It seems to alleviate the problem if I set the initial inject node to inject after 2 seconds instead of 0.1 seconds. Then I change the template UI node to "reload last value on refresh", which means you don't have to wait the full 2 seconds after a refresh for it to show on the dash.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.