Javascript: how to get calculate multiple input values in loop using javascript?

I am trying to calculate the the value of some input field in my django template using javascipt (onkeyup=(), the form is in a loop e.g {% for p in prediction %} {% endfor %}.

I have this simple line to grab the input values (NOTE: They are in a loop)

   let stake_amount_input = document.querySelector("#amount").value
   let shares_amount_input = document.querySelector("#shares").value

Based on the fact that i have all these function in a django loop, am i not supposed to get all the input fields values when i calculate the other objects in the loop.

Based on the fact that i have all these function in a django loop, am i not supposed to get all the odds when i console.log(odds)

{% for p in prediction.prediction_data.all %}
  <form action="#" method="POST">
     <input type="number" value="" name="amount" id="amount" class="shares" onkeyup="CalculateNewBalance()">
     <input type="number" value="" name="shares" id="shares" class="shares" onkeyup="CalculateNewBalance()">

    <script>
      function CalculateNewBalance(){
          let stake_amount_input = document.querySelector(".amount").value
          let shares_amount_input = document.querySelector(".shares").value
          let potential_win = document.querySelector(".potential-win")

          let potential_win_value = parseFloat(stake_amount_input) * parseInt(shares_amount_input)
          potential_win.innerHTML = "$" + potential_win_value
          
          // if the potential_win innerHTML shows Nan, then i want to change the innerHTML to $0.00, but this is not working too
         if (potential_win === isNan) {
             potential_win.innerHTML = "$0.00"
         }

                                                        
    </script>
    </form>
{% endfor %}

enter image description here enter image description here

You have to add unique name every time you loop. Variable names and Id's should be unique. For this you have to add counter or unique values. Check this answer for how to add counter.

{% for p in prediction.prediction_data.all %}
  
  <form action="#" method="POST">
     <input type="number" value="" name="amount" id="amount{{ forloop.counter }}" class="shares" onkeyup="CalculateNewBalance()">
     <input type="number" value="" name="shares" id="shares{{ forloop.counter }}" class="shares" onkeyup="CalculateNewBalance()">

    <script>
      function CalculateNewBalance(){
          let stake_amount_input{{ forloop.counter }} = document.querySelector(".amount{{ forloop.counter }}").value
          let shares_amount_input{{ forloop.counter }} = document.querySelector(".shares{{ forloop.counter }}").value
          let potential_win{{ forloop.counter }} = document.querySelector(".potential-win{{ forloop.counter }}")

          let potential_win_value{{ forloop.counter }} = parseFloat(stake_amount_input{{ forloop.counter }}) * parseInt(shares_amount_input{{ forloop.counter }})
          potential_win{{ forloop.counter }}.innerHTML = "$" + potential_win_value{{ forloop.counter }}
          
          // if the potential_win innerHTML shows Nan, then i want to change the innerHTML to $0.00, but this is not working too
         if (potential_win{{ forloop.counter }} === isNan) {
             potential_win{{ forloop.counter }}.innerHTML = "$0.00"
         }

                                                        
    </script>
    </form>
{% endfor %}

{{ forloop.counter }} returns a list of numbers from 1 to number, until for loop runs.

The This would make every id unique and every variable unique. For example, when the loop runs

for first time:

let potential_win1 = document.querySelector(".potential-win1").value

for second time:

let potential_win2 = document.querySelector(".potential-win2").value

and so on.

Instead of putting whole form & script inside loop just add input fields inside loop and then either set event on each element inside loop or add event listener programmatically. I'll show programmatic approch.

<form action="#" method="POST">
{% for p in prediction.prediction_data.all %}
     <input type="number" value="" name="amount" class="shares" onkeyup="CalculateNewBalance()">
     <input type="number" value="" name="shares" class="shares" onkeyup="CalculateNewBalance()">
{% endfor %}
</form>
 let inputs = document.querySelectorAll('input');
function CalculateNewBalance(e) {
    let target = e.target
    let potential_win_value;
    let potential_win;

    if (target.nextElementSibling.classList.contains('potential-win')) {
        potential_win = target.nextElementSibling
    } else {
        potential_win = target.nextElementSibling.nextElementSibling
    }

    if (target.nextElementSibling.classList.contains('shares')) {
        potential_win_value = parseFloat(target.nextElementSibling.value) * parseInt(target.value)
    } else {
        potential_win_value = parseFloat(target.previousElementSibling.value) * parseInt(target.value)
    }

    potential_win.innerHTML = "$" + potential_win_value

    if (potential_win.innerHTML == '$NaN') potential_win.innerHTML = '$0.00'
}

['input', 'change'].forEach(evt => {
    inputs.forEach(input => input.addEventListener(evt, CalculateNewBalance, false))
});

Here is working example

 let inputs = document.querySelectorAll('input');
        function CalculateNewBalance(e) {
            let target = e.target
            let potential_win_value;
            let potential_win;

            if (target.nextElementSibling.classList.contains('potential-win')) {
                potential_win = target.nextElementSibling
            } else {
                potential_win = target.nextElementSibling.nextElementSibling
            }

            if (target.nextElementSibling.classList.contains('shares')) {
                potential_win_value = parseFloat(target.nextElementSibling.value) * parseInt(target.value)
            } else {
                potential_win_value = parseFloat(target.previousElementSibling.value) * parseInt(target.value)
            }

            potential_win.innerHTML = "$" + potential_win_value

            if (potential_win.innerHTML == '$NaN') potential_win.innerHTML = '$0.00'
        }
        
        ['input','change'].forEach( evt => {
            inputs.forEach(input => input.addEventListener(evt, CalculateNewBalance, false))
        }
        );
<form action="#" method="POST">
        <input type="number" value="" name="amount" placeholder="amount" class="shares">
        <input type="number" value="" name="shares" placeholder="shares" class="shares">
        <span class="potential-win">$0.00</span><br />

        <input type="number" value="" name="amount" placeholder="amount" class="shares">
        <input type="number" value="" name="shares" placeholder="shares" class="shares">
        <span class="potential-win">$0.00</span><br />

        <input type="number" value="" name="amount" placeholder="amount" class="shares">
        <input type="number" value="" name="shares" placeholder="shares" class="shares">
        <span class="potential-win">$0.00</span><br />
    </form>

Note:

  1. If you're creating application which includes real transactions & calculations of amount you should not rely on client side calculation handle it on server side.
  2. Don't use ID inside loop it shold be unique
Back to Top