# Custom node with dynamic properties

**URL:** <https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844>\
**Category:** Developing Nodes\
**Created:** [13 November 2018 17:50 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844 "2018-11-13T17:50:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![PTS93](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pts93/32/3717_2.png) [@PTS93](https://discourse.nodered.org/u/PTS93)\
**Post date:** [13 November 2018 17:50 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/1 "2018-11-13T17:50:44Z")

</div>

I want to create a node with a very similar functionality as the switch node (as in user can dynamically add rules)  
Though I can't find any resources how the switch node actually accomplishes its dynamic properties.  
Currently I generate a few text inputs in a form-row whenever the user presses a button.

That works fine but when I click done and open the node properties again, everything is gone.  
How do I make that persistent and also don't loose whatever the user typed into my generated inputs?

I looked at the switch node source but can't really see what it does differently. Its quite a huge node which doesn't make it easy to read to begin with.

It doesn't seem to populate the property UI from context as far as I can see so I thought node-red might handle the persistence for me if the UI is setup in a specific way that I'm missing?

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [14 November 2018 07:40 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/3 "2018-11-14T07:40:56Z")

</div>

Hi,

Since you don't have shared your code, I will try to explain in short how the [switch node](https://github.com/node-red/node-red/blob/master/nodes/core/logic/10-switch.html) manages its rules on the config screen:

- When the node is **registered** in Node-RED, the 'rules' property is declared. This is an _array_ of rules, which gets one rule by default:

```auto
RED.nodes.registerType('switch', {
     ...
     defaults: {
         ...
         rules: {value:[{t:"eq", v:"", vt:"str"}]},
         ...
     },

```

- When the config screen is **opened** afterwards, all the rules in the array will be displayed on the screen:

```auto
oneditprepare: function() {
     ...
     for (var i=0;i<this.rules.length;i++) {
             var rule = this.rules[i];
             $("#node-input-rule-container").editableList('addItem',{r:rule,i:i});
         }
},

```

- When the config screen is **closed** (with the 'done' button), the rules on the config screen need to be copied to the rules array:

```auto
oneditsave: function() {
     var rules = $("#node-input-rule-container").editableList('items');
     var node = this;
     node.rules = [];
     rules.each(function(i) {
             ...
             node.rules.push(r);
     });
},

```

This way the '_ **rules** _' field always contains the correct rule set. So when the rules are not displayed, this means you don't show the rules array items on your screen OR you don't store the screen items in your rules array...

It is not easy to create such a node for the first time...

Good luck with it !  
Bart

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [14 November 2018 07:50 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/4 "2018-11-14T07:50:48Z")

</div>

Hmm, perhaps a short intro about the rule list widget in **html side** of the config screen:

- The **visual** widget is an editable list container, which needs to be declared like this:

```auto
 <div class="form-row node-input-rule-container-row">
     <ol id="node-input-rule-container"></ol>
 </div>

```

- In **oneditsave** (see code snippet in my first post) the `var rules` refers to that editable list, so you can loop through the editable list with `rules.each` (and copy the rules to `node.rules` i.e. to the rule array).
- In **oneditprepare** it works a similar way, but copying in the other direction.

---

<div class="post-metadata">

**Author:** ![PTS93](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pts93/32/3717_2.png) [@PTS93](https://discourse.nodered.org/u/PTS93)\
**Post date:** [14 November 2018 09:42 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/5 "2018-11-14T09:42:20Z")

</div>

Thank you, I managed to make it work.  
It wasnt obvious to me that you have to repopulate the list manually.

It also tripped me up that my array for saving the user values has to be present in the defaults object in order for nod-red to persistently store it and recognize changes after saving.

---

<div class="post-metadata">

**Author:** ![afelix](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/afelix/32/9743_2.png) [@afelix](https://discourse.nodered.org/u/afelix)\
**Post date:** [26 June 2019 14:56 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/7 "2019-06-26T14:56:47Z")

</div>

Just found this thread and thanks for the help, it does exactly what I'm looking for. For future people finding this thread, the location of the switch node source got changed to a different path. Here's the [new link for the html](https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/nodes/core/logic/10-switch.html) and [for the javascript file](https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/nodes/core/logic/10-switch.js). These aren't permalinks and refer to the master branch, but they're currently located in the `node-red` repository with the following path: `packages/node_modules/@node-red/nodes/core/logic/`

---

<div class="post-metadata">

**Author:** ![jake123](https://avatars.discourse-cdn.com/v4/letter/j/ac8455/32.png) [@jake123](https://discourse.nodered.org/u/jake123)\
**Post date:** [12 April 2021 08:20 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/8 "2021-04-12T08:20:25Z")

</div>

How would i make added li-s stay after i click done.

```auto
  const addToList = () => {
              let selectedItems = $("#node-input-options option:selected");
              selectedItems.each(function (i, el) {
                // console.log(el, i);
                let text = $(el).text();
                let val = $(el).val();
                var li = $("<li>").text(text).val(val).attr("title", val);
                list.append(li);
                li.on("dblclick", function () {
                  li.remove();
                });
             
              });
            };

```

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [12 April 2021 08:22 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/9 "2021-04-12T08:22:40Z")

</div>

@jake123 please do not cross-post. You already have your thread on this topic and people are actively trying to help.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [12 April 2021 08:22 UTC](https://discourse.nodered.org/t/custom-node-with-dynamic-properties/4844/10 "2021-04-12T08:22:49Z")

</div>


