skip to Main Content

Html:

<div class="from">
    <select
        name=""
        class="droplistOptions"
    >
        <!--insert option element here-->
    </select>
</div>
<p class="to-seprator">To</p>
<div class="to">
    <select
        name=""
        class="droplistOptions"
    >
        <!--insert option element here also -->
    </select>
</div>

Javascript Code:

const droplists = document.querySelectorAll('.droplistOptions');
countryNames = ['usa', 'India', 'china', 'japan'];
countryNames.forEach((country) => {
    const optionElement = document.createElement('option');
    optionElement.value = country;
    optionElement.textContent = country;
    droplists.forEach((item) => item.append(optionElement));
});

In above Code I want to insert all countries names from countryNames array as option element inside the both select tag in html but when i am using append it only append the option element in last or 2nd select tag inside html and first select tag is empty there is no option element inserted inside first select tag.I don’t know what mistake I am doing.I want to understand why it’s working like this it should append optionElement at both place in select tag because droplists is nodelist array and forEach iterating each element so

3

Answers


  1. The optionsElement you create and then append to the 1st list, is then append (moved) to the 2nd list. Deep clone the element before appending it:

    const droplists = document.querySelectorAll(".droplistOptions");
    const countryNames = ['usa', 'India', 'china', 'japan']
    countryNames.forEach((country) => {
      const optionElement = document.createElement("option");
      optionElement.value = country;
      optionElement.textContent = country;
      droplists.forEach((item) => item.append(optionElement.cloneNode(true)));
    });
    <div class="from">
      <select name="" class="droplistOptions">
        <!--insert option element here-->
      </select>
    </div>
    <p class="to-seprator">To</p>
    <div class="to">
      <select name="" class="droplistOptions">
        <!--insert option element here also -->
      </select>
    </div>

    Or create a new element for each list:

    const droplists = document.querySelectorAll(".droplistOptions");
    const countryNames = ['usa', 'India', 'china', 'japan']
    countryNames.forEach((country) => {
      droplists.forEach((item) => {
        const optionElement = document.createElement("option");
        optionElement.value = country;
        optionElement.textContent = country;
        item.append(optionElement);
      });
    });
    <div class="from">
      <select name="" class="droplistOptions">
        <!--insert option element here-->
      </select>
    </div>
    <p class="to-seprator">To</p>
    <div class="to">
      <select name="" class="droplistOptions">
        <!--insert option element here also -->
      </select>
    </div>

    If you have a very long list, it might be better to create a fragment, attach all optionElement nodes to the fragment, and then append a clone of the fragment to the lists. In this way you’ll avoid making multiple consecutive changes to the DOM:

    const droplists = document.querySelectorAll(".droplistOptions");
    const countryNames = ['usa', 'India', 'china', 'japan']
    
    const fragment = new DocumentFragment();
    countryNames.forEach((country) => {
      const optionElement = document.createElement("option");
      optionElement.value = country;
      optionElement.textContent = country;
      
      fragment.append(optionElement);
    });
    
    droplists.forEach((item) => {
      item.append(fragment.cloneNode(true));
    });
    <div class="from">
      <select name="" class="droplistOptions">
        <!--insert option element here-->
      </select>
    </div>
    <p class="to-seprator">To</p>
    <div class="to">
      <select name="" class="droplistOptions">
        <!--insert option element here also -->
      </select>
    </div>
    Login or Signup to reply.
  2. You can’t insert same tag in different palces in DOM. It’s same element and when you call "append", it brings your option to first <select> and then replace it to second, inserting doen’t work as cloning.

    You need to create new <option> for each of yours lists:

    const droplists = document.querySelectorAll(".droplistOptions");
    countryNames = ['usa','India','china','japan']
    countryNames.forEach((country) => {
     droplists.forEach((item) => {
        const optionElement = document.createElement("option");
        optionElement.value = country;
        optionElement.textContent = country;
        item.append(optionElement));
     });
    });
    
    Login or Signup to reply.
  3. Because you only create one option element in your .forEach loop – you are moving the element from the first select element to the second with each call of .appends.

    There are many ways to go about this, but I like using innerHTML, even though you’ll lose syntax semantics in your editor. This will be far more performant as you avoid object operations and the garbage collector will not need to manage needless DOM-element objects.

    Also, consider utilising the more appropriate for...of loops in your code instead of the .forEach construct. .forEach really only exists to iterate over non-assigned arrays. Again, this will also have performance benefits as you will not need to store function objects and closures in memory created by the .forEach method.

    const droplists = document.querySelectorAll('.droplistOptions');
    const countryNames = ['usa', 'India', 'china', 'japan'];
    
    for (const country of countryNames) {
      for (const list of droplists) {
        item.innerHTML = `${list.innerHTML}<option value="${country}">${country}</option>`;
      }
    }
    <div class="from">
      <select name="" class="droplistOptions">
        <!--insert option element here-->
      </select>
    </div>
    <p class="to-seprator">To</p>
    <div class="to">
      <select name="" class="droplistOptions">
        <!--insert option element here also -->
      </select>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search