EXAMPLE (template) - displaying a list using Radio buttons, returning the selection, reversing the selection

Problem: You have a list of items that you want to display and allow the user to select one and return that to the flow. In this case we will display a list of songs and show how to return the one picked. In addition, to show how to use a script in the template, we will show how to reverse the song name and return it.

Sample data:
It's been a Hard Day's Night
Help!
Rocky Raccoon

We will use a function node to create the table like this:
13%20AM

First, we will just display the table using this code in the template node:
08%20AM
The styling in the <li> is to remove the dot before each item since this is a list, and the styling in the <div> is to adjust the position of the list so it is under the title. The result is this:
28%20AM
To send the name of the song back to the flow as soon as it is checked, we add a ng-click to the <li> element so the template now looks like this:
51%20AM
and in the backend you can see the results in a debug node:
01%20AM
Now what if we wanted to use a button to send the data back (maybe you will have multiple options on the dashboard you want sent back at the same time. We will remove the ng-click from the <li>, add an ng-model to the <input> and add in an <md-button> so the template will now look like this:


and now the song name won't be sent until you press the button.
Flow so far:

[{"id":"d63cbb3f.4e214","type":"debug","z":"968ca76f.3dc46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":770,"y":320,"wires":[]},{"id":"e0f1a75d.a784c","type":"ui_template","z":"968ca76f.3dc46","group":"2659c0e4.6c014","name":"Display Song List","order":1,"width":"12","height":"6","format":"<div style=\"margin: 0 0 0 -40px;\">\n  <ul>\n    <li ng-repeat=\"song in msg.payload track by $index\" \n      style=\"list-style-type: none;\">\n        <label>\n            <input type=\"radio\" ng-model=\"$parent.song\" value=\"{{song}}\" name=\"data\" />{{song}}\n        </label>\n    </li>\n </ul>\n     <md-button ng-click=\"send({payload:song})\">\n        Click to send data to backend\n    </md-button>\n\n</div>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":450,"y":320,"wires":[["d63cbb3f.4e214"]]},{"id":"bcf8f068.90c7c8","type":"function","z":"968ca76f.3dc46","name":"build list (1)","func":"var arr =[\"It's been a Hard Day's Night\",\n        \"Help!\",\n        \"Rocky Raccoon\"];\nmsg.payload = arr;\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":320,"wires":[["e0f1a75d.a784c"]]},{"id":"1a27d443.646804","type":"inject","z":"968ca76f.3dc46","name":"Go","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"","x":90,"y":320,"wires":[["bcf8f068.90c7c8"]]},{"id":"2659c0e4.6c014","type":"ui_group","z":"","name":"Radio button list","tab":"f9ac9e91.20e588","order":3,"disp":true,"width":"12","collapse":false},{"id":"f9ac9e91.20e588","type":"ui_tab","z":"","name":"Table Examples","icon":"dashboard","order":1}]

But what if we want to do something with the data before returning it to the flow? (Like reversing the string?)

We need to change a couple things and add a <script>. First lets change the button so it will send the data to the script. We change the ng-click from
ng-click="send({payload:song})"
to
ng-click="send({payload:action(song)})"
and add in the script so the template now looks like this:


Now when you click the button, you send the song to this.scope.action and it is processed. (NOTE: my understanding of 'this.scope stuff is hazy at best, I just know this wrks. If you want more details you need to do some more research) and the string is reversed and returned to the flow. Here is what the result looks like when we choose It's been a Hard Day's Night:
08%20AM
Here is the flow with this example:

[{"id":"5502dcbe.937f0c","type":"debug","z":"968ca76f.3dc46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":770,"y":220,"wires":[]},{"id":"8a517f1b.afab4","type":"ui_template","z":"968ca76f.3dc46","group":"2659c0e4.6c014","name":"Reverse Song name","order":2,"width":"12","height":"6","format":"<script>\n    \nthis.scope.action = function(opt) {\n        var splitString = opt.split(\"\"); \n        var reverseArray = splitString.reverse();\n        var joinArray = reverseArray.join(\"\");\n        opt = joinArray;\n     return opt; }    \n</script>\n\n<div style=\"margin: 0 0 0 -40px;\">\n  <ul>\n    <li ng-repeat=\"song in msg.payload track by $index\" \n      style=\"list-style-type: none;\">\n        <label>\n            <input type=\"radio\" ng-model=\"$parent.song\" value=\"{{song}}\" name=\"data\" />{{song}}\n        </label>\n    </li>\n </ul>\n     <md-button ng-click=\"send({payload:action(song)})\">\n        Click to send data to backend\n    </md-button>\n\n</div>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":460,"y":220,"wires":[["5502dcbe.937f0c"]]},{"id":"ea2ab1c3.c4d2f","type":"function","z":"968ca76f.3dc46","name":"build list (1)","func":"var arr =[\"It's been a Hard Day's Night\",\n        \"Help!\",\n        \"Rocky Raccoon\"];\nmsg.payload = arr;\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":220,"wires":[["8a517f1b.afab4"]]},{"id":"e38f7ef2.da25a8","type":"inject","z":"968ca76f.3dc46","name":"Go","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"","x":90,"y":220,"wires":[["ea2ab1c3.c4d2f"]]},{"id":"2659c0e4.6c014","type":"ui_group","z":"","name":"Radio button list","tab":"f9ac9e91.20e588","order":3,"disp":true,"width":"12","collapse":false},{"id":"f9ac9e91.20e588","type":"ui_tab","z":"","name":"Table Examples","icon":"dashboard","order":1}]
2 Likes

@zenofmud. HI very late to this party but I have been reviewing your sample code and trying to adapt it to have an item set as the default radio button.
No matter what I try, it doesn't seem to want to play nice. Not being an Angular expert doesn't help but it must be a simple syntax issue but I am not seeing it.

What does you flow look like?

There is a nice dashboard node available you can also take a look. I use this from time to time:

Thanks Christian for the pointer. That looks good.

I am going to persevere for a while to see if I can resolve the radio button default.

It ended up not being as bad as I thought to create the radio list with a default preset value.
This works but may not be perfection for those who are Angular experts and there may be a cleaner method.

An initial Function node to create the array.

var c = false;
var f = false;
flow.get("tempunits","storeInFile") == "°C" ? c = true : f = true;
var arr =[{"unit":"°C","checked":c},
          {"unit":"°F","checked":f}];
msg.payload = arr;
return msg;

.
msg.payload then gets pushed into the Template node

<div style="margin: 0 0 0 -40px;">
  <ul>
     <li ng-repeat="tempunit in msg.payload track by $index" 
        style="list-style-type: none;"
        ng-click="send({payload:tempunit.unit})"
        >
        <label>
         <input type="radio"  name="data" ng-checked="tempunit.checked" />{{tempunit.unit}}
        </label>
     </li>
  </ul>
</div>

to create this with °C preset as the default value.
Capture

If any Angular experts out there know how to set the button centre colour that would be greatly appreciated. I want to try to get the radio button centre colour to be the Node Red default colour.