skip to Main Content

I am building a price calculator for a tour. The total price should change based on the tour type selected and based on the number of guests.

Right now the calculator updates and calculates the total price when a tour type is selected, however I can’t get it to update when I change the guest count.

The way it programed right now, if I put in guest count first an then select a tour type, the total price displays correctly. However, if I then go back and try to update the guest count, the price won’t update – so I currently have to change the guest count, then select a new tour type and then reselect the tour type that I want, in order to get an updated total

function populate(tournameId) {
  var total = 0;
  var quantity = document.getElementsByName('quantity')[0].value;
  var tournameSelect = document.getElementById(tournameId);

  let selectedOption = tournameSelect.options[tournameSelect.selectedIndex];

  var selectedtournameValue = +selectedOption.dataset.price;
  var total = quantity * selectedtournameValue;
  document.getElementById("total").value = total;
}
<p class="normalinput">Enter Total Number of Guests:</p>
<input type="number" class="quantity" name="quantity" value="0" required>
<br>
<select class="normalinput" name="tourname" id="tourname" onchange="populate('tourname')">
  <option data-price="0" value="None">None</option>
  <option data-price="59" value="G0001">Milano Coffee Crawl (Coffee Included) <span>€       </span>59</option>
  <option data-price="49" value="G0002">Milano Coffee Crawl (Coffee Not Included) <span>€</span>49</option>
  <option data-price="39" value="G0003">Milano History Walk <span>€</span>39</option>
  <option data-price="69" value="G0004">Napoli Coffee Crawl (Coffee Included) <span>€</span>69</option>
  <option data-price="59" value="G0005">Npoli Coffee Crawl (Coffee Not Included) <span>€</span>59</option>
</select>
<p class="total"> Total: <span>€</span><input type="text" name="total" id="total" value="0"></p>

3

Answers


  1. The issue is because you need to bind event handlers to both the select and input.

    Also note that it’s no longer good practice to use the onX attributes in your HTML, so be very wary of any guides or tutorials that recommend this. Instead you should use JS to attach your event handlers, as demonstrated in the following example:

    const tourSelect = document.querySelector('#tourname');
    const quantityField = document.querySelector('.quantity');
    const totalField = document.querySelector('#total');
    
    const calculateTotal = () => {
      const selectedOption = tourSelect.options[tourSelect.selectedIndex];
      const selectedtournamePrice = +selectedOption.dataset.price;  
      const total = quantityField.value * selectedtournamePrice;
      totalField.value = total || 0;
    }
    
    tourSelect.addEventListener('change', calculateTotal)
    quantityField.addEventListener('input', calculateTotal)
    
    calculateTotal();
    <p class="normalinput">Enter Total Number of Guests:</p>
    <input type="number" class="quantity" name="quantity" value="0" required><br />
    
    <select class="normalinput" name="tourname" id="tourname">
      <option data-price="0" value="None">None</option>
      <option data-price="59" value="G0001">Milano Coffee Crawl (Coffee Included) <span>&#8364;       </span>59</option>
      <option data-price="49" value="G0002">Milano Coffee Crawl (Coffee Not Included) <span>&#8364;</span>49</option>
      <option data-price="39" value="G0003">Milano History Walk <span>&#8364;</span>39</option>
      <option data-price="69" value="G0004">Napoli Coffee Crawl (Coffee Included) <span>&#8364;</span>69</option>
      <option data-price="59" value="G0005">Npoli Coffee Crawl (Coffee Not Included) <span>&#8364;</span>59</option>
    </select>
    <p class="total"> 
      Total: <span>&#8364;</span>
      <input type="text" name="total" id="total" value="0">
    </p>
    Login or Signup to reply.
  2. This can be fixed by calling the same function on onchange of input

    <input type="number" class="quantity" name="quantity" value="0" required onchange="populate('tourname')">
    

    Below is the final updated script,

    function populate(tournameId) {
      var total = 0;
      var quantity = document.getElementsByName('quantity')[0].value;
      var tournameSelect = document.getElementById(tournameId);
    
      let selectedOption = tournameSelect.options[tournameSelect.selectedIndex];
    
      var selectedtournameValue = +selectedOption.dataset.price;
      var total = quantity * selectedtournameValue;
      document.getElementById("total").value = total;
    }
    <p class="normalinput">Enter Total Number of Guests:</p>
    <input type="number" class="quantity" name="quantity" value="0" required onchange="populate('tourname')">
    <br>
    <select class="normalinput" name="tourname" id="tourname" onchange="populate('tourname')">
      <option data-price="0" value="None">None</option>
      <option data-price="59" value="G0001">Milano Coffee Crawl (Coffee Included) <span>&#8364;       </span>59</option>
      <option data-price="49" value="G0002">Milano Coffee Crawl (Coffee Not Included) <span>&#8364;</span>49</option>
      <option data-price="39" value="G0003">Milano History Walk <span>&#8364;</span>39</option>
      <option data-price="69" value="G0004">Napoli Coffee Crawl (Coffee Included) <span>&#8364;</span>69</option>
      <option data-price="59" value="G0005">Npoli Coffee Crawl (Coffee Not Included) <span>&#8364;</span>59</option>
    </select>
    <p class="total"> Total: <span>&#8364;</span><input type="text" name="total" id="total" value="0"></p>
    Login or Signup to reply.
  3. I would use the input event and delegate from a common container.

    Also use value="" on the select in case you ever want to make it required

    window.addEventListener('DOMContentLoaded', () => {
      const tourSelect = document.getElementById('tourname');
      const quantityField = document.querySelector('.quantity');
      const totalField = document.getElementById('total');
      const container = document.querySelector('.form-container');
      const calculateTotal = () => {
        const selectedOption = tourSelect.options[tourSelect.selectedIndex];
        const selectedtournamePrice = +selectedOption.dataset.price;
        const total = quantityField.value * selectedtournamePrice;
        totalField.value = total || 0;
      }
      container.addEventListener('input', calculateTotal)
      calculateTotal(); // inittialise
    
    });
    <div class="form-container">
      <p class="normalinput">Enter Total Number of Guests:</p>
      <input type="number" class="quantity" name="quantity" value="0" required>
      <br>
      <select class="normalinput" name="tourname" id="tourname">
        <option data-price="0" value="">None</option>
        <option data-price="59" value="G0001">Milano Coffee Crawl (Coffee Included) <span>&#8364;       </span>59</option>
        <option data-price="49" value="G0002">Milano Coffee Crawl (Coffee Not Included) <span>&#8364;</span>49</option>
        <option data-price="39" value="G0003">Milano History Walk <span>&#8364;</span>39</option>
        <option data-price="69" value="G0004">Napoli Coffee Crawl (Coffee Included) <span>&#8364;</span>69</option>
        <option data-price="59" value="G0005">Npoli Coffee Crawl (Coffee Not Included) <span>&#8364;</span>59</option>
      </select>
      <p class="total"> Total: <span>&#8364;</span><input readonly type="text" name="total" id="total" value="0"></p>
    
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search