Calculating sum of checked checkboxes - javascript

I would like to calculate the sum of checked checkboxes and print the result to the form input value, but this code isn't working:
var calculator = document.querySelector("form");
function extras() {
var extrasPricing = new Array();
extrasPricing["candles"] = 5;
extrasPricing["inscription"] = 10;
extrasPricing["decoration"] = 25;
extrasPricing["special"] = 50;
var extrasCost = 0;
var extras = calculator.elements["extras"];
for (var i = 0; i < extras.length; i++) {
if (extras[i].checked) {
extrasCost = extrasCost + extrasPricing[extras[i].value];
break;
}
}
return extrasCost;
}
function calculateTotal() {
calculator.total.value = "$" + extras();
}
<form>
<fieldset>
<legend>Select Extras</legend>
<label><input type="checkbox" name="extras" value="candles" onclick="calculateTotal()">Candles</label><br>
<label><input type="checkbox" name="extras" value="inscription" onclick="calculateTotal()">Inscription</label><br>
<label><input type="checkbox" name="extras" value="decoration" onclick="calculateTotal()">Decoration</label><br>
<label><input type="checkbox" name="extras" value="special" onclick="calculateTotal()">Special Frosting & Icing</label>
</fieldset>
<input type="text" name="total" readonly>
<input type="submit" value="Submit">
</form>
What am I doing wrong while performing the calculation?

You seem to be coming from PHP.
There are several issues with your code.
In JavaScript, several data structures exist either as primitives or objects. In the case of the array, this is the primitive:
var anArray = [];
and this is the object:
var anArray = new Array();
when both exist, you should never use the object. It should only ever be used internally.
Also, JavaScript does not have associative arrays or dictionaries. It only has what it calls objects. Under the hood, they're the same thing, but what that means is:
colors["blue"]
and
colors.blue
are the same thing. When the second is possible, which is not always the case, the second form is preferred.
Now, for your HTML.
Don't use name. name is obsolete. Use either class or id. Here, you could use class, but really, you don't need to. Putting an id on the fieldset element would probably be enough to get to your input elements.
You should not write JavaScript inside of HTML. There are many solutions to that problem. The simplest is to simply use jQuery. If you do, it will be jQuery that will attach the callback to your HTML to keep the HML and JavaScript nice and separate. An ever better approach would be to use an even more complete framework such as React, Vue or Angular, but those can be more difficult to learn that can be overkill for now.
So, let's try jQuery instead.
Try this on for size: https://jsfiddle.net/8tf25zw9/3/

Remove the break which will stop the for loop. Your for loop is only going to get the value of the first checked checkbox that way. Your logic is flawed; just because you have found one checked checkbox does not mean that your calculations are finished. You need to add the values of all the checked checkboxes.
var calculator = document.querySelector("form");
function extras() {
var extrasPricing = new Array();
extrasPricing["candles"] = 5;
extrasPricing["inscription"] = 10;
extrasPricing["decoration"] = 25;
extrasPricing["special"] = 50;
var extrasCost = 0;
var extras = calculator.elements["extras"];
for (var i = 0; i < extras.length; i++) {
if (extras[i].checked) {
extrasCost = extrasCost + extrasPricing[extras[i].value];
//Do not break here
}
}
return extrasCost;
}
function calculateTotal() {
calculator.total.value = "$" + extras();
}
<form>
<fieldset>
<legend>Select Extras</legend>
<label><input type="checkbox" name="extras" value="candles" onclick="calculateTotal()">Candles</label><br>
<label><input type="checkbox" name="extras" value="inscription" onclick="calculateTotal()">Inscription</label><br>
<label><input type="checkbox" name="extras" value="decoration" onclick="calculateTotal()">Decoration</label><br>
<label><input type="checkbox" name="extras" value="special" onclick="calculateTotal()">Special Frosting & Icing</label>
</fieldset>
<input type="text" name="total" readonly>
<input type="submit" value="Submit">
</form>

Here's a working example of your code. There were a few syntax errors as well noted above by eje211.
var calculator = document.querySelector("form");
function extras() {
// Object vs Array
var extrasPricing = {
candles: 5,
inscription: 10,
decoration: 25,
special: 50
}
var extrasCost = 0;
var extras = document.getElementsByName("extras");
for (var i = 0; i < extras.length; i++) {
if (extras[i].checked) {
var val = extras[i].value;
// Update here to add/remove value of checked item to previous checked item.
extrasCost += extrasPricing[val];
}
}
return extrasCost;
}
function calculateTotal() {
calculator.total.value = "$" + extras();
}
<form>
<fieldset>
<legend>Select Extras</legend>
<label><input type="checkbox" name="extras" value="candles" onclick="calculateTotal()">Candles</label><br>
<label><input type="checkbox" name="extras" value="inscription" onclick="calculateTotal()">Inscription</label><br>
<label><input type="checkbox" name="extras" value="decoration" onclick="calculateTotal()">Decoration</label><br>
<label><input type="checkbox" name="extras" value="special" onclick="calculateTotal()">Special Frosting & Icing</label>
</fieldset>
<input type="text" name="total">
<input type="submit" value="Submit">
</form>

As noted by others, your extrasPricing does need to be an object to more easily access it. You can also you documentQuerySelectorAll with your CSS selectors to select your checked elements.
The '...' is a spread operator that converts a NodeList (which is returned with documentQuerySelectorAll) to an array, which is then able to use the various array methods to map the values to a new array, then reduce the values to a total.
Reduce throws an error if the array is empty, so the ternary operator is used to return the reduce output if the array has an element (extrasCost.length > 0), or to return 0 if the array is empty.
function extras() {
const extrasPricing = {
candles: 5,
inscription: 10,
decoration: 25,
special: 50,
};
let extrasCost = [...document.querySelectorAll('input[name=extras]:checked')]
.map((el) => extrasPricing[el.value])
return extrasCost.length > 0 ? extrasCost.reduce((total, num) => total + num) : 0;
}
function calculateTotal() {
calculator.total.value = '$' + extras();
}
<form>
<fieldset>
<legend>Select Extras</legend>
<label><input type="checkbox" name="extras" value="candles" onclick="calculateTotal()">Candles</label><br>
<label><input type="checkbox" name="extras" value="inscription" onclick="calculateTotal()">Inscription</label><br>
<label><input type="checkbox" name="extras" value="decoration" onclick="calculateTotal()">Decoration</label><br>
<label><input type="checkbox" name="extras" value="special" onclick="calculateTotal()">Special Frosting & Icing</label>
</fieldset>
<input type="text" name="total">
<input type="submit" value="Submit">
</form>

Related

Get value of checkbox and display it in specific format

I am trying to get the checked value in checkbox and display it in some specific format using javascript but somehow I dont know how to do it
I have tried html and javascript and I dont know ajax or jquery so I am trying javascript only
function Hobby()
{
var checkedValue = null;
var inputElements = document.getElementsByClass('messageCheckbox');
for(var i=0; inputElements[i]; ++i){
if(inputElements[i].checked){
checkedValue = inputElements[i].value
document.getElementById("hobbies_value").innerHTML = inputElements;
break;
}
}
}
Hobby <input class="messageCheckbox" type="checkbox" name="painting" id="painting" value="painting">Painting
<input class="messageCheckbox" type="checkbox" name="dancing" id="dancing" value="dancing">Dancing
<input class="messageCheckbox" type="checkbox" name="sports " id="sports " value="sports ">Sports
<input type="button" value="student_submit" onclick="Hobby()"><br/>
If checked values are dancing and painting
then output should be
Hobby:#dancing#painting
and I dont want to display it as alert box instead I want to display it on same page
You need to concatenate the values and display them outside the loop. Something like this:
function Hobby()
{
var checkedValue = "";
var inputElements = document.getElementsByClassName('messageCheckbox');
for(var i=0; inputElements[i]; ++i){
if(inputElements[i].checked){
checkedValue += "#"+inputElements[i].value
}
}
document.getElementById("hobbies_value").innerHTML = checkedValue;
}
Hobby <input class="messageCheckbox" type="checkbox" name="painting" id="painting" value="painting">Painting
<input class="messageCheckbox" type="checkbox" name="dancing" id="dancing" value="dancing">Dancing
<input class="messageCheckbox" type="checkbox" name="sports " id="sports " value="sports ">Sports
<input type="button" value="student_submit" onclick="Hobby()"><br/>
Javascript code is
<div id="hobbies_value"></div>

merging checkbox selection into appendChild

I'm currently creating a Checkbox and trying to append the selections to a function.
This is what I currently have :
<input type="checkbox" id="Animal" value="Animal" name="langs" checked><label for="UW">UW</label><br>
<input type="checkbox" id="Vegatable" value="Vegetable" name="langs"><label for="OIB">OIB</label><br>
<input type="text" id="Other" value="N/A" name="langs" style="font-size:10px;" style="width: 125px;" /><label for="Other">Other</label><br>
This is what I currently have for the Appendchild Result:
<tr name="checkbox_value"><th>Systems Used: </th>
</tr>
I'm using the option Document.getElementId but I can't get multiple result or a single result
var SysRow = document.getElementById("checkbox_value");
var td4 = document.createElement("td");
td4.innerHTML = document.getElementById("langs").value;
SysRow.appendChild(td4);
from my understanding i can use document.getElementsByClassName() or document.querySelectorAll() but I'm not sure how to implement it .
What if the person selects multiple results like "Animal" and "Vegetable".
Use this code:
var items=document.getElementsByClassName('appendInput');
var checkedItems ="";
for(var i=0; i<items.length; i++){
if(items[i].type=='checkbox' && items[i].checked)
checkedItems+=items[i].value+" ";
}
document.getElementById('result').innerHTML = checkedItems;
<input class="appendInput" type="checkbox" name="langs" value="Animal" checked>
<input class="appendInput" type="checkbox" name="langs" value="Vegetable" checked>
<input class="appendInput" type="checkbox" name="langs" value="N/A">
<div id="result"></div>
Add a class on the elements that you want to append
<input class="toappend" type="text" name="element_1">
<input class="toappend" type="text" name="element_2">
<input class="toappend" type="text" name="element_3">
Then in JS
var allElements = document.querySelectorAll('.toappend');
allElements will become nodeList then you can pass it in the function
function yourFunction(elements) {
// If you want to use forEach method, you have to convert the nodeList to an Array
//ES5
var arrElements = Array.prototype.slice.call(elements);
//ES6
let arrElements = Array.from(elements);
arrElements.forEach(function(currentEl, index, array) {
var appendTo = document.querySelector('#checkbox_value');
appendTo.insertAdjacentHTML('beforeend', currentEl.outerHTML);
});
}
Check this pen

How to display value using radio buttons in javascript and add it with checkboxes value?

I'm trying to add the radio button and the checkboxes, but I'm either getting a nan value from the checkboxes or nothing is displayed if I add them both. I'm not sure why I am not getting the answer I thought I've understood through my code, especially on javascript.
function calculatePrice() {
var i;
var resultmessage = "";
var pizzamount = parseFloat(0);
var radval;
var radval2;
var chckbox;
var totalvalue = parseInt(0);
for (i = 0; i < document.cost.typed.length; i++) {
if (document.cost.typed[i].checked) {
radval = document.i.typed[i].value;
}
}
if (document.cost.cheese.checked) {
pizzamount += 150 / 100;
}
if (document.cost.pepperoni.checked) {
pizzamount += 150 / 100;
}
radval = parseFloat(radval);
pizzamount = parseFloat(pizzamount)
var resultmessage = "Total cost: $" + pizzamount;
document.getElementById("result").innerHTML = resultmessage;
}
<form name="cost" autocomplete="on">
<table class="left" border="1px">
<tr>
<th>
Choose a Pizza Size
</th>
</tr>
<tr>
<td>
<input type="radio" name="typed" value="18" checked>Extra Large
<br>
<input type="radio" name="typed" value="15">Large
<br>
<input type="radio" name="typed" value="10">Medium
<br>
<input type="radio" name="typed" value="8">Small
<br>
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="cheese" checked>Extra Cheese<br>
<input type="checkbox" name="pepperoni">Pepperoni<br>
</td>
</tr>
</table>
<input type="button" value="Place Order" onClick="calculatePrice()">
</form>
Made a few small changes, but largely cosmetic -- firstly, note that I'm still storing the check and radio as variables, and accessing them. But when I use the radio, I simply use that to get the size, then (using its index) reference the price/size array to get the actual pizza price. Other than that, it's working exactly the same.
calculatePrice = function calculatePrice() {
var resultmessage = "";
var pizzamount = parseFloat(0);
var radval;
var radval2;
var chckbox;
var totalValue = parseInt(0);
var priceTable = [
{
size: "18",
price: 12.00
}, {
size: "15",
price: 10.75
}, {
size: "10",
price: 9.90
}, {
size: "8",
price: 9.25
}];
var size = document.getElementsByName("size");
var extras = document.getElementsByName("extras");
// First, calculate the size. This is a radio, so
// we should only get one value.
for (var i=0; i<size.length; i++) {
if(size[i].checked){
radVal = priceTable[i].size;
totalValue += priceTable[i].price;
}
}
// next, the extras. This may be multiple options
for (var i=0; i<extras.length; i++) {
if (extras[i].checked) {
totalValue += (150/100);
}
}
//radval = parseFloat(radval);
totalValue = parseFloat(totalValue);
var resultmessage = "Total cost: $" + totalValue;
document.getElementsByClassName("running-total")[0].innerHTML = resultmessage;
}
label {
font-weight: bold;
display: block;
}
form {
width: 250px;
border: 1px dotted green;
}
<form name="cost" autocomplete="on">
<fieldset>
<label for="size">Choose a Pizza Size:</label>
<input type="radio" name="size" value="18" checked>Extra Large
<input type="radio" name="size" value="15">Large
<input type="radio" name="size" value="10">Medium
<input type="radio" name="size" value="8">Small
</fieldset>
<fieldset>
<label for="specials">Pizza Special:</label>
</fieldset>
<fieldset>
<label for="extras">Extras:</label>
<input type="checkbox" name="extras" value="cheese">Cheese
<input type="checkbox" name="extras" value="pepperoni">Pepperoni
</fieldset>
<input type="button" onClick="calculatePrice()" value="Calculate Price!" /> <span class="running-total"></span>
</form>
Your html is incomplete. You don't have the specials or extras columns filled out, and you have some pizza sizes on there twice.
What you'll want to do is have things that you cannot have more than one of as a set of radio buttons (e.g. pizza sizes), and things you can have multiple of as a set of check boxes.
Then, you need to iterate through each checkbox and radio button to see if it's checked, and if it is, add it's value to the total.
It will also make it easier to work with if you add a border to the table and it's children.
I wasn't really able to make much sense of the code you had, so I hope that you find this helpful.

Javascript taking .innerHTML on indexOf checked

I have a variable named 'options'. Whenever a user checks one of the checkboxes, I need 'options' to populate the string with the .innerHTML for each checked checkbox. For example, when Instagram and Google+ are checked, 'options' would = Instagram, Google+.
html:
<section id="extra-features">
<div class="span3">
<label class="checkbox" for="Checkbox1">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> Instagram
</label>
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> Review site monitoring
</label>
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> Google+
</label>
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> LinkedIn
</label>
</div>
<div class="span3">
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> Pinterest
</label>
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> FourSquare
</label>
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> Tumblr
</label>
<label class="checkbox">
<input type="checkbox" class="sum" value="50" data-toggle="checkbox"> Advertising
</label>
</div>
</section>
<div class="card-charge-info">
Your card will be charged $<span id="payment-total">0</span> now, and your subscription will bill $<span id="payment-rebill">0</span> every month thereafter. You can cancel or change plans anytime.
</div>
javascript:
var price = 0,
additional = 0,
options = "",
inputs = document.getElementsByClassName('sum'),
total = document.getElementById('payment-total'),
total2 = document.getElementById('payment-rebill');
for (var i=0; i < inputs.length; i++) {
inputs[i].onchange = function() {
var add = this.value * (this.parentNode.className.split(" ").indexOf("checked") > -1 ? 1 : -1);
additional += add
total.innerHTML = price + additional;
if (price == select.options[2].value) {
total2.innerHTML = 0;
}
else {
total2.innerHTML = price + additional;
}
}
}
JSFiddle: http://jsfiddle.net/rynslmns/LQpHQ/
I would recommend tabulating the information each time they change a check state. What you're doing now is problematic; currently you start at 0, but end up being in the negative (total price) quickly by checking and unchecking a couple of options.
Also, options, as a string, will become difficult to keep up with. I'd probbaly make that an array that you can add/remove from (but if you tabulate at the end, there's no worrying).
For example:
var inputs = document.getElementsByClassName('sum'),
total = document.getElementById('payment-total'),
total2 = document.getElementById('payment-rebill');
// Perform the summing
// Though I'm not sure where total is coming from, but you can work that out.
// And for now I have it alerting the options, but you can do whatever you'd like with that.
function sumItUp(){
var ttl = 0, additional = 0, options = [];
for (var i = 0; i < inputs.length; i++){
if (inputs[i].checked){
options.push(inputs[i].parentNode.textContent.trim());
var n = new Number(inputs[i].value);
if (!isNaN(n)) additional += n;
}
}
total.innerHTML = ttl.toFixed(2);
total2.innerHTML = (ttl + additional).toFixed(2);
alert('Options:\n\n' + options.join(', '));
}
// bind events to sum it on every change
for (var i = 0; i < inputs.length; i++){
inputs[i].addEventListener('change', sumItUp);
}
// Polyfill for trim()
if (!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g,'');
};
}
jsFiddle
You won't be able to use .innerHTML to get the text of the checkbox since it doesn't contain any text. You'll want to use .nextSibling instead. Something like this should work:
var price = 0,
additional = 0,
options = "",
inputs = document.getElementsByClassName('sum'),
total = document.getElementById('payment-total'),
total2 = document.getElementById('payment-rebill');
for (var i=0; i < inputs.length; i++) {
inputs[i].onchange = function() {
var text = this.nextSibling.nodeValue;
if(options.indexOf(text) != -1) {
options += text + ',';
}
}
}
Of course you'd also want to handle when a checkbox is unselected as well.

How to validate for checkbox selection if all checkbox have same name?

Hi All
I have a group of check box having same name so as to get the array of single variable when it is posted on serverside for exampleL
<input type="checkbox" name="midlevelusers[]" value="1">
<input type="checkbox" name="midlevelusers[]" value="1">
<input type="checkbox" name="midlevelusers[]" value="1">
<input type="checkbox" name="midlevelusers[]" value="1">
I need a javascript validation to check whether any checkbox is selected or not?
Thanks and Regards
NOTE: I need javascript validation
You can access the DOM elements and check their checked property. For instance:
var list, index, item, checkedCount;
checkedCount = 0;
list = document.getElementsByTagName('input');
for (index = 0; index < list.length; ++index) {
item = list[index];
if (item.getAttribute('type') === "checkbox"
&& item.checked
&& item.name === "midlevelusers[]") {
++checkedCount;
}
}
Live example
There we're looking through the whole document, which may not be efficient. If you have a container around these (and presumably you do, a form element), then you can give that element an ID and then look only within it (only the var, form =, and list = lines are new/different):
var form, list, index, item, checkedCount;
checkedCount = 0;
form = document.getElementById('theForm');
list = form.getElementsByTagName('input');
for (index = 0; index < list.length; ++index) {
item = list[index];
if (item.getAttribute('type') === "checkbox"
&& item.checked
&& item.name === "midlevelusers[]") {
++checkedCount;
}
}
Live example
Off-topic: You haven't mentioned using a library, so I haven't used one above, but FWIW this stuff is much easier if you use one like jQuery, Prototype, YUI, Closure, or any of several others. For instance, with jQuery:
var checkedCount = $("input[type=checkbox][name^=midlevelusers]:checked").length;
Live example Other libraries will be similar, though the details will vary.
<form name="myform" method="POST" action="" onsubmit="return checkTheBox();">
<input type="checkbox" name="midlevelusers[]" value="1" /> 1
<input type="checkbox" name="midlevelusers[]" value="2" /> 2
<input type="checkbox" name="midlevelusers[]" value="3" /> 3
<input type="checkbox" name="midlevelusers[]" value="4" /> 4
<input type="checkbox" name="midlevelusers[]" value="5" /> 5
<input type="submit" value="Submit Form" />
</form>
<script type="text/javascript">
function checkTheBox() {
var flag = 0;
for (var i = 0; i< 5; i++) {
if(document.myform["midlevelusers[]"][i].checked){
flag ++;
}
}
if (flag != 1) {
alert ("You must check one and only one checkbox!");
return false;
}
return true;
}
</script>
try,
function validate() {
var chk = document.getElementsByName('midlevelusers[]')
var len = chk.length
for(i=0;i<len;i++)
{
if(chk[i].checked){
return true;
}
}
return false;
}
use id's
<input type="checkbox" name="midlevelusers[]" id="mlu1" value="1">
<input type="checkbox" name="midlevelusers[]" id="mlu2" value="2">
<input type="checkbox" name="midlevelusers[]" id="mlu3" value="3">
<input type="checkbox" name="midlevelusers[]" id="mlu4" value="4">
now you can do
for (var i=1;i<5;i++){
var el = document.getElementById('mlu'+i);
if (el.checked) { /* do something */}
}
This function would alert whether or not a checkbox has any values checked.
function isChecked(checkboxarray){
for (counter = 0; counter < checkboxarray.length; counter++){
if (checkboxarray[counter].checked){
alert("Checkbox has at least one checked");
else{
alert("None checked");
}
You would need to add a bit more to do what you actually want to do with it but that will get you on the right track I think!
You could use jQuery and do it this way:
if($('input[name="light[]"]:checked').length < 1){
alert("Please enter the light conditions");
}

Categories