# Dynamic drop-down list issue in node-red editor for custom node

**URL:** <https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474>\
**Category:** Developing Nodes\
**Created:** [21 September 2023 14:25 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474 "2023-09-21T14:25:47Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [21 September 2023 14:25 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/1 "2023-09-21T14:25:47Z")

</div>

Hello All,

I have created custom node in node-red editor in which i have two drop-down lists.

1. First drop down have 5 static items
2. Second drop down is dynamic which is filled based on item selected in first drop down.

**Issue:**

- I select an item from first drop down, it is showing correct items in second drop-down.
- Selection from second drop down is also fine.
- Just do save and exit the dialog box.

On again opening by double clikcing on my custom node, it is showing previously selected value for first drop-down correctly. But whatever item was selected on second drop-down is not persist. Even items are there in second drop down.

Is it expected behaviour in editor for dynamic drop down ?  
Any pointers on this..

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [21 September 2023 14:36 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/2 "2023-09-21T14:36:05Z")

</div>

This is a common area for confusion - your not alone.

What you can do is.

- Add the **oneditprepare** handler
- Trigger the change for your parent dropdown within that handler

```auto
$('#node-input-some-select-element').trigger('change')

```

I am sure I don't have this fully right, but should be close

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [21 September 2023 15:01 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/3 "2023-09-21T15:01:08Z")

</div>

Hello @marcus-j-davies ,  
Thanks for reply.

- I added oneditprepare and added code for trigger:

`$('#node-input-some-select-element').trigger('change')`

It is doing something which is not intended:  
First drop down has 4 items (a,b,c,d)  
I selected 'a'

based on this second drop down shows (10,20,30,40,50)

then I selected 'b' from first dropdown  
Now it is appeding (60,70,80,90) to existing items which were shown earlier..  
so, now second drop down shows (10,20,30,40,50,60,70,80,90)

It is not intended anyhow..

original issue still there which is :  
when I do select item from second drop down and save and close the dialog.

again opening it is not showing the item which was being selected in second drop down.

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [21 September 2023 15:49 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/4 "2023-09-21T15:49:50Z")

</div>

After you have triggered the change in the handler.

Try doing

`$('#node-input-second-select-element').val(this.mySecondValueID)`

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [21 September 2023 16:00 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/5 "2023-09-21T16:00:26Z")

</div>

If your second drop-down is growing rather than replacing, make sure that you empty the contents before changing them. Remember that a drop-down is an HTML `select` tag containing multiple `option` tags. So simply remove all of the `select` tag's children first.

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [22 September 2023 06:39 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/6 "2023-09-22T06:39:19Z")

</div>

Hello @TotallyInformation  
**Issue is not related to growing item in drop down..**

Drop down functionalities are working fine.. for selected item in first drop down it is showing items in second drop down.

**Issue** as I mentioned is when you select a item from first and second drop down and do save and close the edit dialog of node.

Then open again.. It is showing correct previously selected item in first drop down but for second dropdown it is not showing the previously selected item . Even second dropdown have all the items including previously selected one.

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [22 September 2023 07:16 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/7 "2023-09-22T07:16:37Z")

</div>

I think sharing your HTML file will help at this point.

````auto
```
HTML Here
```

````

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [22 September 2023 10:47 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/8 "2023-09-22T10:47:35Z")

</div>

Hello @marcus-j-davies ,

Following is the HTML:

```auto

<script type="text/html" data-template-name="meal">
    <div class="form-row">
        <label for="node-input-meal_type">Type of Meal</label>
        <select name="meal_type" id="node-input-meal_type" onchange="onmealtypechange();">
            <option value="sel" selected>Select</option>
            <option value="breakfast" selected>Brekfast</option>
            <option value="lunch">Lunch</option>
            <option value="dinner">Dinner</option>
        </select>
    </div>

    <div class="form-row">
        <label for="node-input-meal">Select item</label>
        <select name="meal" id="node-input-meal" onchange="onmealitemchange();">
        </select>
    </div>
</script>

<script type="text/html" data-help-name="meal">
    <p>A node which represents meals</p>
</script>

```

listeners:

```auto
<script type="text/javascript">
    function onmealtypechange() {
        var sel = document.getElementById("node-input-meal_type");
        var drop = document.getElementById("node-input-meal");
        console.log("## meal items size (on type change): " + drop.length);
        drop.innerHTML="";

        console.log("## selected meal type: " + sel.value);

        if(sel.value == 'breakfast') {
            var opt1 = document.createElement('option');
            opt1.value = "";
            opt1.innerHTML = "Select";
            opt1.selected = true;
            drop.appendChild(opt1);

            var opt2 = document.createElement('option');
            opt2.value = 'tea';
            opt2.innerHTML = 'tea';
            drop.appendChild(opt2);

            var opt3 = document.createElement('option');
            opt3.value = 'milk';
            opt3.innerHTML = 'milk';
            drop.appendChild(opt3);
        } else if(sel.value == 'lunch') {

        } else if(sel.value == 'dinner') {

        }
    }

    function onmealitemchange() {

    }
</script>

```

Plugin:

```auto
<script type="text/javascript">
    RED.nodes.registerType('meal',{
        category: 'function',
        color: '#a6bbcf',
        defaults: {
            meal_type: {value: "sel"},
            meal: {value: ""}
        },
        inputs:0,
        outputs:1,
        icon: "",
        label: function() {
            return this.name||"Meal";
        },
        oneditprepare : function() {

            console.log("## on edit prepare meal_type: " + this.meal_type);
            console.log("## on edit prepare meal: " + this.meal);

            var meal_list = document.getElementById("node-input-meal_type");
            console.log("## Meal type size: " + meal_list.length);

            var meal = document.getElementById("node-input-meal");
            console.log("## meal items size: " + meal.length);
        },
        oneditsave : function(){

        }
    });
</script>

```

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [22 September 2023 10:53 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/9 "2023-09-22T10:53:37Z")

</div>

**To reprodcue issue:**

1. drag meal node to editor.
2. double click on meal node to edit -\> select meal type (breakfast) -\> select meal (tea or milk) -\> done
3. double click on meal node to edit

expected to show the meal\_type = breakfast and meal = tea or milk (whichever is choosen in step 2)  
now working as expected.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [22 September 2023 12:25 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/10 "2023-09-22T12:25:58Z")

</div>

Not spotted a specific problem yet but a couple of things to tidy up maybe.

First, you have 2 items selected in the meal type?

Second, you are using raw DOM when you have access to jQuery. Not necessarily an issue but jQuery smooths out some of the DOM's oddities and can reduce the amount of code required.

Something else to remember - don't think it will impact the code you've shared but can catch you out. While the custom node's html file looks like a web page, it is NOT. It is a page fragment that is included along with other fragments. That means that your exposed JavaScript code is just that, exposed to the page global. Personally, I wrap all of my Editor code in an IIFE to prevent issues.

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [22 September 2023 12:35 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/11 "2023-09-22T12:35:19Z")

</div>

First, you have 2 items selected in the meal type?

=\> I have corrected it ..

```auto
 <option value="sel" selected>Select</option>
 <option value="breakfast" selected>Brekfast</option>

```

===========================================

```auto
 <option value="sel" selected>Select</option>
<option value="breakfast" >Brekfast</option>

```

But it didn't have side effect.. 🙂

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [22 September 2023 13:34 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/12 "2023-09-22T13:34:13Z")

</div>

One observation is whenever I just open edit dialogue of my meal node by double clicking.  
It always call **onmealtypechange()**

But in that:  
`console.log("## meal items size (on type change): " + drop.length);`

It always prints zero size, which is weird because:

1. First time open meal node edit dialogue, it will print length as zero (It is Fine)
2. Select menu type: breakfast, meal: tea .. save and exit dialogue
3. Second time Open edit meal node edit dialogue. **`but now also it is printing length as zero`**. It should print 3.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [22 September 2023 22:09 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/13 "2023-09-22T22:09:22Z")

</div>

> [@Pioneerj](#):
>
> One observation is whenever I just open edit dialogue of my meal node by double clicking.  
> It always call **onmealtypechange()**

Yes, because opening it is where it is CREATED in the DOM. It doesn't exist until then. So the onchange is triggered because it is changing (setting the initial value).

> [@Pioneerj](#):
>
> It always prints zero size

I _think_ that is a timing issue.

* * *

You should note that I never use `onchange` in the html script. I only ever create a listener in the oneditprepare function. That function is executed once when the Editor is loaded and again whenever the panel is opened.

So use something like this in your oneditprepare function

```auto
$('#node-input-meal_type').on('change', function() {
    // NOTE that inside here, `this` refers to the selected DOM element 
    // and `$(this)` gives you a jQuerified version of the selected element.
    console.log(..)
})

```

You may also need to take the `selected` off completely. The first entry will be pre-selected anyway but I am not sure whether the Editor's panel handling will restore the saved value. Been a while since I did this I'm afraid. If it doesn't, you will also have to set the value in oneditprepare.

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [25 September 2023 06:30 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/14 "2023-09-25T06:30:49Z")

</div>

There is no difference on putting on change in oneditprepare:

```auto

            $('#node-input-meal_type').on('change', function() {
                // NOTE that inside here, `this` refers to the selected DOM element 
                // and `$(this)` gives you a jQuerified version of the selected element.
                var sel = document.getElementById("node-input-meal_type");
                var drop = document.getElementById("node-input-meal");
                console.log("## meal items size (on type change): " + drop.length);
                drop.innerHTML="";

                console.log("## selected meal type(edit prepare): " + sel.value);

                if(sel.value == 'breakfast') {
                    var opt1 = document.createElement('option');
                    opt1.value = "";
                    opt1.innerHTML = "Select";
                    opt1.selected = true;
                    drop.appendChild(opt1);

                    var opt2 = document.createElement('option');
                    opt2.value = 'tea';
                    opt2.innerHTML = 'tea';
                    drop.appendChild(opt2);

                    var opt3 = document.createElement('option');
                    opt3.value = 'milk';
                    opt3.innerHTML = 'milk';
                    drop.appendChild(opt3);
                }

            });

```

Result is same. Selected value is not persistent.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [25 September 2023 11:14 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/15 "2023-09-25T11:14:22Z")

</div>

OK, was worth trying anyway. Timing edge-cases can be tricky.

```auto
var sel = document.getElementById("node-input-meal_type");

```

Firstly, best to use `const` or `let` since `var` gets hoisted and can be confusing.

Secondly, I think it would be better as:

```auto
const mealType = $(this).value
const drop = $("#node-input-meal");

```

Then simply replace `sel.value` as MealType. Feels cleaner that way.

You can also simplify your append code:

```auto
drop.append('<option value="" select>Select an option</option>')
drop.append('<option value="tea" select>Tea</option>')
...

```

Your way works of course but, to me at least, the other way is clearer.

Oh, and this:

```auto
 drop.innerHTML="";

```

could be this if you've used the jQuery above:

```auto
drop.empty();

```

Though not sure it really makes a difference.

But none of that makes it clear why you are getting your problem. Do you have your node in GitHub? If so, can I install it on my dev instance?

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [26 September 2023 11:08 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/16 "2023-09-26T11:08:02Z")

</div>

package.json

```auto
{
  "name": "node-red-meal-node",
  "version": "1.0.0",
  "description": "meal node implementation",
  "main": "meal-node.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "pioneerj",
  "license": "ISC",
  "node-red": {
    "nodes": {
      "meal-node": "meal-node.js"
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [26 September 2023 11:08 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/17 "2023-09-26T11:08:51Z")

</div>

meal-node.js

```auto

module.exports = function(RED) {
    function mealNode(config) {
        RED.nodes.createNode(this, config);
        
        var node = this;
        var msg = {};

        msg.payload = {
            "monitor_type" : "test"
        };

        setImmediate(() => {
            node.log(JSON.stringify(msg));
            node.send(msg);
            node.log("monitor : sent message from " + msg.node_name);
        });
    }

    RED.nodes.registerType("meal", mealNode);
}

```

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [26 September 2023 12:38 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/18 "2023-09-26T12:38:30Z")

</div>

Github repo link:

> **[GitHub - pioneerj-s/node-red-meal-node](https://github.com/pioneerj-s/node-red-meal-node)**
>
> Contribute to pioneerj-s/node-red-meal-node development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [26 September 2023 20:01 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/19 "2023-09-26T20:01:06Z")

</div>

Try this:

```auto
        oneditprepare : function() {
            console.log("## on edit prepare");			
			
            $('#node-input-meal_type').on('change', function() {
                const mealType = $('#node-input-meal_type').val()
                console.log(`🍴## meal type changed: "${mealType}"`)

                const meal = $("#node-input-meal")

                meal.empty()
                meal.append('<option value="" select>Select an option</option>')

                switch (mealType) {
                    case 'breakfast': {
                        meal.append('<option value="tea">Tea</option>')
                        meal.append('<option value="milk">Milk</option>')
                        break
                    }
                
                    case 'lunch': {
                        meal.append('<option value="ham sandwich">Ham Sandwitch</option>')
                        meal.append('<option value="cheese sandwich">Cheese Sandwitch</option>')
                        break
                    }
                
                    case 'tea': {
                        meal.append('<option value="burger">Burger</option>')
                        meal.append('<option value="steak">Steak</option>')
                        break
                    }
                
                    default: {
                        break
                    }
                }
            })

            $('#node-input-meal').on('change', function() {
                const meal = $('#node-input-meal_type').val()
                console.log(`🍴## meal changed: "${meal}"`)
            })
        },

```

Less effort to write, a lot easier to read and not mixing jQuery/DOM which results in weird errors.

---

<div class="post-metadata">

**Author:** ![Pioneerj](https://avatars.discourse-cdn.com/v4/letter/p/6bbea6/32.png) [@Pioneerj](https://discourse.nodered.org/u/Pioneerj)\
**Post date:** [27 September 2023 07:43 UTC](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474/20 "2023-09-27T07:43:27Z")

</div>

Clean code is good practice.. But it is not helping to solve issue. I tried with your changes as well..  
But still original issue is there.

Steps are simple to reproduce:

- Install [GitHub - pioneerj-s/node-red-meal-node](https://github.com/pioneerj-s/node-red-meal-node) plugin

- Drag meal node to editor.

- Double click on meal node to edit it

- Select meal type: breakfast

- Select meal: milk

- Click done

- again Double click on meal node to edit.

- You can see following on meal node  
- meal type: breakfast  
**- meal: it should show milk which we selected previously but it is not showing.**

Hope you are able to reprodcue original issue.

[Next page](https://discourse.nodered.org/t/dynamic-drop-down-list-issue-in-node-red-editor-for-custom-node/81474.md?page=2)
