Dashboard 2.0 with multiple inputs stored and prefilled with and from context storage

Hello,

I'm looking to create sort of a configuration page with Dashboard 2.0.
This page should contain multiple text input nodes, a button to save the entered values and a table which displays the last changes made for each input (sort of a log).

My flow currently looks like this:

[{"id":"ab144c1b47805573","type":"ui-button","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Save","label":"Save","order":4,"width":"1","height":"1","emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"{}","payloadType":"global","topic":"save_button","topicType":"str","buttonColor":"","textColor":"","iconColor":"","x":770,"y":160,"wires":[["4441392ccf74dfce"]]},{"id":"39566cf71386f044","type":"ui-text-input","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Input_1","label":"Input_1","order":1,"width":"2","height":"1","topic":"input_1","topicType":"str","mode":"number","tooltip":"","delay":300,"passthru":true,"sendOnDelay":false,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"sendOnClear":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","x":780,"y":200,"wires":[["4441392ccf74dfce"]]},{"id":"4e0cf6449f1be04a","type":"ui-text-input","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Input_2","label":"Input_2","order":2,"width":"2","height":"1","topic":"input_2","topicType":"str","mode":"text","tooltip":"","delay":300,"passthru":true,"sendOnDelay":false,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"sendOnClear":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","x":780,"y":240,"wires":[["4441392ccf74dfce"]]},{"id":"21e7299682a26d77","type":"inject","z":"e97c3811a2016996","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":430,"y":140,"wires":[["aa019c43f81e650f"]]},{"id":"4441392ccf74dfce","type":"join","z":"e97c3811a2016996","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":true,"accumulate":true,"timeout":"","count":"1","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":970,"y":220,"wires":[["033651c71b59da29"]]},{"id":"033651c71b59da29","type":"switch","z":"e97c3811a2016996","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"save_button","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1010,"y":260,"wires":[["9aeb2934ba9d42de"]]},{"id":"fa29a859d522e80f","type":"function","z":"e97c3811a2016996","name":"prefill inputs","func":"//let jsonData = JSON.parse(msg.payload);\n//node.warn(jsonData);\nnode.warn(msg.payload);\nnode.warn(msg.payload.input_1);\nnode.warn(msg.payload.input_2);\nnode.warn(msg.payload.input_3);\n\n/*msg.payload = {\n    input_1: jsonData.input_1,\n    input_2: jsonData.input_2,\n    input_3: jsonData.input_3\n};*/\n\nreturn [\n    { payload: msg.payload.input_1 },\n    { payload: msg.payload.input_2 },\n    { payload: msg.payload.input_3 }\n];","outputs":3,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":240,"wires":[["39566cf71386f044"],["4e0cf6449f1be04a"],["947ae92045eb2e50"]],"outputLabels":["Input_1","Input_2","Input_3"]},{"id":"9aeb2934ba9d42de","type":"change","z":"e97c3811a2016996","name":"","rules":[{"t":"set","p":"#:(persistent)::configuration","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1230,"y":260,"wires":[[]]},{"id":"aa019c43f81e650f","type":"change","z":"e97c3811a2016996","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"#:(persistent)::configuration","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":180,"wires":[["fa29a859d522e80f"]]},{"id":"947ae92045eb2e50","type":"ui-text-input","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Input_3","label":"Input_3","order":3,"width":"2","height":"1","topic":"input_3","topicType":"str","mode":"text","tooltip":"","delay":300,"passthru":true,"sendOnDelay":false,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"sendOnClear":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","x":780,"y":280,"wires":[["4441392ccf74dfce"]]},{"id":"842e73ead28eb5a2","type":"ui-group","name":"My Group","page":"8f25a3ecd25384a8","width":"6","height":"1","order":1,"showTitle":false,"className":"","visible":"true","disabled":"false"},{"id":"8f25a3ecd25384a8","type":"ui-page","name":"Configration","ui":"48b78019ef2446aa","path":"/configuration","icon":"home","layout":"grid","theme":"cf0f3291020d08d9","order":5,"className":"","visible":"true","disabled":"false"},{"id":"48b78019ef2446aa","type":"ui-base","name":"My Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"showPageTitle":true,"navigationStyle":"icon","titleBarStyle":"default"},{"id":"cf0f3291020d08d9","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]

I set the msg.payload to the value of persistent global.configuration, which I want to use to store the values saved from the dashboard, and push the value for each input field to a corresponding output of the function node to load the stored values into the ui.
The save button sets a msg.topic as "save_button", which is used in the switch node to check if the button has been clicked. The change node afterwards should persist the changed values to the context store.

My problem is, that so far only the changed values are stored in the context. If I only update input_1 via the dashboard, then the context only stores the value for that input, essentially loosing the values for the other inputs.
What do I need to change in my flow to make it save all the values? Maybe my current flow is badly designed for that task to begin with (it is my first experience with node red)? I would be happy to know if there are things I could improve.

I'm also a bit lost on how to create a row in a table for each change made to a saved value of an input field. I want the table to look like this:


The logs should also be persisted.
How can I do this?

Thank you for your help!

Welcome to Node-RED (and the forums) @luftbumb

I can help with the following, quickly, the other stuff I'll need to dive into another time (or hopefully someone else can help):

Currently, any data you send to a ui-table overrides the whole table contents (we have plans to allow single row appending, but it's not in just yet). This means you'd need to have a log stored in the context store (flow or global) and then when you have changes, you can have a little flow that sets msg.payload to global.myLog (or whatever you choose) with a "change" node, to then send it to ui-table.

You can format these however you like, e..g each entry into your myLog variable could be:

{
    "timestamp": <timestamp>,
    "modified_input": "input_1",
    "old value": 1,
    "new value": 2
}

Thank you for your answer.
I think I have both things mostly figured out now.
Here's my flow:

[{"id":"ab144c1b47805573","type":"ui-button","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Save","label":"Save","order":4,"width":"1","height":"1","emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"{}","payloadType":"global","topic":"save_button","topicType":"str","buttonColor":"","textColor":"","iconColor":"","x":490,"y":120,"wires":[["2403f10afb7f2b45"]]},{"id":"39566cf71386f044","type":"ui-text-input","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Input_1","label":"Input_1","order":1,"width":"2","height":"1","topic":"input_1","topicType":"str","mode":"number","tooltip":"","delay":300,"passthru":true,"sendOnDelay":false,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"sendOnClear":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","x":500,"y":160,"wires":[["474895e1ba50ac74"]]},{"id":"4e0cf6449f1be04a","type":"ui-text-input","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Input_2","label":"Input_2","order":2,"width":"2","height":"1","topic":"input_2","topicType":"str","mode":"text","tooltip":"","delay":300,"passthru":true,"sendOnDelay":false,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"sendOnClear":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","x":500,"y":200,"wires":[["474895e1ba50ac74"]]},{"id":"21e7299682a26d77","type":"inject","z":"e97c3811a2016996","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":100,"wires":[["fa29a859d522e80f"]]},{"id":"947ae92045eb2e50","type":"ui-text-input","z":"e97c3811a2016996","group":"842e73ead28eb5a2","name":"Input_3","label":"Input_3","order":3,"width":"2","height":"1","topic":"input_3","topicType":"str","mode":"text","tooltip":"","delay":300,"passthru":true,"sendOnDelay":false,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"sendOnClear":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","x":500,"y":240,"wires":[["474895e1ba50ac74"]]},{"id":"e105df83e9bf86f4","type":"inject","z":"e97c3811a2016996","name":"read configuration_2","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":400,"wires":[["3581b866b3f64436"]]},{"id":"3581b866b3f64436","type":"change","z":"e97c3811a2016996","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"#:(persistent)::configuration_2","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":400,"wires":[["79f2e5899d702be3"]]},{"id":"79f2e5899d702be3","type":"debug","z":"e97c3811a2016996","name":"debug 582","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":400,"wires":[]},{"id":"3fea2f25ded2aa85","type":"inject","z":"e97c3811a2016996","name":"init configuration_\"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":360,"wires":[["e0ae4a0e033ff268"]]},{"id":"e0ae4a0e033ff268","type":"change","z":"e97c3811a2016996","name":"","rules":[{"t":"set","p":"#:(persistent)::configuration_2","pt":"global","to":"{\"input_1\":111,\"input_2\":222,\"input_3\":333}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":360,"wires":[[]]},{"id":"e09e5a28be27b827","type":"ui-table","z":"e97c3811a2016996","group":"b025a43f30db9ac8","name":"","label":"text","order":1,"width":0,"height":0,"maxrows":0,"passthru":false,"autocols":true,"showSearch":false,"selectionType":"none","columns":[],"x":1290,"y":240,"wires":[[]]},{"id":"708f38dc0e998edc","type":"join","z":"e97c3811a2016996","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":850,"y":200,"wires":[["47428b012a43a654"]]},{"id":"2403f10afb7f2b45","type":"change","z":"e97c3811a2016996","name":"msg.complete","rules":[{"t":"set","p":"complete","pt":"msg","to":"true","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":120,"wires":[["708f38dc0e998edc"]]},{"id":"47428b012a43a654","type":"function","z":"e97c3811a2016996","name":"store changed values in global.configuration","func":"let configuration_2 = global.get('configuration_2', 'persistent');\nconst configuration_log = global.get('configuration_log', 'persistent');\n\nfor (var input in msg.payload) {\n    if(configuration_2[input] !== undefined) {\n        if(configuration_2[input] != msg.payload[input]) {\n            configuration_log.unshift({\n                \"Time\": new Date().toLocaleString('de-DE'),\n                \"Modified input\": input,\n                \"Old value\": configuration_2[input],\n                \"New value\": msg.payload[input]\n            });\n        }\n\n        configuration_2[input] = Number(msg.payload[input]);\n    }\n}\nglobal.set('configuration_log', configuration_log, 'persistent');\nreturn {payload: configuration_log};","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":240,"wires":[["1af834b6d09409d8","e09e5a28be27b827"]]},{"id":"1af834b6d09409d8","type":"debug","z":"e97c3811a2016996","name":"debug 588","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":950,"y":280,"wires":[]},{"id":"978019ca4c9b036c","type":"inject","z":"e97c3811a2016996","name":"read configuration_log","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":500,"wires":[["f51a7b41e8f63306"]]},{"id":"f51a7b41e8f63306","type":"change","z":"e97c3811a2016996","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"#:(persistent)::configuration_log","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":500,"wires":[["30259f5456a7c2e3"]]},{"id":"30259f5456a7c2e3","type":"debug","z":"e97c3811a2016996","name":"debug 589","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":500,"wires":[]},{"id":"20e90b04c87b60d4","type":"inject","z":"e97c3811a2016996","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"#:(persistent)::configuration_log","payloadType":"global","x":1050,"y":120,"wires":[["e09e5a28be27b827"]]},{"id":"6e792704666d6a24","type":"inject","z":"e97c3811a2016996","name":"init configuration_log","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":460,"wires":[["ae262412bb931fa3"]]},{"id":"ae262412bb931fa3","type":"change","z":"e97c3811a2016996","name":"","rules":[{"t":"set","p":"#:(persistent)::configuration_log","pt":"global","to":"[]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":460,"wires":[[]]},{"id":"fa29a859d522e80f","type":"function","z":"e97c3811a2016996","name":"prefill inputs","func":"const configuration_2 = global.get('configuration_2', 'persistent');\nreturn [\n    { payload: configuration_2.input_1 },\n    { payload: configuration_2.input_2 },\n    { payload: configuration_2.input_3 }\n];","outputs":3,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":270,"y":200,"wires":[["39566cf71386f044"],["4e0cf6449f1be04a"],["947ae92045eb2e50"]],"outputLabels":["Input_1","Input_2","Input_3"]},{"id":"474895e1ba50ac74","type":"junction","z":"e97c3811a2016996","x":600,"y":200,"wires":[["708f38dc0e998edc"]]},{"id":"842e73ead28eb5a2","type":"ui-group","name":"My Group","page":"8f25a3ecd25384a8","width":"6","height":"1","order":1,"showTitle":false,"className":"","visible":"true","disabled":"false"},{"id":"b025a43f30db9ac8","type":"ui-group","name":"My Group","page":"8f25a3ecd25384a8","width":"12","height":"1","order":2,"showTitle":false,"className":"","visible":"true","disabled":"false"},{"id":"8f25a3ecd25384a8","type":"ui-page","name":"Configration","ui":"48b78019ef2446aa","path":"/configuration","icon":"home","layout":"grid","theme":"5075a7d8e4947586","order":3,"className":"","visible":"true","disabled":"false"},{"id":"48b78019ef2446aa","type":"ui-base","name":"My Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"showPageTitle":true,"navigationStyle":"default","titleBarStyle":"default"},{"id":"5075a7d8e4947586","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]

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