Home > Software engineering >  How to Get Value of Radio Button on Click and Subtract Value When Unchecked?
How to Get Value of Radio Button on Click and Subtract Value When Unchecked?

Time:06-12

Here's my codepen https://codepen.io/shodoro/pen/wvyQNJO

Right now, my checkbox options add or subtract the value based on whether something is selected or deselected.

My problem is for my radio buttons, if I click on one option 3 times, it will add that value 3 times instead of subtracting or resetting.

So if I click on one radio button with a value of $3 and I press it 10 times, it will add to $30, when it should have went from $3 to $0, back to $3 to 0 etc... basically only add the value once when clicked

How is my logic for my checkboxes working, but for my radio buttons it just keeps adding the values with each click?

Here's the JS

document.addEventListener("click", ({ target }) => {
  if (target.className === "food" && target.checked) {
    window.menuItems  = parseInt(target.value);
  } else if (target.className === "food" && !target.checked) {
    window.menuItems -= parseInt(target.value);
  } 
  
  //tips logic
  else if (target.className === "tips" && target.checked) {
    window.tip  = parseInt(target.value);
  } else if (target.className === "tips" && !target.checked) {
    window.tip -= parseInt(target.value);
  } else {
    return;
  }

I want my radio buttons to do the same as my checkboxes, but I don't understand why they aren't?

CodePudding user response:

For tips, you don't want to add or subtract as tips are supposed to be either/or! So updating your JS code with the version below should fix it :D

window.menuItems = 0;
window.tip = 0;

const foodTotal = document.getElementById("price");
const tipTotal = document.getElementById("tip");

document.addEventListener("click", ({ target }) => {
  if (target.className === "food" && target.checked) {
    window.menuItems  = parseInt(target.value);
  } else if (target.className === "food" && !target.checked) {
    window.menuItems -= parseInt(target.value);
  } 
  
  //tips logic
  if (target.className === "tips" && target.checked) {
    window.tip = parseInt(target.value);
  }
  
    foodTotal.textContent = `Food Total: $${(window.menuItems / 100).toFixed(2)}`;
    tipTotal.textContent = `Tip: $${(window.tip / 100).toFixed(2)}`;
});

Hope this helps!

CodePudding user response:

you should just use = instead of = or -= for radio buttons.

window.menuItems = 0;
window.tip = 0;

const foodTotal = document.getElementById("price");
const tipTotal = document.getElementById("tip");
const orderTotal = document.getElementById("total");


document.addEventListener("click", ({ target }) => {
  if (target.className === "food" && target.checked) {
    window.menuItems  = parseInt(target.value);
  } else if (target.className === "food" && !target.checked) {
    window.menuItems -= parseInt(target.value);
  } 
  
  //tips logic
  if (target.className === "tips" && target.checked) {
    window.tip = parseInt(target.value);
  }
var foodTotalAmount = (window.menuItems / 100);
var tipTotalAmount = (window.tip / 100);
var orderTotalAmount = (foodTotalAmount   tipTotalAmount);
    foodTotal.textContent = `Food Total: $${foodTotalAmount.toFixed(2)}`;
tipTotal.textContent = `Tip: $${tipTotalAmount.toFixed(2)}`;
orderTotal.textContent = `Your order total is: $${orderTotalAmount.toFixed(2)}`;
});
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Perfect Pies</title>
  </head>
  <body>
        <div >
          <h2>Checkbox Items</h2>
          <div >
            <input type="checkbox" name="items" value="1000"  />
            <label for="items">Food $10</label>
          </div>
          <div >
            <input type="checkbox" name="items" value="2000"  />
            <label for="items">Food $20</label>
          </div>
          <div >
            <input type="checkbox" name="items" value="3000"  />
            <label for="items">Food $30</label>
          </div>
        <div >
          <h2>Radio Items click an option multiple times and you will see it add infinitely</h2>
          <p id="price">Food Total: $0.00</p>
          <p id="tip">Tip: $0.00</p>
          <div >
            <div>
              <input
                type="radio"
                value="0"
                id="tip0"
                name="tip"
                
                checked
              />
              <label for="tip0">$0</label>
            </div>
            <div>
              <input
                type="radio"
                value="300"
                id="tip1"
                name="tip"
                
              />
              <label for="tip1">$3</label>
            </div>
            <div>
              <input
                type="radio"
                value="500"
                id="tip2"
                name="tip"
                
              />
              <label for="tip2">$5</label>
            </div>
          </div>
          <p id="total">Your order total is: $0.00</p>
          <button id="orderBtn">Place Order</button>
        </div>
      </div>
    </div>
  </body>
</html>

CodePudding user response:

Subsequent clicks on the same radio do not change the value, but you are updating your total value based on clicks and not the input.value.
What you should be doing for both checkboxes and radios is to listen for the change event, then update your total value using the currently selected values of the inputs.

window.menuItems = 0;
window.tip = 0;

const foodTotal = document.getElementById("price");
const tipTotal = document.getElementById("tip");


document.addEventListener("change", ({
  target
}) => {
  if (target.className === "food") {
    let total = 0;
    document.querySelectorAll(`input[name="${target.name}"]:checked`).forEach((chk) => total  = parseInt(chk.value))
    window.menuItems = total;
  }
  //tips logic
  else if (target.className === "tips") {
    window.tip = document.querySelector(`input[name="${target.name}"]:checked`).value;
  } else {
    return;
  }

  foodTotal.textContent = `Food Total: $${(window.menuItems / 100).toFixed(2)}`;
  tipTotal.textContent = `Tip: $${(window.tip / 100).toFixed(2)}`;
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="styles.css" />
  <title>Perfect Pies</title>
</head>

<body>
  <div >
    <h2>Checkbox Items</h2>
    <div >
      <input type="checkbox" name="items" value="1000"  />
      <label for="items">Food $10</label>
    </div>
    <div >
      <input type="checkbox" name="items" value="2000"  />
      <label for="items">Food $20</label>
    </div>
    <div >
      <input type="checkbox" name="items" value="3000"  />
      <label for="items">Food $30</label>
    </div>
    <div >
      <h2>Radio Items</h2>
      <p id="price">Food Total: $0.00</p>
      <p id="tip">Tip: $0.00</p>
      <div >
        <div>
          <input type="radio" value="0" id="tip0" name="tip"  checked />
          <label for="tip0">$0</label>
        </div>
        <div>
          <input type="radio" value="300" id="tip1" name="tip"  />
          <label for="tip1">$3</label>
        </div>
        <div>
          <input type="radio" value="500" id="tip2" name="tip"  />
          <label for="tip2">$5</label>
        </div>
      </div>
      <p id="total">Your order total is: $0.00</p>
      <button id="orderBtn">Place Order</button>
    </div>
  </div>
  </div>
</body>

</html>

CodePudding user response:

Simplified

Just loop each time over the checked inputs

Note I am using matches since className can have more than one class

const foodTotal = document.getElementById("price");
const tipTotal = document.getElementById("tip");
const total = document.getElementById("total")
const container = document.querySelector(".menu-items");
container.addEventListener("click", () => {
  let food = 0;
  let tips = 0;
  let tot = 0;
  container.querySelectorAll("input:checked").forEach(inp => {
    food  = inp.matches(".food") ?  inp.value : 0;
    tips  = inp.matches(".tips") ?  inp.value : 0; 
    tot = food   tips;
  })  
  foodTotal.textContent = `$${(food/100).toFixed(2)}`;
  tipTotal.textContent = `$${(tips/100).toFixed(2)}`;
  total.textContent = `${(tot/100).toFixed(2)}`;
});
<div >
  <h2>Checkbox Items</h2>
  <div >
    <input type="checkbox" name="items" value="1000"  />
    <label for="items">Food $10</label>
  </div>
  <div >
    <input type="checkbox" name="items" value="2000"  />
    <label for="items">Food $20</label>
  </div>
  <div >
    <input type="checkbox" name="items" value="3000"  />
    <label for="items">Food $30</label>
  </div>
  <div >
    <p>Food Total: <span id="price">$0.00</span></p>
    <p>Tip: <span id="tip">$0.00</span></p>
    <div >
      <div>
        <input type="radio" value="0" id="tip0" name="tip"  checked />
        <label for="tip0">$0</label>
      </div>
      <div>
        <input type="radio" value="300" id="tip1" name="tip"  />
        <label for="tip1">$3</label>
      </div>
      <div>
        <input type="radio" value="500" id="tip2" name="tip"  />
        <label for="tip2">$5</label>
      </div>
    </div>
    <p>Your order total is: <span id="total">$0.00</span></p>
    <button id="orderBtn">Place Order</button>
  </div>
</div>

  • Related