user15950620
user15950620

Reputation: 3

Javascript - trying to copy an array whtout loosing refrence

I have a select element (delivery time) that needs to update when changing another select element (delivey say). In my HTML/PHP i ha three hidden select hours elements for each day option. in this javascript I have an event listener for change in delivery day.

Array.prototype.push.apply(t, t3); copies the element but deletes t3 (so if a user rechooses the day it's empty.

t = [...t3]; Copies the element without deleting t3 but cuts the refrence to document.getElementById("shipping_time").options so i get an empty selector

//update hours
jQuery(document).ready(function($){
  const selectElement = document.querySelector('#shipping_day');

  selectElement.addEventListener('change', (event) => {
    var selectedday = document.getElementById("shipping_day");
    var t = document.getElementById("shipping_time").options;
    var t1 = document.getElementById("shipping_time1").options;
    var t2 = document.getElementById("shipping_time2").options;
    var t3 = document.getElementById("shipping_time3").options;
    var i;

    if(selectedday.options.selectedIndex==0){
      t.options=0;
      Array.prototype.push.apply(t, t1);
    }
    if(selectedday.options.selectedIndex==1){
      t.length=0;
      Array.prototype.push.apply(t, t2);
    }
    if(selectedday.options.selectedIndex==2){

      t.length=0;
      //Array.prototype.push.apply(t, t3);
      //t = [...t3];

    }

  console.log(t);
  console.log(t1);
  console.log(t2);
  console.log(t3);
  console.log(document.getElementById("shipping_time"));

  });
});```

Upvotes: 0

Views: 53

Answers (1)

Guerric P
Guerric P

Reputation: 31805

Your problem is that a DOM node cannot be in two places at the same time, so you're actually moving them. If you absolutely need to use hidden fields as source for your select options, then you have to clone the options in order to copy them somewhere else in the DOM:

Array.from(t1).map(x => x.cloneNode(true)).forEach(x => t.add(x));

Here is a working demo:

const [mainSelect, abcSelect, defSelect, firstButton, secondButton] = ['main-select', 'abc-select', 'def-select', 'first-button', 'second-button'].map(document.getElementById.bind(document));

firstButton.addEventListener('click', () => {
  Array.from(abcSelect.options).map(x => x.cloneNode(true)).forEach(x => mainSelect.options.add(x));
});
secondButton.addEventListener('click', () => {
  Array.from(defSelect.options).map(x => x.cloneNode(true)).forEach(x => mainSelect.options.add(x));
});
.hidden {
  display: none;
}
<select id="main-select">
</select>

<select id="abc-select" class="hidden">
  <option>a</option>
  <option>b</option>
  <option>c</option>
</select>

<select id="def-select" class="hidden">
  <option>d</option>
  <option>e</option>
  <option>f</option>
</select>

<button id="first-button">Add abc</button>
<button id="second-button">Add def</button>

Upvotes: 1

Related Questions