Я думал, что решил этот цикл javascript «для», чтобы суммировать числовые варианты выбора нескольких полей в число, каждый раз, когда одно из них изменяется.

Но изменение выбора в любом из выбранных полей - это добавление номера снова вместо замены исходного номера выбора - это то, что я хочу.

Пример: пользователь выбирает из 3 полей следующие значения: +15, -5, +1. Всего должно быть "11"

Если пользователь изменяет свой первый выбор на +10 вместо # + 15, общее значение должно быть «6». Вместо этого он ДОБАВЛЯЕТ измененный номер ко всему. Таким образом, число становится «21» - не то, что я хочу.

Примечание: я хочу увеличивать число постепенно с каждым выбором выбора - НЕ итого всех, когда пользователь закончил с полями

Вот что у меня есть:

<form action="/cgi-bin/dropdown.cgi" method="post">
 <select class="select0 selectables" id="dropdown-0" name="dropdown0">        
 <option disabled="disabled" selected="selected" value="">select</option>    
 <option value="10">Choice 1 (+10)</option>
 <option value="-5">Choice 2 (-5)</option>
 <option value="60">Choice 3 (+60)</option> 
</select>
<br />
<select class="select1 selectables" id="dropdown-1" name="dropdown1">    
<option disabled="disabled" selected="selected" value="">select</option>
<option value="8">Choice A (+8)</option>
<option value="-10">Choice B (-10)</option>
<option value="15">Choice C (+15)</option> 
</select>
<br />
<select class="select2 selectables" id="dropdown-2" name="dropdown2">    
<option disabled="disabled" selected="selected" value="">select</option>
<option value="5">Choice ii (+5)</option>
<option value="15">Choice ii (+15)</option>
    <option value="12">Choice iii (+12)</option> 
    </select>
 </form>

  <div id="tally" style="">0</div>
  <script>
  var sum = 0; 

  document.addEventListener("DOMContentLoaded", function(event) {
    var gg1 = new JustGage({
      id: "gg1",
      value: 0,
      textRenderer: customValue
    });

    var userSelection = document.getElementsByClassName('selectables');
    for(let i = 0; i < userSelection.length; i++) {
      userSelection[i].addEventListener("change", function() {
        fieldvalue = userSelection[i].value;
        fieldname = userSelection[i].id;

        if (fieldvalue > 0) {
          // using += breaks other scripts for some reason
          sum = sum + parseInt(fieldvalue);
        } else if (fieldvalue < 1) {
          fieldvalue = fieldvalue * -1;
          sum = sum - parseFloat(fieldvalue, 10);
        }
        document.getElementById("tally").innerHTML = sum; 
        // this is the value that takes the number I'm trying to increment based on choices in selects 
        gg1.refresh(sum);
        return false;
      })
    }

  });
  </script>
-1
turpentyne 1 Май 2019 в 01:54

3 ответа

Лучший ответ

Это происходит потому, что внутри функции обратного вызова слушателя изменений вы не учитываете значения других выпадающих списков. Возьмите их, используя второй цикл for, и пересчитайте сумму.

Вот ваша модифицированная функция обратного вызова:

for (let i = 0; i < userSelection.length; i++) {
  userSelection[i].addEventListener("change", function() {
    sum = 0;
    for (var b = 0; b < userSelection.length; b++) {
      fieldvalue = userSelection[b].value;
      if (fieldvalue > 0) {
        // using += breaks other scripts for some reason
        sum = sum + parseInt(fieldvalue);
      } else if (fieldvalue < 1) {
        fieldvalue = fieldvalue * -1;
        sum = sum - parseFloat(fieldvalue, 10);
      }
    }
    document.getElementById("tally").innerHTML = sum;
    // this is the value that takes the number I'm trying to increment based on choices in selects 
    gg1.refresh(sum);
    return false;
  })
}
0
obscure 30 Апр 2019 в 23:09

Как уже упоминалось, вам нужно пересчитывать итоговое значение каждый раз, когда изменяется любое из выбранных контрольных значений. Вот демо (не оптимизировано):

document.querySelectorAll('select').forEach(select => select.addEventListener('change', (event) => {
  if (allValid()) {
    document.querySelector('#tally').innerHTML = calcTotal();
  }
}))


const allValid = () => {
  let status = true;
  document.querySelectorAll('select').forEach(select => {
    if (select.selectedIndex === 0) status = false;
  })
  return status;
}

const calcTotal = () => {
  let total = 0;
  document.querySelectorAll('select').forEach(select => {
    total += parseInt(select.value);
  })
  return total;
}
<select class="select0 selectables" id="dropdown-0" name="dropdown0">
  <option disabled="disabled" selected="selected" value="">select</option>
  <option value="10">Choice 1 (+10)</option>
  <option value="-5">Choice 2 (-5)</option>
  <option value="60">Choice 3 (+60)</option>
</select>
<br />
<select class="select1 selectables" id="dropdown-1" name="dropdown1">
  <option disabled="disabled" selected="selected" value="">select</option>
  <option value="8">Choice A (+8)</option>
  <option value="-10">Choice B (-10)</option>
  <option value="15">Choice C (+15)</option>
</select>
<br />
<select class="select2 selectables" id="dropdown-2" name="dropdown2">
  <option disabled="disabled" selected="selected" value="">select</option>
  <option value="5">Choice ii (+5)</option>
  <option value="15">Choice ii (+15)</option>
  <option value="12">Choice iii (+12)</option>
</select>

<div id="tally" style="">0</div>
0
Vikram Deshmukh 1 Май 2019 в 00:25

Всякий раз, когда любое из выбранных значений изменяется, вы должны пересчитать всю сумму. Что-то вроде этого:

  onload = function {

    var userSelection = document.getElementsByClassName('selectables');
    for(let i = 0; i < userSelection.length; i++) {
      userSelection[i].addEventListener("change", function() {
        var sum= computeSum();
        //whatever you want to do with sum
      })
    }

    function computeSum() {
      var sum = 0;
      for(const select in userSelection) {
        sum += select.value;
      }
      return sum;
    }

  }
0
Anis R. 30 Апр 2019 в 23:07