Javascript taking .innerHTML on indexOf checked - javascript

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.

Related

How get the sum of all the checkbox values of checked items

let addonCheckboxes = document.querySelectorAll(".custom-checkbox")
let priceSection = document.getElementById("priceSection")
let customProductPricing = document.getElementById("customProductPricing")
for (let i = 0; i < addonCheckboxes.length; i++) {
addonCheckboxes[i].addEventListener("change", function() {
if (addonCheckboxes[i].checked != false) {
priceSection.textContent = parseInt(customProductPricing) + parseInt(addonCheckboxes[i].getAttribute("price"));
} else {
priceSection.textContent = parseInt(customProductPricing)
}
})
}
<input class="custom-checkbox" type="checkbox" price="150"></input>
<input class="custom-checkbox" type="checkbox" price="150"></input>
<input class="custom-checkbox" type="checkbox" price="150"></input>
<div id="priceSection">
</id>
<div id="customProductPricing">"150"</div>
I want to get the total of all the checkboxes if they are all checked. So far it gives only one value. And need to deduct the prices if the checkbox is unchecked.
This one has fixed all the errors you made in your markup, and simplified the code by alot.
const output = document.getElementById('priceSection');
const totalPrice = () => [...document.querySelectorAll('#prices input[type=checkbox]:checked')]
.reduce((acc, {
dataset: {
price
}
}) => acc + +price, 0);
document.getElementById('prices').addEventListener('change', () => output.textContent = totalPrice());
<div id="prices">
<input type="checkbox" data-price="10" />
<input type="checkbox" data-price="20" />
<input type="checkbox" data-price="30" />
</div>
<div id="priceSection"></div>
You are overwriting instead of summing. When you are iterating through an array of checkboxes and you find that more than one is checked your function fails.
You should firstly count the sum of checked checkboxes and then send it to priceSection, and when your sum is equal to zero you should set it parseInt(customProductPricing) like you did in else.
When the change event of the <input> elements is triggered, the update() method is called and the values in the page are collected and printed on the page. I don't understand the issue of lowering the price if the checkbox is not selected. Update the update() method to subtract unselected values from the total using the following approach; Add an else statement to the if block.
(function() {
let addonCheckboxes = document.querySelectorAll(".custom-checkbox");
function update()
{
let total = parseInt(document.getElementById("customProductPricing").textContent);
for(let i = 0 ; i < addonCheckboxes.length ; ++i)
if(addonCheckboxes[i].checked == true)
total += parseInt(addonCheckboxes[i].value);
document.getElementById("priceSection").innerHTML = "Result: " + total;
}
for(let i = 0 ; i < addonCheckboxes.length ; ++i)
addonCheckboxes[i].addEventListener("change", update);
})();
<input class="custom-checkbox" type="checkbox" value="10"/>
<label>10</label>
<input class="custom-checkbox" type="checkbox" value="20"/>
<label>20<label>
<input class="custom-checkbox" type="checkbox" value="30"/>
<label>30<label>
<!-- Static Value -->
<div id="customProductPricing">40</div>
<br><div id="priceSection" style="color: red;">Result: </div>
Using data set you can access price
let addonCheckboxes = document.querySelectorAll(".custom-checkbox")
let priceSection = document.getElementById("priceSection")
let customProductPricing = document.getElementById("customProductPricing")
let sum = 0
for (let i = 0; i < addonCheckboxes.length; i++) {
addonCheckboxes[i].addEventListener("change", function(e) {
console.log(e.target.dataset.price)
if (addonCheckboxes[i].checked != false) {
sum = sum +Number(e.target.dataset.price)
} else {
sum = sum -Number(e.target.dataset.price)
}
customProductPricing.innerHTML = sum
})
}
<input class="custom-checkbox" type="checkbox" data-price="150"></input>
<input class="custom-checkbox" type="checkbox" data-price="150"></input>
<input class="custom-checkbox" type="checkbox" data-price="150"></input>
<div id="priceSection">
</id>
<div id="customProductPricing">"150"</div>
As #Sercan has mentioned... I am also not sure about the issue of loweing the sum but I've whipped up something for you.
Hopefully it'll lead you to what you want to achieve.
let addonCheckboxes = document.querySelectorAll(".custom-checkbox")
let priceSection = document.getElementById("priceSection")
let customProductPricing = document.getElementById("customProductPricing");
var checkboxes = document.getElementsByClassName("custom-checkbox");
function sum(){
var total = 0;
for(let x = 0; x < checkboxes.length; x++){
let price = document.getElementsByClassName(x);
if(price[0].checked){
total = total + Number(price[0].dataset.price);
}
}
console.log('Sum = ' + total)
}
<input class="custom-checkbox 0" onclick="sum()" type="checkbox" data-price="150"></input>
<input class="custom-checkbox 1" onclick="sum()" type="checkbox" data-price="150"></input>
<input class="custom-checkbox 2" onclick="sum()" type="checkbox" data-price="150"></input>
<div id="priceSection"></id>
<div id="customProductPricing">"150"</div>

How to add a display a total value of the checkbox that are checked

I'm trying to display a total value of all the checkboxes that are checked
I've tried only this solution
my description is quite precise and self-explanatory
Javascript function
How to display the total of all checkboxes that are checked. Trying to display the total price by calculating all the checkboxes that are checked.
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>On the go</title>
<link rel="stylesheet" type="text/css" href="menu.scss">
<script>
function calcAndShowTotal() { **
* // declaring the name and total***
var hotbeverage = document.querySelectorAll('input[name="hotbeverage"]');
var total = 0; **
* // checking if any checkboxes have been selected***
for (i = 0; i < hotbeverage.length; i++) { **
* // if the checkbox is selected add the value to total***
if (hotbeverage[i].checked) {
total = total + hotbeverage[i].value;
}
document.getElementById("amount").value = "You order total is R" + total;
}
</script>
***// adding checkboxes***
</head>
<body>
<h1>Hot Beverages</h1>
<div id="pricelist">
<input type="checkbox" name="hotbeverage" value="item1" price="25.00">Americano <b>R25.00</b><br>
<input type="checkbox" name="hotbeverage" value="item2" price="2">Caffe Latte <b>R30.00</b><br>
<input type="checkbox" name="hotbeverage" value="item3" price="3">Cappuccino <b>R15.00</b><br>
<input type="checkbox" name="hotbeverage" value="item4" price="4">Hot Chocolate<b>R20.00</b><br>
<input type="checkbox" name="hotbeverage" value="item5" price="5">Chai Latte <b>R20.00</b><br>
<input type="checkbox" name="hotbeverage" value="item6" price="6">ButterScotch latte<b>R28.00</b><br>
<input type="text" id="amount" value="0" />
</div>
</body>
</html>
I want the text field to populate with the value
The main problem comes when you're trying to calculate the value of the input when the real value is in the price attribute, so you can change .value by .getAttribute('price').
NOTE: It's always better to use data-* attribute when you need a custom attribute, so data-price will be more efficient, then you can get the value like :
parseFloat( hotbeverage[i].dataset.price );
document.querySelector('#calc').addEventListener('click', calcAndShowTotal);
function calcAndShowTotal() {
var hotbeverage = document.querySelectorAll('input[name="hotbeverage"]');
var total = 0;
for (i = 0; i < hotbeverage.length; i++) {
if (hotbeverage[i].checked) {
total += parseFloat( hotbeverage[i].getAttribute('price') );
}
}
document.getElementById("amount").value = "You order total is R " + total;
}
<h1>Hot Beverages</h1>
<div id="pricelist">
<input type="checkbox" name="hotbeverage" value="item1" price="25.00">Americano <b>R25.00</b><br>
<input type="checkbox" name="hotbeverage" value="item2" price="2">Caffe Latte <b>R30.00</b><br>
<input type="checkbox" name="hotbeverage" value="item3" price="3">Cappuccino <b>R15.00</b><br>
<input type="checkbox" name="hotbeverage" value="item4" price="4">Hot Chocolate<b>R20.00</b><br>
<input type="checkbox" name="hotbeverage" value="item5" price="5">Chai Latte <b>R20.00</b><br>
<input type="checkbox" name="hotbeverage" value="item6" price="6">ButterScotch latte<b>R28.00</b><br>
<input type="text" id="amount" value="0" />
</div>
<button id="calc">Calculate</button>
To display the total of all checkboxes that are checked and display the total price by calculating all the checkboxes that are checked you can use following code:
html tag:
test 1
test 2
test 3
test 4
javaScript code:
jQuery(document).ready(function($) {
var sum = 0;
$('#pakker :checkbox').click(function() {
sum = 0;
$('#pakker :checkbox:checked').each(function(idx, elm) {
sum += parseInt(elm.value, 10);
});
$('#sum').html(sum);
});
});
Please also refer following link for more details.
http://jsfiddle.net/vaKWs/6/
Following are mistakes in the code:
You are not calling the function calcAndShowTotal. You should attach event to all the checkboxes to see change.
You are adding value but you should add its price. Use getAttribute to checkbox's price.
In your loop you are declaring global variable i. Use let before it.
let hotbeverage = document.querySelectorAll('input[name="hotbeverage"]');
hotbeverage.forEach(x => {
x.addEventListener('change',calcAndShowTotal)
})
function calcAndShowTotal() {
// declaring the name and total***
var total = 0;
// checking if any checkboxes have been selected***
for (let i = 0; i < hotbeverage.length; i++) {
// if the checkbox is selected add the value to total***
if (hotbeverage[i].checked) {
total = total + (+hotbeverage[i].getAttribute('price'))
}
document.getElementById("amount").value = "You order total is R" + total;
}
}
<h1>Hot Beverages</h1>
<div id="pricelist">
<input type="checkbox" name="hotbeverage" value="item1" price="25.00">Americano <b>R25.00</b><br>
<input type="checkbox" name="hotbeverage" value="item2" price="2">Caffe Latte <b>R30.00</b><br>
<input type="checkbox" name="hotbeverage" value="item3" price="3">Cappuccino <b>R15.00</b><br>
<input type="checkbox" name="hotbeverage" value="item4" price="4">Hot Chocolate<b>R20.00</b><br>
<input type="checkbox" name="hotbeverage" value="item5" price="5">Chai Latte <b>R20.00</b><br>
<input type="checkbox" name="hotbeverage" value="item6" price="6">ButterScotch latte<b>R28.00</b><br>
<input type="text" id="amount" value="0" />
</div>

Calculating sum of checked checkboxes

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>

Function to set textarea value - additional runs through append data instead of replace it

I have a textarea, whose value I want to set with a function. When I first click the button to set the value, the value populates correctly.
If I then click the button to set the value again, using a different option from the list of radio buttons, the value in the textarea is not cleared and replaced with the new data - data resultiing from the logic in the JS code is appended to the data in the textarea, instead of replacing what is already there.
I have tried to clear the textarea value with:
document.getElementById("output").value = '';
But that doesn't clear it.
HTML:
<label class="radio-inline">
<input type="radio" name="myArray" id="radioActivity" value="valActivity"> Activity
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioFlags" value="arrFlags"> Flags
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioFood" value="arrFood"> Food
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioNature" value="arrNature"> Nature
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioObjects" value="arrObjects"> Objects
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioPeople" value="arrPeople"> People
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioLetters" value="arrLetters"> Letters
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioSymbols" value="arrSymbols"> Symbols
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioTravel" value="arrTravel"> Travel
</label>
<input type="text" class="form-control" id="itemSet" value="10" />
<button id="rdio"> Check Radio </button>
<textarea id="output" class="form-control" style="width:95%; height:500px; margin-top:20px;"></textarea>
JS:
var myCols = 2;
var arrActivity = ["alien monster","man in business suit levitating","fencer","horse racing","skier","snowboarder","golfer","surfer","rowboat","swimmer"];
var arrFlags = ["ascension","andorra","the united arab emirates","afghanistan","antigua and barbuda","anguilla","albania","armenia","angola","antarctica"];
var arrFood = ["grapes","melon","watermelon","tangerine","lemon","banana","pineapple","red apple","green apple","pear"];
var arrNature = ["see-no-evil monkey","hear-no-evil monkey","speak-no-evil monkey","splashing sweat symbol","dash symbol","monkey face","monkey","gorilla","dog face","dog"];
var arrObjects = ["skull and crossbones","love letter","bomb","hole","shopping bags","prayer beads","gem stone","hocho","amphora","world map"];
var arrPeople = ["grinning face","grinning face with smiling eyes","face with tears of joy","rolling on the floor laughing","smiling face with open mouth","smiling face with open mouth and smiling eyes","smiling face with open mouth and cold sweat","smiling face with open mouth and tightly-closed eyes","winking face","smiling face with smiling eyes"];
var arrLetters = ["letter a","letter b","letter c","letter d","letter e","letter f","letter g","letter h","letter i","letter j"];
var arrSymbols = ["eye in speech bubble","heart with arrow","heavy black heart","beating heart","broken heart","two hearts","sparkling heart","growing heart","blue heart","green heart"];
var arrTravel = ["racing car","racing motorcycle","silhouette of japan","snow capped mountain","mountain","volcano","mount fuji","camping","beach with umbrella","desert"];
var arrNew = [];
function boom()
{
if (document.getElementById("radioActivity").checked) {
y = arrActivity;
} else if(document.getElementById("radioFlags").checked) {
y = arrFlags;
} else if (document.getElementById("radioFood").checked) {
y = arrFood;
} else if (document.getElementById("radioNature").checked) {
y = arrNature;
} else if (document.getElementById("radioObjects").checked) {
y = arrObjects;
} else if (document.getElementById("radioPeople").checked) {
y = arrPeople;
} else if (document.getElementById("radioLetters").checked) {
y = arrLetters;
} else if (document.getElementById("radioSymbols").checked) {
y = arrSymbols;
} else if (document.getElementById("radioTravel").checked) {
y = arrTravel;
}
for (var i = 0; i < y.length; i+=myCols) {
arrNew.push(
y.slice(i, i+myCols)
);
}
// attempts to clear the output...
// op = '';
document.getElementById("output").value = '';
// set the textarea output
op = JSON.stringify(arrNew, null, 4);
document.getElementById('output').value = op;
}
var z = document.getElementById('rdio');
z.addEventListener("click", boom);
Codepen to show issue:
https://codepen.io/paperknees/pen/JrgNzp
arrNew should be declared as an empty array inside the function call every time.
function boom() {
var arrNew = [];
...

A function that collects an array of numbers as a parameter and returns an array of percentages?

I'm currently a beginner and trying to understand how to basically use a function get an array of the numbers from each input to then figure out how to make an individual percentage for each candidate. In the JS, using that to get the total but is there a way to get each individual number from each input somehow? Maybe I'm going into a wrong direction with my for loop :/ Any direction or hints would be great.
<div>
<label for="votes1">Votes for Candidate 1</label>
<input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
</div>
<div>
<label for="votes2">Votes for Candidate 2</label>
<input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
</div>
<div>
<label for="votes3">Votes for Candidate 3</label>
<input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
</div>
<output id="totalvotes"></output>
Here's the JS for it
function totalVotes() {
var votes = document.getElementsByName("votesPerPerson");
var totalVotes = 0;
for( var i = 0; i < votes.length; i ++ ) {
totalVotes += parseInt(votes[i].value);
}
document.getElementById("totalvotes").innerHTML = totalVotes;
}
Looks like you have a good grasp of getting the sum. To create an array, there's several ways you can do that but I recommend mapping it from the collection of elements like this:
function totalVotes() {
var votes = document.getElementsByName("votesPerPerson");
var total = document.getElementById("totalvotes");
// create new array
var percentages = [];
var totalVotes = 0;
// reset innerHTML in case loop returns early due to invalid value
total.innerHTML = "";
// reset each vote percentage
for (var i = 0; i < votes.length; i++) {
votes[i].nextElementSibling.innerHTML = "";
}
// overwrite each index with value
for (var i = 0; i < votes.length; i++) {
totalVotes += percentages[i] = parseInt(votes[i].value);
// one of the values is invalid
if (isNaN(percentages[i])) return;
}
total.innerHTML = totalVotes;
// calculate percentages here by mapping array of votes
for (var i = 0; i < percentages.length; i++) {
percentages[i] = 100 * percentages[i] / totalVotes;
votes[i].nextElementSibling.innerHTML = percentages[i].toFixed(2) + "%";
}
}
document.addEventListener('change', totalVotes)
<div>
<label for="votes1">Votes for Candidate 1</label>
<input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
<output></output>
</div>
<div>
<label for="votes2">Votes for Candidate 2</label>
<input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
<output></output>
</div>
<div>
<label for="votes3">Votes for Candidate 3</label>
<input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
<output></output>
</div>
<output id="totalvotes"></output>
function totalVotes() {
var votes = document.getElementsByName("votesPerPerson");
var totalVotes = 0;
var percentages = [];
for( var i = 0; i < votes.length; i ++ ) {
totalVotes += parseInt(votes[i].value);
percentages[i] = parseInt(votes[i].value);
}
percentages = percentages.map(function(candidateVotes) {return candidateVotes/totalVotes;});
document.getElementById("totalvotes").innerHTML = totalVotes;
}
The percentages are in the array of the same name, then you can do whatever you want with it!
Hopes this helps!
You mostly have the idea. You just need to attach some event handlers (with one other minor change).
function totalVotes() {
var votes = document.getElementsByName("votesPerPerson");
var totalVotes = 0;
for(var i = 0; i < votes.length; i++) {
totalVotes += parseInt(votes[i].value || 0); // "Minor change" here
}
document.getElementById("totalvotes").innerHTML = totalVotes;
}
// Additions below this point
var votes = document.getElementsByName("votesPerPerson");
for( var i = 0; i < votes.length; i ++ ) {
votes[i].addEventListener('change', totalVotes);
}
totalVotes(); // Run once to get 0 to show without changing anything
<div>
<label for="votes1">Votes for Candidate 1</label>
<input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
</div>
<div>
<label for="votes2">Votes for Candidate 2</label>
<input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
</div>
<div>
<label for="votes3">Votes for Candidate 3</label>
<input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
</div>
<output id="totalvotes"></output>
Now, that code works, but note some of the repetition, global variables, etc. Here's an alternative that may offer you some different ways of accomplishing the same things:
// If you want to know what this outer function is, look up "IIFE"
(function() {
'use strict';
// Get the elements (and make sure they are put in an array)
var voteInputEls = Array.from(
document.getElementsByName('votesPerPerson')
);
// This is used below to handle the change event
function setTotalVotes() {
// "reduce" the voteInputEls array to a total value
var totalVotes = voteInputEls.reduce(function (lastVal, voteInputEl) {
return lastVal + parseInt(voteInputEl.value || 0);
}, 0);
document.getElementById('totalvotes').innerHTML = totalVotes;
}
// Attach event listeners
voteInputEls.forEach(function(voteInputEl) {
voteInputEl.addEventListener('change', setTotalVotes);
});
setTotalVotes(); // Run once to get 0
})();
<div>
<label for="votes1">Votes for Candidate 1</label>
<input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
</div>
<div>
<label for="votes2">Votes for Candidate 2</label>
<input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
</div>
<div>
<label for="votes3">Votes for Candidate 3</label>
<input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
</div>
<output id="totalvotes"></output>

Categories