What is the best way to choose the checked items and calculate the total price by adding up all the prices of the selected items?

Seeking help with utilizing JavaScript to identify and collect all checked items from an HTML file.
I'm looking to determine which items have been selected from a menu, each of which has an associated price.
How can I access the prices of the checked items in a JavaScript array?
My goal is to calculate the total price of all checked items from the HTML menu.
Making progress on the code. Using a forEach() loop to iterate through the checked items and isolate them by their id.
Considered using split('Checkbox') but unsure how to make it work to sum up the prices from the menuItem array and get the total: total += menu.price.

var menuItems = 
  [ { itemName: 'salad',        price: 13.95 } 
  , { itemName: 'pancakes',     price:  8.95 } 
  , { itemName: 'omlette',      price:  8.95 } 
  , { itemName: 'croissant',    price:  5.95 } 
  , { itemName: 'muffin',       price:  8.95 } 
... (content continues)
      <input type="checkbox" id="milCheckbox" name="milk" />
      $3.95
    </td>
  </tr>
</table>
<div>
  <form>
    <input type="submit" value="Submit" id="sub">
    <input type="reset" value="Reset">
  </form>
</div>  
<div style="margin-top: 10px;">
  <button type="button">Total Amount</button>
</div>
        
<script type="text/javascript" src="/js/menu.js"></script>
</body>
</html>

Answer №1

To create a similar setup, you can set the price for each item using a data attribute in the checkbox input. Just be cautious of any potential floating-point errors.

document.getElementById("SubmitButton").addEventListener('click', function(e) {
  e.preventDefault();
  var selectedItems = document.querySelectorAll('.item-selection:checked');
  
  var selectedItemPrices = [];
  var total = 0;
  
  for (var i = 0; i < selectedItems.length; i++) {
    var price = Number.parseFloat(selectedItems[i].getAttribute('data-price'));
  
    selectedItemPrices.push({
      itemName: selectedItems[i].getAttribute('name'),
      price: price.toFixed(2)
    });
    
    total += price;
  }
  
  console.log(selectedItemPrices);
  console.log(total.toFixed(2));
});
<table style="width:100%">
  <tr>
    <th>BreakFast</th>
    <th>Lunch</th>
    <th>Beverages</th>
  </tr>
  <tr>
    <td><label for="Pancakes"><b>Blueberry Pancakes</b></label>
      <input class="item-selection" type="checkbox" id="panCheckbox" name="pancakes" data-price="8.95" />$8.95</td>
    <td><label for="burger"><b>Cheeseburger</b></label>
      <input class="item-selection" type="checkbox" id="burg" name="burger" data-price="10.95"/>$10.95</td>
    <td><label for="Coffee"><b>Black Coffee:</b></label>
      <input class="item-selection" type="checkbox" id="cofCheckbox" name="coffee" data-price="1.95"/>$1.95</td>
  </tr>
  <tr>
    <td><label for="Omelette"><b>Vegetable Omelette</b></label>
      <input class="item-selection" type="checkbox" id="omlCheckbox" name="omlette" data-price="8.95"/>$8.95</td>
    <td><label for="Wrap"><b>Teriyaki Wrap:</b></label>
      <input class="item-selection" type="checkbox" id="rapCheckbox" name="wrap" data-price="12.95"/>$12.95</td>
    <td><label for="Tea"><b>Green Tea:</b></label>
      <input class="item-selection" type="checkbox" id="teCheckbox" name="tea" data-price="11.95"/>$11.95</td>
  </tr>
  <tr>
    <td> <label for="Croissant"><b>Croissant:</b></label>
      <input class="item-selection" type="checkbox" id="crosCheckbox" name="croissant" data-price="5.95"/>$5.95</td>
    <td><label for="salad"><b>Ceasar Salad:</b></label>
      <input class="item-selection" type="checkbox" id="salCheckbox" name="sald" data-price="13.95"/>$13.95</td>
    <td><label for="beer"><b>Corona Beer 12 oz:</b></label>
      <input class="item-selection" type="checkbox" id="BerCheckbox" name="Beer" data-price="5.95"/>$5.95</td>
  </tr>
  <tr>
    <td> <label for="Muffin"><b>Blueberry Muffin</b></label>
      <input class="item-selection" type="checkbox" id="MufCheckbox" name="muffin" data-price="8.95"/>$8.95</td>
    <td><label for="soup"><b>Tomato Soup:</b></label>
      <input class="item-selection" type="checkbox" id="souCheckbox" name="soup" data-price="11.95"/>$11.95</td>
    <td><label for="Milk"><b>Chocolate Milk:</b></label>
      <input class="item-selection" type="checkbox" id="milCheckbox" name="milk" data-price="3.95"/>$3.95</td>
  </tr>
</table>
<div>
  <form>
    <input id="SubmitButton" type="submit" value="Submit" id="sub">
    <input type="reset" value="Reset">
  </form>
</div>
<div style="margin-top: 10px;">
  <button type="button">Total Amount</button>
</div>

Answer №2

Give this a try! The solution provided will function based on checking/unchecking the checkbox. If you require it to work on a button click instead, just let me know and I can make the necessary modifications.

I've made adjustments to your HTML code as well. You now have the option of using the value attribute of the checkbox to assign specific item values, which can then be utilized for further calculations in JavaScript. Feel free to reach out if you encounter any issues!

<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org">
<head>
    <title>MENU</title>
    <script type="text/javascript" src="/js/menu.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript">

        var total = 0;
        $(document).ready(function () {
            $('input[type="checkbox"]').change(function () {
                var ischecked = $(this).is(':checked');
                if (!ischecked) {
                    total -= parseFloat($(this).val());
                } else {
                    total += parseFloat($(this).val());
                }
                console.log(total.toFixed(2));
            });
        });

    </script>
    <link rel="stylesheet" type="text/css" href="css/menu.css">
</head>
<body>
    <form>
        <div class="name">
            <h1>JOE'S FAMILY DINER</h1>
        </div>

        <table style="width:100%">
            <tr>
                <th>BreakFast</th>
                <th>Lunch</th>
                <th>Beverages</th>
            </tr>
            <tr>
                <td>
                    <label for="Pancakes"> <b>Blueberry Pancakes</b> </label>
                    <input type="checkbox" id="panCheckbox" name="pancakes" value="8.95" />$8.95

                </td>
                <td>
                    <label for="burger"> <b>Cheeseburger</b> </label>
                    <input type="checkbox" id="burg" name="burger" value="10.95" />
                    $10.95
                </td>
                <td>
                    <label for="Coffee"> <b>Black Coffee:</b> </label>
                    <input type="checkbox" id="cofCheckbox" name="coffee" value="1.95" />
                    $1.95
                </td>
            </tr>
             [...]
        	<div>
            	<input type="submit" value="Submit" id="sub">
            	<input type="reset" value="Reset">
        	</div>
        	<div style="margin-top: 10px;">
            	<button type="button">Total Amount</button>
       		</div>
    	</form>
	</body>
</html>

Answer №3

Using FormData, you can easily retrieve only the checked elements in a form.

This method requires reorganizing your HTML to suit this functionality.

Here's a practical example of how to utilize forms effectively:

const menuItems = 
  { BreakFast :
    [ { itemName: 'pancakes',  price: 8.95, label: 'Blueberry Pancakes' }
    , { itemName: 'omlette',   price: 8.95, label: 'Vegetable Omelette' }
    , { itemName: 'croissant', price: 5.95, label: 'Croissant'          }
    , { itemName: 'muffin',    price: 8.95, label: 'Blueberry Muffin'   }
    ]
  , Lunch :
    [ { itemName: 'cheeseburger', price: 10.95, label: 'Cheeseburger'  }
    , { itemName: 'teriyaki',     price: 12.95, label: 'Teriyaki Wrap' }
    , { itemName: 'salad',        price: 13.95, label: 'Ceasar Salad'  }
    , { itemName: 'soup',         price: 11.95, label: 'Tomato Soup'   }
    ]
  , Beverages :
    [ { itemName: 'coffee', price:  1.95, label: 'Black Coffee'      }
    , { itemName: 'tea',    price: 11.95, label: 'Green Tea'         }
    , { itemName: 'beer',   price:  5.95, label: 'Corona Beer 12 oz' }
    , { itemName: 'milk',   price:  3.95, label: 'Chocolate Milk'    }
    ]
  }

const
  myForm = document.querySelector('#my-form-id')
, total  = document.querySelector('#total > em')

for (let menu in menuItems) // build the menu
  {
  let menuPart = document.createElement('fieldset') 
  menuPart.innerHTML = `<legend>${menu}</legend>`
  menuItems[menu].forEach(item=>
    {
    menuPart.innerHTML += `
        <label>
          <b>${item.label}</b>
          <input type="checkbox" name="${item.itemName}" value="${item.price}">
          <em>$ ${item.price}</em>
        </label>`
    })
  myForm.querySelector('.cols-3-parts').appendChild(menuPart)
  }
myForm.onsubmit = e =>
  {
  e.preventDefault() // disable submit while testing

  let inputJSON = Array.from(new FormData(myForm))
    .reduce((r,[name,value])=>{ r[name]= isNaN(value) ? value : Number(value); return r} ,{}) 
  console.log( JSON.stringify( inputJSON ))
  setTimeout(console.clear, 2000);
  }
myForm.onreset = e =>
  {
  total.textContent = '0.00'
  }
myForm.oninput = e =>
  {
  let  totalVal = 0;
  Array.from(new FormData(myForm))
    .forEach(([name,value])=> totalVal += isNaN(value) ? 0 : Number(value) ) 
    
  total.textContent = totalVal.toFixed(2)
  }
form#my-form-id {
  width   : 60em;
  padding : .4em;
  }
button {
  margin : 1em .4em 0 0;
  width  : 6em;
  }
.cols-3-parts {
  display   : flex;
  flex-wrap : wrap;
  }
.cols-3-parts fieldset {
  flex-grow : 1;
  width     : 30%;
  }
.cols-3-parts fieldset label {
  display : block;
  float   : left;
  clear   : left; 
  }
.cols-3-parts fieldset label b {
  display       : inline-block;
  width         : 11.4em;
  text-overflow : "";
  white-space   : nowrap;
  overflow      : hidden;
  }
.cols-3-parts fieldset label b::after {
  content     : '...............................';
  color       : grey;
  font-weight : normal;
  }
.cols-3-parts fieldset label input[type="checkbox"] {
  vertical-align: top;
  }
.cols-3-parts fieldset label em {
  font-size      : .8em;
  vertical-align : top;
  }
<h1>JOE'S FAMILY DINER</h1>

<form action="xx" id="my-form-id">
  <div class='cols-3-parts'> </div>

  <button type="submit">Submit</button>
  <button type="reset" >Reset</button>
</form>

<p id="total">
  Total : $ <em>0.00</em>
</p>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve every video on React.js channel from YouTube

Currently, I am working on integrating react-youtube into my React App with the goal of accessing all videos from a specific YouTube channel. The challenge I am facing is that I need to display these videos as thumbnails, exactly how they are listed in the ...

The dropdown menu vanishes from sight as soon as the cursor moves away from a link

Recently, I encountered an issue while trying to create a dropdown menu using Jquery. The problem arose when attempting to select the second link, as the entire menu would disappear. Additionally, is there a way to ensure that only one dropdown menu is vis ...

What is the best way to simulate an external class using jest?

My Vue page code looks like this: <template> // Button that triggers the submit method </template> <script> import { moveTo } from '@/lib/utils'; export default { components: { }, data() { }, methods: { async ...

Import JSON Data into Angular-nvD3 Chart (AngularJS)

I am seeking help to load encoded JSON Data retrieved from a database via queries into an Angular-nvD3 graph. I am unsure about the best approach to achieve this task. The encoded JSON data is fetched using API queries from a database table called PRODUCT ...

Tips for identifying and swapping values/parameters in a URL during redirect

To provide more clarity on my inquiry, I will outline the details below: There are three links: Link A, Link B, and Link C Link A: {c_val} Link B: {id} Link C: In the database, there is a value adgaf7g6adf6gadfg8a86fgs9f6g The main focus here is when ...

What could be causing my form to malfunction when attempting to submit data using Ajax and an external PHP script that is handling two string inputs?

Hello, I am facing an issue while trying to utilize Ajax to interact with a PHP file and submit both inputs (fullname and phonenumber). When I click the submit button, it simply refreshes the page without performing the desired action. Below is the code I ...

Modify the MUI time picker to display as a digital clock inside a DateTimePicker widget

I need to update my MUI DateTimePicker component to use the DigitalClock time picker instead of the Analog Clock picker. The current component has two steps, first picking the date from a calendar and then selecting the time. This change is only necessary ...

Aggregate the data entered into input fields on one page and display them on a separate page

Can you help me with this task? - I have 2 pages set up (page 1 has input fields & page 2 is where the entered data should be displayed) - I want to retrieve all the text input from the first field and insert it into the "content" tag on the second page. ...

Arranging a javascript object by organizing an array as a value

Looking to organize a JavaScript Object structured as key:pair, where the pair consists of an array with 2 timestamp values. The goal is to arrange the elements so that those with the smallest numbers (earliest times) are shown first. For instance, consid ...

retrieving embedded content from an iframe on Internet Explorer version 7

Need help with iframe content retrieval $('.theiframe').load(function(){ var content = $(this.contentDocument).find('pre').html(); } I'm facing an issue where the iframe content is retrieved properly in FF, Chrome, and IE 8,9 ...

AngularJS Default Option Selection

I am encountering some difficulties with the preselection of a select-input in angularJS. The select-box is being populated by an array. <select class="form-control" ng-model="userCtrl.selected_country" ng-options="country.name for country in userCt ...

Changing the Flash message to an Alert message in Symfony2: A step-by-step guide

I've encountered a problem where the success message from an action method in Symfony2 Controller appears as a flash message, but I need to display it as an alert or dialogue message according to requirements. I have attempted various solutions witho ...

Is the ng-style not displaying the background image with the interpolated value?

I have been attempting to update the background image of a div using angular ng-style. Below is the code I am working with: <div class="cover-image" ng-style="{'background-image' : 'url({{data.image}})'}"></div> However, ...

Using the JSON parameter in C# with MVC 3

I'm facing an issue with sending JSON data from a JavaScript function to a C# method using Ajax. When I receive the data in C#, it's not being recognized as JSON. How can I resolve this issue? If I try to output the received data using Response.W ...

The click function for the responsive navbar hamburger is not functioning properly

Having some trouble with the code not working in responsive mode. I've tested it on a 600px screen and the hamburger button doesn't seem to work (I click it and nothing happens). I've gone through both the CSS and JS multiple times but can&a ...

The Angular service/value is failing to retrieve the updated variable from the $(document).ready() function

Currently, I'm facing an issue with my Angular service/value. It seems to be grabbing the original variable instead of the new one that is supposed to be inside $(document).ready(). Here's the relevant code snippet: var app = angular.module("app ...

Identifying memory leaks caused by rxjs in Angular applications

Is there a specific tool or technique available to identify observables and subscriptions that have been left behind or are still active? I recently encountered a significant memory leak caused by components not being unsubscribed properly. I came across ...

The specified 'contactId' property cannot be found within the data type of 'any[]'

I am attempting to filter an array of objects named 'notes'. However, when I attempt this, I encounter the following error: Property 'contactId' does not exist on type 'any[]'. notes: Array < any > [] = []; currentNot ...

Step-by-step guide on displaying SVG text on a DOM element using Angular 8

I have a FusionChart graph that I need to extract the image from and display it on the same HTML page when the user clicks on the "Get SVG String" button. I am able to retrieve the SVG text using this.chart.getSVGString() method, but I'm unsure of ho ...

Difficulty encountered in resetting progress bar post ajax form submission

Hello, I hope you can assist me with an issue I am facing regarding my progress bar. After submitting the form using AJAX to insert data, my progress bar does not reset. I would like it to reset after clicking the submit button. The progress bar is speci ...