Search code examples
javascriptjqueryinnerhtml

JS multiplier takes the current innerHTML value instead of only the first one


I have a list of <p> tags generated from my PHP script. Each of them has a value, for example, "30" or "5" (<p>30</p>). I have a select list with some values. By selecting them you multiply the value of every <p> tag. The problem is when I multiply <p>10</p> by 2 I get 20. When I multiply it once more, this time by 3, I don't get 30, but 60. I know that js takes the value that is there in the <p> tag at the moment of executing the function, but I don't know how to make it take only the base (on page load) value.

function multiply() {
  $('.tags p').each(function() {
    let multiply_val = document.querySelector(".multiply_ing").value;
    let ing = parseFloat(this.innerHTML);
    this.innerHTML = ing * multiply_val;
  })
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="multiply">
  <select class="multiply_ing" onchange="multiply()">
    <option value="0.5">0.5x</option>
    <option value="1" selected>1x</option>
    <option value="2">2x</option>
    <option value="3">3x</option>
  </select>
</div>
<div class="tags">
  <p>10</p>
  <p>5</p>
  <p>2</p>
</div>


Solution

  • I suggest you use data-attributes.

    Also use external event handlers and make sure your class is present on the tag (you were missing ingredient)

    Also you can trigger the change, so it is the value of the select that initialises the content:

    $(function() {
      $(".multiply_ing").on("change", function() {
        let multiply_val = +this.value;
        $('.ingredient p').each(function() {
          let ing = +this.dataset.val;
          this.innerHTML = ing * multiply_val;
        });
      }).change(); // initialise
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <div class="multiply">
      <select class="multiply_ing">
        <option value="0.5">0.5x</option>
        <option value="1" selected>1x</option>
        <option value="2">2x</option>
        <option value="3">3x</option>
      </select>
    </div>
    <div class="tags ingredient">
      <p data-val="10"></p>
      <p data-val="5"></p>
      <p data-val="2"></p>
    </div>