Search code examples
javascriptdropdown

Update selected value in dropdown list depending on other lists selected values


i'm trying to figure out how can i make dynamic selection of values in few dropdown lists using Vanilla JS. I have 3 dropdown lists with same values. Each of them should have different value selected at the same time (duplicates not allowed). So once user changes another value in one list, value of another list should be updated accordingly. Basically, i need to swap their numbers in such case. But i can't complete the task as I'm quite new to JS and overall in programming. I tried following:

// defining initial values
var startPoint = document.querySelectorAll("select");

// function to recalculate value of each list on change
function calculateNewValues() {
  var changes = new Array();
  // getting updated values from lists as an array
  var updatedValues = document.querySelectorAll("select");
  // looping through array
  for (let i = 0; i < updatedValues.length; i++) {
    // if in updated array value of current index isn't equal to value
    // of index in initial array
    if (updatedValues[i].value != startPoint[i].value) {
      // creating variable changes for tracking
      changes[i] = updatedValues[i].value;
    }
    // if var changes has been defined (i.e. value of any list was updated)
    if (changes.length > 0) {
      // finding index of initial array with same value
      var key = startPoint.findIndex(changes[i]);
      // setting value of found index to previously stored value in updated list
      updatedValues[key].value = startPoint[i].value;
    }
  }

  updatedValues.forEach(element => {
    console.log(element.value);
  });
}
// event listeners for change of every dropdown list
const lists = document.querySelectorAll("select");
for (k = 0; k < lists.length; k++) {
  lists[k].addEventListener("change", calculateNewValues, false);
}
<p>
  <select name="list1" id="list1">
    <option value="1" id="list1option1" selected>1</option>
    <option value="2" id="list1option2">2</option>
    <option value="3" id="list1option3">3</option>
  </select>
</p>
<p>
  <select name="list2" id="list2">
    <option value="1" id="list2option1">1</option>
    <option value="2" id="list2option2" selected>2</option>
    <option value="3" id="list2option3">3</option>
  </select>
</p>
<p>
  <select name="list3" id="list3">
    <option value="1" id="list3option1">1</option>
    <option value="2" id="list3option2">2</option>
    <option value="3" id="list3option3" selected>3</option>
  </select>
</p>

i am probably doing some mistake when it comes to if (changes.length > 0) { but i can't understand how i can make this part better.

Thanks a lot in advance.


Solution

  • You have assigned startPoint to querySelectorAll. Which will hold exact same objects whenever you write same querySelectorAll. So in your case startPoint and updatedValues will always same.

    1. I have definen startPoint as an array of values and set its values in setStartingPointValues().
    2. Added target as current list which is being updated.
    3. Updated if (target.id == updatedValues[i].id && updatedValues[i].value != startPoint[i]) and retrieved target's old value.
    4. var key = startPoint.findIndex(x => x == target.value); will find select with value similar to new value. If we found key != -1, then update that select with oldValue.
    5. Call setStartingPointValues() at end of change event.

    // defining initial values
    var startPoint = [];
    
    // store values for all select.
    function setStartingPointValues() {
      startPoint = [];
      document.querySelectorAll("select").forEach(x => startPoint.push(x.value));
    }
    
    setStartingPointValues();
    
    // function to recalculate value of each list on change
    function calculateNewValues() {
      let target = this;
      let oldValue = 0;
      // getting updated values from lists as an array
      var updatedValues = document.querySelectorAll("select");
      // looping through array
      for (let i = 0; i < updatedValues.length; i++) {
        // if in updated array value of current index isn't equal to value    
        // of index in initial array    
        if (target.id == updatedValues[i].id && updatedValues[i].value != startPoint[i]) {
          // creating variable changes for tracking
          // changes[i] = updatedValues[i].value;
          oldValue = startPoint[i];
        }
        // if var changes has been defined (i.e. value of any list was updated)
    
        // finding index of initial array with same value
        var key = startPoint.findIndex(x => x == target.value);
        // setting value of found index to previously stored value in updated list
        if (key !== -1)
          updatedValues[key].value = oldValue;
    
      }
    
      setStartingPointValues();
    }
    // event listeners for change of every dropdown list
    const lists = document.querySelectorAll("select");
    for (k = 0; k < lists.length; k++) {
      lists[k].addEventListener("change", calculateNewValues, false);
    }
    <p>
      <select name="list1" id="list1">
        <option value="1" id="list1option1" selected>1</option>
        <option value="2" id="list1option2">2</option>
        <option value="3" id="list1option3">3</option>
      </select>
    </p>
    <p>
      <select name="list2" id="list2">
        <option value="1" id="list2option1">1</option>
        <option value="2" id="list2option2" selected>2</option>
        <option value="3" id="list2option3">3</option>
      </select>
    </p>
    <p>
      <select name="list3" id="list3">
        <option value="1" id="list3option1">1</option>
        <option value="2" id="list3option2">2</option>
        <option value="3" id="list3option3" selected>3</option>
      </select>
    </p>