0

I'm trying to make an order form that adds up the values that are selected from different widget types, on submit there is no output. I'm not sure if I'm doing this right or if I'm going in the wrong direction? Is the way I'm trying to select the value actually working with the if statements, or is there another way to select the value?

var size = document.getElementById('pizzaSize').value;

if (document.getElementById('pepperoni').selected) {
  var pepperoni = 1.50;
}
if (document.getElementById('mushrooms').selected) {
  var mushrooms = 1.50;
}
if (document.getElementById('peppers').selected) {
  var peppers = 1.50;
}
if (document.getElementById('pesto').selected) {
  var pesto = 2.00;
}

function totalPizza() {

  var total = parseInt(size + pepperoni + mushrooms + peppers + pesto);

  var tax = parseInt(total * '.10');
  var totalPlusTax = parseInt(total + tax);

  document.getElementById("total").innerHTML = "Subtotal: " + total;
  document.getElementById("tax").innerHTML = "Sales Tax: " + tax;
  document.getElementById("totalTax").innerHTML = "Total: " + totalPlusTax;
}
<h2 id="heading">Pizza Order Form</h2>
<form id="pizzaOrder" action="#">
  <label for="name">Name</label><br>
  <input placeholder="First Last" type="text" name="name" id="name" minlength="5" maxlength="30"><br><br>
  <label id="pizzaSize" for="size">Pizza Size</label><br>
  <input name="size" type="radio" id="size" value="4">Personal<br>
  <input name="size" type="radio" id="size" value="6">Small<br>
  <input name="size" type="radio" id="size" value="8">Medium<br>
  <input name="size" type="radio" id="size" value="10">Large<br>
  <br>
  <label for="crust">Crust Type</label><br>
  <select id="crust" name="crust">
    <option value="thin">Thin</option>
    <option value="regular">Regular</option>
    <option value="pan">Pan</option>
    <option value="stuffed">Stuffed</option>
  </select>
  <br><br>
  <label for="toppings">Toppings:</label><br>
  <label for="pepperoni">Pepperoni</label>
  <input type="checkbox" id="pepperoni" name="toppings" value="1.50"><br>
  <label for="mushrooms">Mushrooms</label>
  <input type="checkbox" id="mushrooms" name="toppings" value="1.50"><br>
  <label for="peppers">Green Peppers</label>
  <input type="checkbox" id="peppers" name="toppings" value="1.50"><br>
  <label for="pesto">Pesto</label>
  <input type="checkbox" id="pesto" name="toppings" value="2"><br>
  <br><button type="submit" onsubmit="totalPizza();">Place Order</button>
</form>
<p id="total"></p>
<p id="tax"></p>
<p id="totalTax"></p>

Thank you for any suggestions.

Mike
  • 1,279
  • 7
  • 18
jozu
  • 3
  • 3

3 Answers3

0

Use onclick="totalPizza()" instead of onsubmit. onsubmit is an event for the torm tag, not a button.

Matt U
  • 4,970
  • 9
  • 28
0

There are several things you need to do so your code will work as expected.

  1. Move the onsubmit to the form (Read more)
  2. You don't want the form to being submitted so you need to stop the submit using event.preventDefault
  3. You have multiple elements with the same id. You should avoid it and you really don't need it. To get the value of radio buttons list, search for the :checked one and get its value (See that answer)
  4. Move all the logic into the function so all the inputs will be counted for each click.
  5. There is also a small change in the tax calculation.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Pizza</title>
</head>

<body>
  <h2 id="heading">Pizza Order Form</h2>
  <form id="pizzaOrder" action="#" onsubmit="totalPizza(event)">
    <label for="name">Name</label><br>
    <input placeholder="First Last" type="text" name="name" id="name" minlength="5" maxlength="30"><br><br>
    <label id="pizzaSize" for="size">Pizza Size</label><br>
    <input name="size" type="radio" value="4">Personal<br>
    <input name="size" type="radio" value="6">Small<br>
    <input name="size" type="radio" value="8">Medium<br>
    <input name="size" type="radio" value="10">Large<br>
    <br>
    <label for="crust">Crust Type</label><br>
    <select id="crust" name="crust">
      <option value="thin">Thin</option>
      <option value="regular">Regular</option>
      <option value="pan">Pan</option>
      <option value="stuffed">Stuffed</option>
    </select>
    <br><br>
    <label for="toppings">Toppings:</label><br>
    <label for="pepperoni">Pepperoni</label>
    <input type="checkbox" id="pepperoni" name="toppings" value="1.50"><br>
    <label for="mushrooms">Mushrooms</label>
    <input type="checkbox" id="mushrooms" name="toppings" value="1.50"><br>
    <label for="peppers">Green Peppers</label>
    <input type="checkbox" id="peppers" name="toppings" value="1.50"><br>
    <label for="pesto">Pesto</label>
    <input type="checkbox" id="pesto" name="toppings" value="2"><br>
    <br><button type="submit">Place Order</button>
  </form>
  <p id="total"></p>
  <p id="tax"></p>
  <p id="totalTax"></p>
  <script>
    function totalPizza(e) {
      e.preventDefault();
      var size = document.querySelector('input[name="size"]:checked').value;

      if (document.getElementById('pepperoni').selected) {
        var pepperoni = 1.50;
      }
      if (document.getElementById('mushrooms').selected) {
        var mushrooms = 1.50;
      }
      if (document.getElementById('peppers').selected) {
        var peppers = 1.50;
      }
      if (document.getElementById('pesto').selected) {
        var pesto = 2.00;
      }

      var total = parseInt(size + pepperoni + mushrooms + peppers + pesto);

      var tax = (total * 0.1).toFixed(2);
      var totalPlusTax = total + tax;

      document.getElementById("total").innerHTML = "Subtotal: " + total;
      document.getElementById("tax").innerHTML = "Sales Tax: " + tax;
      document.getElementById("totalTax").innerHTML = "Total: " + totalPlusTax;
    }
  </script>
</body>

</html>

Let me know if something is not clear..

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
0

Please refer to the example below for the following changes:

  1. move the onsubmit attribute from the button to the form element
  2. you don't need independent if-statements to set your values, simply iterate over the inputs and look for checked state
  3. use event.preventDefault to stay on the page (and prevent it from leaving/reloading the page)
  4. use parseFloat as opposed to parseInt to capture decimals
  5. format the results with .toFixed to address issues with floating point arithmetic -- note: this isn't a complete solution, but addresses the simplistic case of the demo. Addressing/mitigating the underlying floating-point math issues would require a more elaborate library
  6. use '$' to denote monetary value

(see bottom for additional changes)

function totalPizza() {
  event.preventDefault() // prevent form from switching pages

  let subtotal = 0
  let inputs = document.querySelectorAll('input,select')

  inputs.forEach(input => {
    if (input.checked)
      subtotal += parseFloat(input.value)
  })

  let tax = parseFloat(subtotal * '.10');
  let total = parseFloat(subtotal + tax);

  document.querySelector("#subtotal").innerHTML = "Subtotal: $"  + subtotal.toFixed(2);
  document.querySelector("#tax").innerHTML      = "Sales Tax: $" + tax.toFixed(2);
  document.querySelector("#totalTax").innerHTML = "Total: $"     + total.toFixed(2);
}
label {
  display: block;
}

.mt-1 {
  margin-top: 1rem;
}

.row {
  display: flex;
}

.col {
  margin: 0 2rem;
}
<h2 id="heading">Pizza Order Form</h2>
<div class="row">
  <div class="col">
    <form id="pizzaOrder" action="#" onsubmit="totalPizza()">

      <label for="name">Name</label>
      <input placeholder="First Last" type="text" name="name" id="name" minlength="5" maxlength="30">

      <label class="mt-1" id="pizzaSize">Pizza Size</label>
      <label><input name="size" type="radio" value="4"> Personal</label>
      <label><input name="size" type="radio" value="6"> Small</label>
      <label><input name="size" type="radio" value="8"> Medium</label>
      <label><input name="size" type="radio" value="10"> Large</label>

      <label class="mt-1" for="crust">Crust Type</label>
      <select id="crust" name="crust">
        <option value="thin">Thin</option>
        <option value="regular">Regular</option>
        <option value="pan">Pan</option>
        <option value="stuffed">Stuffed</option>
      </select>

      <label class="mt-1" for="toppings">Toppings:</label>
      <label for="pepperoni"><input type="checkbox" id="pepperoni" name="toppings" value="1.50"> Pepperoni</label>
      <label for="mushrooms"><input type="checkbox" id="mushrooms" name="toppings" value="1.50"> Mushrooms</label>
      <label for="peppers"><input type="checkbox" id="peppers" name="toppings" value="1.50"> Green Peppers</label>
      <label for="pesto"> <input type="checkbox" id="pesto" name="toppings" value="2"> Pesto</label>

      <button class="mt-1" type="submit">Place Order</button>
    </form>
  </div>
  <div class="col">
    <p id="subtotal"></p>
    <p id="tax"></p>
    <p id="totalTax"></p>
  </div>
</div>

Layout Changes

  • Added was also some row/col divs for layout
  • Inputs were placed inside label for improved UI (clicking label to select input)
  • Removed br elements and added CSS for spacing
  • Removed duplicate id attributes (can only have one unique)
Mike
  • 1,279
  • 7
  • 18
  • Thank you, this is exactly how I had it in mind. 'let inputs = document.querySelectorAll('input,select')' is what I was looking for but couldn't find, I will make these changes to the form. – jozu Dec 06 '19 at 02:58
  • I also hadn't heard of event.preventDefault(), I only knew of using action="#" to try to get the page to not refresh after the form is submitted. – jozu Dec 06 '19 at 03:02
  • I need to update the description in the answer. The method stops the native event action, the result is unique to the context (or input) that triggered the event. So stopping a form submission event, will prevent the browser from navigating to the form's URL, preventing a checkbox click event would have a different action it's preventing. In the case of the form submission, it will prevent the event from continuing on, which is necessary for the example – Mike Dec 06 '19 at 17:40