Populating a popup form Template node

I have a interactive page where I have a popup that display a form that then can be submitted.
All of that seems to be working well but I would also like to prepopulate the field with the selected data.
The data comes from the payload in the form of an array but so far I cant get it to work. If I use "fixed" data it populates but the array does not want to work.
What am I missing? Here is what I have worked on so far.

[
    {
        "id": "6ab62647.f16d38",
        "type": "debug",
        "z": "2fb934ba.21cfcc",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "false",
        "x": 800,
        "y": 2420,
        "wires": []
    },
    {
        "id": "db3049d.1ba8ab8",
        "type": "inject",
        "z": "2fb934ba.21cfcc",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "topic": "",
        "payload": "welcome",
        "payloadType": "str",
        "x": 170,
        "y": 2400,
        "wires": [
            [
                "e638db02.955bd8"
            ]
        ]
    },
    {
        "id": "e638db02.955bd8",
        "type": "ui_template",
        "z": "2fb934ba.21cfcc",
        "group": "6009bdbc.c559f4",
        "name": "testing payload",
        "order": 0,
        "width": "6",
        "height": "6",
        "format": "<h3>Testing dynamic scripts with Dashboard 2.0</h3>\n{{msg.payload}}\n<script>\n    (function(scope) {\n        console.log('Position 1');\n        console.dir(scope);\n        console.log(scope.msg);\n        scope.$watch('msg.payload', function(data) {\n            console.log('Position 2');\n            console.dir(data);\n        });\n    })(scope);\n</script>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": false,
        "templateScope": "local",
        "x": 560,
        "y": 2420,
        "wires": [
            [
                "6ab62647.f16d38"
            ]
        ]
    },
    {
        "id": "ea308e03.8c183",
        "type": "inject",
        "z": "2fb934ba.21cfcc",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "topic": "",
        "payload": "not welcome",
        "payloadType": "str",
        "x": 180,
        "y": 2440,
        "wires": [
            [
                "e638db02.955bd8"
            ]
        ]
    },
    {
        "id": "316716c9.4f17ba",
        "type": "inject",
        "z": "2fb934ba.21cfcc",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "show",
        "payload": "My Form",
        "payloadType": "str",
        "x": 160,
        "y": 2490,
        "wires": [
            [
                "c4309f7e.37a44"
            ]
        ]
    },
    {
        "id": "84b85db1.c276a",
        "type": "ui_template",
        "z": "2fb934ba.21cfcc",
        "group": "47e18a25.206644",
        "name": "PopUp 1",
        "order": 1,
        "width": 0,
        "height": 0,
        "format": "<div ng-init=\"init()\" id=\"popup_dialog_1\" class=\"dialog\">\n    \n    <div class=\"dialog_content\">\n        \n        <div class=\"dialog_header\">\n            <span ng-click=\"closeDialog()\" class=\"close\">&times;</span>\n            <h2 class=\"title\">{{payload.val3}}</h2>\n        </div>\n        \n        <div class=\"dialog_body\">\n\n            <div layout=\"column\" layout-align=\"center\" style=\"margin-top: 10px\">\n                <label for=\"name\">First Label : </label><input  id=\"1\"  ng-model=\"userInput1\" type=\"text\"   >\n                <label for=\"name\">Second Label : </label><input id=\"2\"  ng-model=\"userInput2\" type=\"text\"   >\n                <label for=\"name\">Third Label : </label><input  id=\"3\"  ng-model=\"userInput3\" type=\"text\"   >\n\t\t \n                 <div layout=\"row\" layout-align=\"center\">\n                    <div class=\"btn_box\">\n                        <md-button class=\"btn\" ng-click=\"confirm()\">\n                            <ng-md-icon icon=\"done\" style=\"color:#fff;\"></ng-md-icon> OK\n                        </md-button>\n                    </div>\n    \n                    <div class=\"btn_box\">\n                        <md-button class=\"btn\" ng-click=\"closeDialog()\">\n                            <ng-md-icon icon=\"close\" style=\"color:#fff;\"></ng-md-icon> Cancel\n                        </md-button>\n                    </div>\n                </div>\n            </div> \n          \n        </div> <!--dialog_body-->\n    </div> <!--dialog_content-->\n</div>  <!--dialog-->\n\n\n<style>\n\n/* The Dialog (background) */\n.dialog {\n    display: none; /* Hidden by default */\n    position: fixed; /* Stay in place */\n    z-index: 9999; /* Sit on top */\n    left: 0;\n    top: 0;\n    width: 100%; /* Full width */\n    height: 100%; /* Full height */\n    overflow: auto; /* Enable scroll if needed */\n    background-color: rgb(0,0,0); /* Fallback color */\n    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */\n    -webkit-transform: translateZ(0px);\n    -webkit-transform: translate3d(0,0,0);\n    -webkit-perspective: 1000;\n}\n\n.dialog_content {\n    position: absolute;\n    background-color: #fff;\n    left: calc(50% - 170px);\n    top: 30px;\n    border-radius: 10px;\n    padding: 0;\n    width: 340px;\n    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);\n    -webkit-animation-name: animatetop;\n    animation-name: animatetop;\n    animation-duration: 0.4s;\n}\nh2.title {\n    margin:10px;\n    font-size: 20px;\n}\n/* Media query for smartphones (to Fix?) */\n@media only screen and (min-device-width : 375px) and (max-device-width : 667px) { \n    .dialog_content {\n    margin-top: 5%;\n    margin-left: 5%;\n}\n}\n\n/* Add Animation */\n@-webkit-keyframes animatetop {\n    from {top: -300px; opacity: 0} \n    to {top: 0; opacity: 1}\n}\n\n@keyframes animatetop {\n    from {top: -300px; opacity: 0}\n    to {top: 0; opacity: 1}\n}\n\n/* Dialog Header */\n.dialog_header {\n    padding: 2px 16px;\n    background-color: #03A9F4;\n    border-radius: 10px 10px 0 0;\n    color: white;\n}\n\n/* Dialog Body */\n.dialog_body {padding: 5px;}\n\n/* The Close Button */\n.close {\n    color: #fff;\n    float: right;\n    font-size: 28px;\n    font-weight: bold;\n    cursor: pointer;\n}\n\n.close:hover,\n.close:focus {\n    color: #1565C0;\n    text-decoration: none;\n    cursor: pointer;\n}\n\n/* Number container */\n.btn_box{\n    margin: 5px;\n}\n\n/* Buttons style */\n.btn {\n    min-height: 40px;\n    min-width: 80px;\n    font-weight: bold;\n    margin: 0px 10px 10px 0px;\n    box-shadow: 4px 4px 6px 0 #dadada;\n    background-color: #29B6F6;\n    color: #fff;\n}\n\n.btn:not([disabled]):hover {\n    background-color: #03A9F4;\n}\n\n\n</style>\n\n<script>\n\n\n\n/**\n * Steve-Mcl 2020-03-30\n * Adapated from the excellent work by Daniel Lando, https://github.com/robertsLando\n * to be the basis of a user input popup form\n * Original licence below...\n * *********************************************************************************\n * pin_dialog.js\n * Node-Red UI template for Node-Red Dashboard. \n * Custom dialog that asks for a PIN to allow actions\n * Enjoy it :). \n * -- Daniel\n *\n *\n * @license The Unlicense, http://unlicense.org/\n * @version 0.2\n * @author  Daniel Lando, https://github.com/robertsLando\n * @updated 2019-03-18\n * @link    ----\n * **********************************************************************************\n *\n */\n\nvar dialog;\n\n/* ==== */\n(function(scope) {\n\n    \n    scope.init = function() {\n        scope.userInput = \"\";\n        //Hide the md-panel\n        $('#popup_dialog_1').parent().parent().css(\"display\", \"none\");\n        dialog = $('#popup_dialog_1').detach();\n    }\n    \n    scope.showDialog = function() {\n        dialog.appendTo(document.body); // better to add the body only when the numpad is displayed (seams to be removed automatically)\n        dialog.css(\"display\", \"block\");\n    }\n    \n    scope.closeDialog = function(){\n        scope.userInput = \"\";\n        scope.payload = \"\";\n        scope.topic = \"\";\n        dialog.css(\"display\", \"none\");\n    }\n    \n\n    scope.confirm = function() {\n        scope.send({topic: scope.payload.topic , cmd : \"send\" || scope.topic, userInput: {a:scope.userInput1,b:scope.userInput2,c:scope.userInput3} });\n        scope.closeDialog();\n    }\n\n    scope.$watch('msg', function(data) {\n        if(data && data.topic){\n            switch(data.topic){\n               case \"show\":\n                   if(scope.inited){\n                        scope.topic = data.topic;\n                        scope.payload = data.payload;\n                        scope.showDialog();\n                        document.getElementById('1').value = data.payload.val1;\n                        document.getElementById('2').value = 'Pauling'; \n                       \n                   }\n                   else\n                        scope.inited = true;\n                break;\n                case \"close\": \n                    scope.closeDialog(); \n                break;\n            }\n        }\n    }\n\t\n\t);\n\n\t\n})(scope);\n\n    scope.userInput1 = \"\";\n    scope.userInput2 = \"\";\n    scope.userInput3 = \"\";\n    scope.payload = \"\";\n    scope.topic = \"\";\n    scope.inited = false;\n\n\n</script>\n",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "x": 540,
        "y": 2490,
        "wires": [
            [
                "c0c5fd12.f0e72"
            ]
        ]
    },
    {
        "id": "c0c5fd12.f0e72",
        "type": "debug",
        "z": "2fb934ba.21cfcc",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 760,
        "y": 2490,
        "wires": []
    },
    {
        "id": "c4309f7e.37a44",
        "type": "function",
        "z": "2fb934ba.21cfcc",
        "name": "",
        "func": "msg.payload = {val1:\"Peter\",val2:\"Pauling\",val3:\"My Form\"}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 330,
        "y": 2490,
        "wires": [
            [
                "84b85db1.c276a"
            ]
        ]
    },
    {
        "id": "6009bdbc.c559f4",
        "type": "ui_group",
        "z": "",
        "name": "Group 2",
        "tab": "2911aeca.7b40d2",
        "order": 2,
        "disp": true,
        "width": "6"
    },
    {
        "id": "47e18a25.206644",
        "type": "ui_group",
        "z": "",
        "name": "rt",
        "tab": "2911aeca.7b40d2",
        "order": 3,
        "disp": false,
        "width": "1",
        "collapse": false
    },
    {
        "id": "2911aeca.7b40d2",
        "type": "ui_tab",
        "z": "2fb934ba.21cfcc",
        "name": "New Test",
        "icon": "dashboard"
    }
]

Could you post your template code separately? And maybe a picture of the flow? Saves us having to keep posting people's flows into Node-RED which gets a bit time consuming sometimes. :smiley:

Apologies , here is the code alone

<div ng-init="init()" id="popup_dialog_1" class="dialog">
    
    <div class="dialog_content">
        
        <div class="dialog_header">
            <span ng-click="closeDialog()" class="close">&times;</span>
            <h2 class="title">{{payload.val3}}</h2>
        </div>
        
        <div class="dialog_body">

            <div layout="column" layout-align="center" style="margin-top: 10px">
                <label for="name">First Label : </label><input  id="1"  ng-model="userInput1" type="text"   >
                <label for="name">Second Label : </label><input id="2"  ng-model="userInput2" type="text"   >
                <label for="name">Third Label : </label><input  id="3"  ng-model="userInput3" type="text"   >
		 
                 <div layout="row" layout-align="center">
                    <div class="btn_box">
                        <md-button class="btn" ng-click="confirm()">
                            <ng-md-icon icon="done" style="color:#fff;"></ng-md-icon> OK
                        </md-button>
                    </div>
    
                    <div class="btn_box">
                        <md-button class="btn" ng-click="closeDialog()">
                            <ng-md-icon icon="close" style="color:#fff;"></ng-md-icon> Cancel
                        </md-button>
                    </div>
                </div>
            </div> 
          
        </div> <!--dialog_body-->
    </div> <!--dialog_content-->
</div>  <!--dialog-->


<style>

/* The Dialog (background) */
.dialog {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 9999; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0,0,0); /* Fallback color */
    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
    -webkit-transform: translateZ(0px);
    -webkit-transform: translate3d(0,0,0);
    -webkit-perspective: 1000;
}

.dialog_content {
    position: absolute;
    background-color: #fff;
    left: calc(50% - 170px);
    top: 30px;
    border-radius: 10px;
    padding: 0;
    width: 340px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: animatetop;
    animation-name: animatetop;
    animation-duration: 0.4s;
}
h2.title {
    margin:10px;
    font-size: 20px;
}
/* Media query for smartphones (to Fix?) */
@media only screen and (min-device-width : 375px) and (max-device-width : 667px) { 
    .dialog_content {
    margin-top: 5%;
    margin-left: 5%;
}
}

/* Add Animation */
@-webkit-keyframes animatetop {
    from {top: -300px; opacity: 0} 
    to {top: 0; opacity: 1}
}

@keyframes animatetop {
    from {top: -300px; opacity: 0}
    to {top: 0; opacity: 1}
}

/* Dialog Header */
.dialog_header {
    padding: 2px 16px;
    background-color: #03A9F4;
    border-radius: 10px 10px 0 0;
    color: white;
}

/* Dialog Body */
.dialog_body {padding: 5px;}

/* The Close Button */
.close {
    color: #fff;
    float: right;
    font-size: 28px;
    font-weight: bold;
    cursor: pointer;
}

.close:hover,
.close:focus {
    color: #1565C0;
    text-decoration: none;
    cursor: pointer;
}

/* Number container */
.btn_box{
    margin: 5px;
}

/* Buttons style */
.btn {
    min-height: 40px;
    min-width: 80px;
    font-weight: bold;
    margin: 0px 10px 10px 0px;
    box-shadow: 4px 4px 6px 0 #dadada;
    background-color: #29B6F6;
    color: #fff;
}

.btn:not([disabled]):hover {
    background-color: #03A9F4;
}


</style>

<script>



/**
 * Steve-Mcl 2020-03-30
 * Adapated from the excellent work by Daniel Lando, https://github.com/robertsLando
 * to be the basis of a user input popup form
 * Original licence below...
 * *********************************************************************************
 * pin_dialog.js
 * Node-Red UI template for Node-Red Dashboard. 
 * Custom dialog that asks for a PIN to allow actions
 * Enjoy it :). 
 * -- Daniel
 *
 *
 * @license The Unlicense, http://unlicense.org/
 * @version 0.2
 * @author  Daniel Lando, https://github.com/robertsLando
 * @updated 2019-03-18
 * @link    ----
 * **********************************************************************************
 *
 */

var dialog;

/* ==== */
(function(scope) {

    
    scope.init = function() {
        scope.userInput = "";
        //Hide the md-panel
        $('#popup_dialog_1').parent().parent().css("display", "none");
        dialog = $('#popup_dialog_1').detach();
    }
    
    scope.showDialog = function() {
        dialog.appendTo(document.body); // better to add the body only when the numpad is displayed (seams to be removed automatically)
        dialog.css("display", "block");
    }
    
    scope.closeDialog = function(){
        scope.userInput = "";
        scope.payload = "";
        scope.topic = "";
        dialog.css("display", "none");
    }
    

    scope.confirm = function() {
        scope.send({topic: scope.payload.topic , cmd : "send" || scope.topic, userInput: {a:scope.userInput1,b:scope.userInput2,c:scope.userInput3} });
        scope.closeDialog();
    }

    scope.$watch('msg', function(data) {
        if(data && data.topic){
            switch(data.topic){
               case "show":
                   if(scope.inited){
                        scope.topic = data.topic;
                        scope.payload = data.payload;
                        scope.showDialog();
                        document.getElementById('1').value = data.payload.val1;
                        document.getElementById('2').value = 'Pauling'; 
                       
                   }
                   else
                        scope.inited = true;
                break;
                case "close": 
                    scope.closeDialog(); 
                break;
            }
        }
    }
	
	);

	
})(scope);

    scope.userInput1 = "";
    scope.userInput2 = "";
    scope.userInput3 = "";
    scope.payload = "";
    scope.topic = "";
    scope.inited = false;


</script>

Thanks.

Hmm, looks like you are using some code by @Steve-Mcl so tagging him, perhaps he can help?

I'm afraid I no longer use Angular and rarely use Dashboard and only for simple things.

Of topic but if I may ask what interface are you using most now?

As @TotallyInformation is the author of the uibuilder project I suspect he uses that :wink:

1 Like

As Dave says, I use uibuilder. :smiley:

But then I had done quite a bit of web design and development long before I looked at IoT and Node-RED. My first website being hand coded static HTML. My second was a custom CMS system I wrote myself using PHP. My 3rd was WordPress. My current main blog is a Hugo static site with a custom theme.

I still occasionally use Dashboard to quickly throw something out of course because it is so convenient. But often I find it almost as quick to throw something together with the help of VueJS and bootstrap-vue.

100% of what I know is self thought and I have not seen so many terms in such a short paragraph that I had to google to know what they are. Cool!

Back to topic : I will wait for @Steve-Mcl.

1 Like