Price calculation with javascript for my data in the loop coming from the database

Viewed 41

I want the prices of the data coming from my database to be displayed on the screen with Javascript. I wrote a code like this but it only works this way. I may have more than one data from the database. For example, more than one title may come instead of gb or screen. I'm trying to loop for this but I couldn't. Could you help?

const values = {
  gb: null,
  display: null,
}

function PriceCalculator(label, newPrice) {
  values[label] = newPrice;
  if(values.gb != null && values.display != null){
    var total = values.gb + values.display;
    var result =  Number(total).toLocaleString("pt-BR",{minimumFractionDigits: 2, maximumFractionDigits: 2});
    document.getElementById("money").innerHTML=result;
  }    
}
<div id="form_step_1">
<div class="container">
<div class="row">
<div class="talepler mb-3">
  <h4>GB</h4>
  <div class="row mb-3" style="display: inline-block">
      <div class="col-sm-3 col-md-4 col-lg-3">
        <input class="inputs" type="radio"
             id="features-1"
             name="1"
             value="features-value-1"
             data-money="-300"
             data-product-money="2500"
              onclick="PriceCalculator('gb', -300)"
        >
        <label class="btn btn-pill" style="display: inline-block;" for="features-1">16GB</label>
      </div>
      <div class="col-sm-3 col-md-4 col-lg-3">
        <input class="inputs" type="radio"
             id="features-2"
             name="1"
             value="features-value-2"
             data-money="-200"
             data-product-money="2500"
              onclick="PriceCalculator('gb', -200)"
        >
        <label class="btn btn-pill" style="display: inline-block;" for="features-2">32GB</label>
      </div>
      <div class="col-sm-3 col-md-4 col-lg-3">
        <input class="inputs" type="radio"
             id="features-3"
             name="1"
             value="features-value-3"
             data-money="-50"
             data-product-money="2500"
              onclick="PriceCalculator('gb', -50)"
        >
        <label class="btn btn-pill" style="display: inline-block;" for="features-3">64GB</label>
      </div>
  </div>
  
  <h4>DISPLAY</h4>
  <div class="row mb-3" style="display: inline-block">
      <div class="col-sm-3 col-md-4 col-lg-3">
        <input class="inputs" type="radio"
             id="features-1"
             name="2"
             value="features-value-1"
             data-money="0"
             data-product-money="2500"
              onclick="PriceCalculator('display', 2500)"
        >
        <label class="btn btn-pill" style="display: inline-block;" for="features-1">Durable</label>
      </div>
      <div class="col-sm-3 col-md-4 col-lg-3">
        <input class="inputs" type="radio"
             id="features-2"
             name="2"
             value="features-value-2"
             data-money="-1500"
             data-product-money="2500"
              onclick="PriceCalculator('display', 1500)"
        >
        <label class="btn btn-pill" style="display: inline-block;" for="features-2">Broken</label>
      </div>
  </div>
</div>
</div>
<div style="position:absolute; right: 0px;">
<div style="display: inline-block; margin-right: 20px"><strong>Pre-bid price:</strong> <div style="display: inline-block" id="money">Not calculated</div></div>
</div>
</div>
</div>

2 Answers

If you have an object like this (which can dynamically change in size / key values)

const values = {
  gb: 100,
  display: 400,
  test: -1200,
  best: 500
}

then the total of all values can be calculated dynamically like this:

const total = Object.values(values).reduce((x,y)=>x=+y,0)

For the purpose of understanding, this can be broken down and console.logged like this

const numbers = Object.values(values);
console.log(numbers) // returns [100,400,-1200,500]
const total = numbers.reduce((x,y)=>x=+y,0) // returns total = -200 

So like last time, delegate - I am using jQuery because your previous code used it. I'll add the vanilla one too

window.addEventListener("DOMContentLoaded", () => {
  const total = document.getElementById("money");
  document.getElementById("form_step_1").addEventListener("input", e => {
    let sum = +e.target.closest(".container").dataset.productPrice;
    document.querySelectorAll(".row h4").forEach(h4 => {
      let title = h4.textContent,
        container = h4.closest("div"), // parent
        chosen = container.querySelectorAll("[type=radio]:checked");
      if (chosen.length !== 0) {
        chosen.forEach(rad => {
          console.log(title,rad.value,Number(rad.dataset.discount))
          sum += Number(rad.dataset.discount)
        })
      }
      total.textContent = sum.toFixed(2);
    })
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="form_step_1">
  <div class="container" data-product-price="2500">
    <div class="row">
      <div class="talepler mb-3">
        <h4>GB</h4>
        <div class="row mb-3" style="display: inline-block">
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-1" name="1" value="features-value-1" data-discount="-300">
            <label class="btn btn-pill" style="display: inline-block;" for="features-1">16GB</label>
          </div>
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-2" name="1" value="features-value-2" data-discount="-200">
            <label class="btn btn-pill" style="display: inline-block;" for="features-2">32GB</label>
          </div>
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-3" name="1" value="features-value-3" data-discount="-50">
            <label class="btn btn-pill" style="display: inline-block;" for="features-3">64GB</label>
          </div>
        </div>
      </div>
      <div class="talepler mb-3">
        <h4>DISPLAY</h4>
        <div class="row mb-3" style="display: inline-block">
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-1" name="2" value="features-value-1" data-discount="0">
            <label class="btn btn-pill" style="display: inline-block;" for="features-1">Durable</label>
          </div>
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-2" name="2" value="features-value-2" data-discount="-1500">
            <label class="btn btn-pill" style="display: inline-block;" for="features-2">Broken</label>
          </div>
        </div>
      </div>
    </div>
    <div style="position:absolute; right: 0px;">
      <div style="display: inline-block; margin-right: 20px"><strong>Pre-bid price:</strong>
        <div style="display: inline-block" id="money">Not calculated</div>
      </div>
    </div>
  </div>
</div>

jQuery

$(function() {
  $("#form_step_1").on("input", function(e) {
    let sum = +$(e.target).closest("div.container").data("price");
    console.log(sum)
    $(".row h4").each(function() {
      let title = $(this).text(),
        $container = $(this).closest("div"), // parent
        $chosen = $container.find("[type=radio]:checked");
      if ($chosen.length !== 0) {
        $chosen.each(function() {
          console.log(title,$(this).val(),Number($(this).data("discount")));
          sum += Number($(this).data("discount"));
        })
      }
      $("#money").text(sum.toFixed(2))
    })
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="form_step_1">
  <div class="container" data-price="2500">
    <div class="row">
      <div class="talepler mb-3">
        <h4>GB</h4>
        <div class="row mb-3" style="display: inline-block">
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-1" name="1" value="features-value-1" data-discount="-300">
            <label class="btn btn-pill" style="display: inline-block;" for="features-1">16GB</label>
          </div>
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-2" name="1" value="features-value-2" data-discount="-200">
            <label class="btn btn-pill" style="display: inline-block;" for="features-2">32GB</label>
          </div>
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-3" name="1" value="features-value-3" data-discount="-50">
            <label class="btn btn-pill" style="display: inline-block;" for="features-3">64GB</label>
          </div>
        </div>
      </div>
      <div class="talepler mb-3">
        <h4>DISPLAY</h4>
        <div class="row mb-3" style="display: inline-block">
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-1" name="2" value="features-value-1" data-discount="0">
            <label class="btn btn-pill" style="display: inline-block;" for="features-1">Durable</label>
          </div>
          <div class="col-sm-3 col-md-4 col-lg-3">
            <input class="inputs" type="radio" id="features-2" name="2" value="features-value-2" data-discount="-1500">
            <label class="btn btn-pill" style="display: inline-block;" for="features-2">Broken</label>
          </div>
        </div>
      </div>
    </div>
    <div style="position:absolute; right: 0px;">
      <div style="display: inline-block; margin-right: 20px"><strong>Pre-bid price:</strong>
        <div style="display: inline-block" id="money">Not calculated</div>
      </div>
    </div>
  </div>
</div>

Related