Javascript: Read, Add and Display form values - javascript

I am trying to write a web app that takes user input as numbers in 15 text or number inputs on a html form, it should then add these values together and display the total in a label elsewhere on the page.
I have 15 inputs with the class name "takings" and a label with the ID "TotalLabel" on the page.
function getsum () {
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i = 0; i < rows.length; i++) {
var val = parseFloat(rows[i].value);
total += val;
}
var label = document.getElementById("TotalLabel");
label.value = total;
alert(parseFloat(total));
}
window.onload = getsum;
The alert is only in place for debugging purposes and it appears that the variable total is still set to zero at the end of the script. I also need to make the getsum() function fire every time a user enters data in any of the fields with class "takings".
Can anyone help?

So you need to add change events to all of the elements and call getsum
function getsum () {
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i = 0; i < rows.length; i++) {
var val = parseFloat(rows[i].value);
total += val;
}
var label = document.getElementById("TotalLabel");
label.value = total;
}
window.onload = getsum;
//Example showing how to add one event listener to the page and listen for change events
//The following works in modern browsers, not all browsers support addEventListener, target, and classList.
document.body.addEventListener("change", function(evt) {
var targ = evt.target;
if(targ.classList.contains("takings")) {
getsum();
}
});
label { display: block; }
<label>1</label><input type="text" class="takings" value="0"/>
<label>2</label><input type="text" class="takings" value="0"/>
<label>3</label><input type="text" class="takings" value="0"/>
<label>4</label><input type="text" class="takings" value="0"/>
<label>5</label><input type="text" class="takings" value="0"/>
<label>Total:</label><input type="text" id="TotalLabel" value="0" readonly/>

To have your getSum() function fire for all of those elements, you can use Javascript to add an onchange event to all elements with the required class name
var input = document.getElementsByClassName("takings");
for (var i = 0; i < cells.length; i++) {
input[i].onchange = getSum;
}
Other than that, I don't see any visible errors in your getSum() function.

You need to add an EventListener to your input fields and call getsum, for example
var a = document.getElementsByClassName("takings");
for (var i = 0;i<a.length;i++){
addEventListener('keyup',getsum);
}
Please note that a label has innerHTML, not a value:
label.innerHTML = total;
With your actual function, you will get NaN as a result as long as not all the inputs have a value, so you will need to add
if (val) {
total += val;
}
to your for loop.
Full working code:
function getsum(){
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i =0; i < rows.length; i++){
var val = parseFloat(rows[i].value);
if (val) {
console.log(val);
total += val;
}}
var label = document.getElementById("TotalLabel");
label.innerHTML = total;
}
var a = document.getElementsByClassName("takings");
for (var i = 0;i<a.length;i++){
this.addEventListener('keyup',getsum);
}
DEMO

Related

Javascript combined value sliders

The solutions I have found are jQuery and can't understand them yet.
Anyways, I have a couple of sliders and I want to make it so that their combined max values are always less than a predefined value (variable called available in this case). So that when I change a slider, the max values of the other sliders change.
var available = 10;
var max = 0;
var old = 0;
window.onload = function () {
var sliders = document.getElementsByTagName("input");
var numSliders = sliders.length;
for (i = 0; i < numSliders; i++) {
//Define all sliders?
sliders.item(i).max = available;
document.getElementById(sliders.item(i).id + "val").innerHTML = sliders.item(i).value;
document.getElementById(sliders.item(i).id + "max").innerHTML = sliders.item(i).max;
sliders.item(i).addEventListener("input", function(){
updateSliders();
Slider(this);
})
}
}
function updateSliders() {
var sliders = document.getElementsByTagName("input");
var numSliders = sliders.length;
for (i = 0; i < numSliders; i++)
{
document.getElementById(sliders.item(i).id + "val").innerHTML = sliders.item(i).value;
document.getElementById(sliders.item(i).id + "max").innerHTML = sliders.item(i).max;
}
};
function Slider(active) {
//Get weird set thingy of all sliders
var sliderObject = document.getElementsByTagName("input");
var numberSliders = sliderObject.length;
var total = 0;
//Work out what is being displayed
for(i=0;i<numberSliders;i++)
{
var value = sliderObject.item(i).value;
total += parseInt(value);
}
for(i=0;i<numberSliders;i++)
{
var value = sliderObject.item(i).value;
max = available - value;
if(sliderObject.item(i) != active)
{
console.log("total = " + total);
console.log("old = " + old);
var difference = total - old;
console.log("Difference = " + difference);
sliderObject.item(i).max = sliderObject.item(i).max - (total - old);
}
}
old = total;
}
<div class="sliderContainer">
<input id="slider1" type="range" value=0> <span id="slider1val">0</span>/<span id="slider1max">0</span>
<br>
<input id="slider2" type="range" value=0> <span id="slider2val">0</span>/<span id="slider2max">0</span>
<br>
<input id="slider3" type="range" value=0> <span id="slider3val">0</span>/<span id="slider3max">0</span>
<br> </div>
It kinda works, but the numbers it displays are wrong or something?
Thanks for your time.
One thing you need to change is the order of function calls executed on input event. Slider(this) should be first.
Here is your fixed code: https://codepen.io/kejt/pen/xgoqeX

.innerHTML += id, no duplicates

Here what I have so I have a long list of check-boxes and I want to display them in text if they are check I was thinking of using the code below, but the problem I'm having is if they check and uncheck a check-box it shows up multiple times any suggestion on how to fix this?
.innerHTML += id;
If you need some more details here's a code dump of the relevant code:
Javascript
function findTotal() {
var items = new Array();
var itemCount = document.getElementsByClassName("items");
var total = 0;
var id = '';
for (var i = 0; i < itemCount.length; i++) {
id = "c" + (i + 1);
if (document.getElementById(id).checked) {
total = total + parseInt(document.getElementById(id).value);
document.getElementById(id).parentNode.classList.add("active");
document.getElementById(id).parentNode.classList.remove("hover");
document.getElementById('display').innerHTML += id;
} else {
document.getElementById(id).parentNode.classList.remove("active");
document.getElementById(id).parentNode.classList.add("hover");
}
}
console.log(total);
document.getElementById('displayTotal').value = total;
}
HTML
<label class="hover topping" for="c4">
<input class="items" onclick="findTotal()" type="checkbox" name="topping" value="1.00" id="c4">BABYBEL</label>
Note: many more label classes
Previous answer should do it. Here your code (see comment "clear container"
Additionally I have simplified your code a bit. Readability greatly increased.
Maybe you should switch to jQuery in general, much simpler for your example.
var displayElement = document.getElementById('display'),
displayTotalElement = document.getElementById('displayTotal');
function findTotal() {
var items = [],
itemCount = document.getElementsByClassName("items"),
total = 0,
id = '';
// clear container
displayElement.innerHTML = "";
for (var i = 0; i < itemCount.length; i++) {
id = "c" + (i + 1);
var element = document.getElementById(id),
elementsParent = element.parentNode;
if (element.checked) {
total = total + parseInt(element.value, 10);
elementsParent.classList.add("active");
elementsParent.classList.remove("hover");
displayElement.innerHTML += id;
} else {
elementsParent.classList.remove("active");
elementsParent.classList.add("hover");
}
}
console.log(total);
displayTotalElement.value = total;
}
Reset the text before the loop:
document.getElementById('display').innerHTML = '';
At the moment you're just always adding to whatever's already thereā€¦

Sum of form input in Javascript

I want the user to enter a number then when it is submitted, it is inserted into the array totalBags.
The user can then submit another number, when submitted the array elements are added together.
E.g. Input = 2
Press submit
Output = 2
New input = 3
Press submit
Output = 5
Here is my code:
<html>
<head>
<script type = "text/javascript">
function submitOrder()
{
var allBags = [];
var bags_text = document.getElementById("bags").value;
allBags.push(bags_text);
var totalBags = 0;
for (var i = 0; i < allBags.length; i++)
{
totalBags += allBags[i]; // here is the problem... i think
}
document.getElementById("container").innerHTML = "<p>"+totalBags+"</p><input type=\"reset\" value=\"New Order\" onClick=\"resetOrder()\" />";
}
function resetOrder()
{
document.getElementById("container").innerHTML = "<p><label for=\"bags\">No. bags: </label><input type=\"text\" id=\"bags\" /></p><p><input type=\"button\" value=\"Subit order\" onClick=\"submitOrder()\"> <input type=\"reset\" value=\"Reset Form\" /></p>";
}
</script>
</head>
<body>
<form name="order_form" id="order_form">
<div id="container">
<label>Total bags: </label><input id="bags" type="text" ><br>
<input type="button" id="submitButton" value="Subit order" onClick="submitOrder()">
<input type="reset" value="Reset" class="reset" />
</div>
</form>
</html>
I should rewrite the program a bit. First, you can define global variables which won't be instantiated in the function. You are doing that, which resets the variables. Fe
function submitOrder()
{
var allBags = [];
// ...
}
It means that each time you're clicking on the button allBags is created as a new array. Then you add an value from the input element. The result is that you have always an array with one element. It's best to declare it outside the function. By this, you ensure that the variables are kept.
// general variables
var allBags = [];
var totalBags = 0;
function submitOrder()
{
// the result is a string. You have to cast it to an int to ensure that it's numeric
var bags_text = parseInt(document.getElementById("bags").value, 10);
// add result to allBags
allBags.push(bags_text);
// total bags
totalBags += bags_text;
// display the result
document.getElementById("container").innerHTML = "<p>"+totalBags+"</p><input type=\"reset\" value=\"New Order\" onClick=\"resetOrder()\" />";
}
by leaving out the loop, you have an more performant program. But don't forget to clear the array and the totalBags variable to 0 if you're using the reset button.
function resetOrder()
{
document.getElementById("container").innerHTML = "...";
// reset variables
totalBags = 0;
allBags = [];
}
Try to use:
for (var i = 0; i < allBags.length; i++)
{
totalBags += parseInt(allBags[i],10);
}
Or use Number(allBags[i]) if you prefer that.
Your element allBags[i] is a string and + between strings and concatenting them.
Further study: What is the difference between parseInt(string) and Number(string) in JavaScript?
function submitOrder()
{
var allBags = parseInt(document.getElementById("bags").value.split(""),10);//Number can also used
var totalBags = 0;
for (var i = 0; i < allBags.length; i++)
{
totalBags += allBags[i];
}
document.getElementById("container").innerHTML = "<p>"+totalBags+"</p><input type=\"reset\" value=\"New Order\" onClick=\"resetOrder()\" />";
}

onchange event not tracking properly

I have a form that I want to track any changes. Right now I have it set so when the user exits the page, an alert box displays saying how many changes were made to the form. However, it keeps registering 0. I've tested with adding an alert to the inputChanges function telling me a change has occurred and the alert fires, but the count still registers as 0 when I exit the page...
Here's my script:
window.onload = function() {
var totalChanges = "";
var inputHandles = 0;
var selectHandles = 0;
var textAreaHandles = 0;
window.onbeforeunload = function(){
alert("Total Form Changes:" + totalChanges);
}//onbeforeunload
var totalChanges = inputHandles + selectHandles + textAreaHandles;
function inputChanges() {
inputHandles++;
alert("Change");
}
var inputs = document.getElementsByTagName("input");
for (i = 0; i < inputs.length; i++){
inputs[i].onchange = inputChanges;
}
function selectChanges(){
selectHandles++;
}
var selects = document.getElementsByTagName("select");
for (i = 0; i < selects.length; i++){
selects[i].onselect = selectChanges;
}
function textAreaChanges(){
textAreaHandles++;
}
var textAreas = document.getElementsByTagName("textarea");
for (i = 0; i < textAreas.length; i++){
textAreas[i].onchange = textAreaChanges;
}
}//Onload
You declare totalChanges here:
var totalChanges = "";
...and then re-declare it here:
var totalChanges = inputHandles + selectHandles + textAreaHandles;
...at which point the things you're adding up are all 0.
You need to do that calculation at the point where you need the value:
window.onbeforeunload = function(){
totalChanges = inputHandles + selectHandles + textAreaHandles;
alert("Total Form Changes:" + totalChanges);
}
Or set totalChanges = 0 initially and then increment it every time the other variables change, but that's clunkier.
Note also that you're not tallying the number of fields that now have values different to their starting values, you're tallying the number of individual edits. So if the user changes a field twice with the second change being back to the original value your code will track that as two changes (when logically it's kind of zero changes).
Since the user can change values back to what they were, I suggest you compare all input.value with input.defaultValue and check select.options[select.selectedIndex]defaultSelected
also you might want to move the } and the alert to after the sum of total changes
something like this
window.onload = function() {
var totalChanges = 0;
window.onbeforeunload = function(){
var inputs = document.getElementsByTagName("input"); // ditto for "textarea"
for (var i = 0; i < inputs.length; i++){
totaChanges += inputs[i].value != inputs[i].defaultValue;
}
var selects = document.getElementsByTagName("select");
for (var i = 0; i < selects.length; i++){
totalChanges += !selects[i].defaultSelected;
}
alert("Total Form Changes:" + totalChanges);
}//onbeforeunload
}

Javascript: Detect checked boxes isn't working with form with only 1 checkbox. Working with 2 or more

I have the function below. It gets the values from checked boxes and transfer it to a textbox. It is working... but only if the form has 2 or more checkboxes.
<script type="text/javascript">
function sendValue()
{
var all_values = '';
boxes = document.DataRequest.itens.length
for (i = 0; i < boxes; i++)
{
if (document.DataRequest.itens[i].checked)
{
all_values = all_values + document.DataRequest.itens[i].value + ","
}
}
window.opener.document.getElementById('emailto').value = all_values;
self.close();
}
</script>
<form name="DataRequest">
<input name="itens" type="checkbox" value="name1">
<input name="itens" type="checkbox" value="name2">
</form>
Am I missing something to make this work with only 1 checkbox?
When there is one item. it does not return array
function sendValue()
{
var all_values = '';
boxes = document.DataRequest.itens.length
if(boxes>1)
{
for (i = 0; i < boxes; i++)
{
if (document.DataRequest.itens[i].checked)
{
all_values = all_values + document.DataRequest.itens[i].value + ","
}
}
}
else
{
if (document.DataRequest.itens.checked)
{
all_values = document.DataRequest.itens.value
}
}
window.opener.document.getElementById('emailto').value = all_values;
self.close();
}
First, you need to give different names to your inputs :
<form name="DataRequest">
<input name="item1" type="checkbox" value="name1">
<input name="item2" type="checkbox" value="name2">
</form>
Using the same name to your inputs is technically possible in your case but a terrible practice as the name is normally what's identify for a form the different inputs.
Then, to access your inputs, you must use a different syntax. More than one version are possible but you can do this :
var boxes = document.forms['DataRequest'].getElementsByTagName('input');
var tokens = [];
for (var i=0; i<boxes.length; i++) {
if (boxes[i].checked) tokens.push(boxes[i].name+'='+boxes[i].value);
}
var all_values = tokens.join(',');
Note that the use of join avoids the trailing comma.
not sure how much compatibility you need with IE 6 - 8, but if that's not required you can use
function serializeChecked() {
var values = [];
var checked_boxes = document.querySelectorAll('form[name="DataRequest"] input[checked]');
for (var i = 0, l = checked_boxes.length; i < l; i++) {
values.push(checked_boxes[i].getAtrribute('value'))
}
return values.join(',');
}
function sendValue() {
window.opener.document.getElementById('emailto').value = serializeChecked();
}
If you do require IE support, use document.DataRequest.getElementsByTagName('input') instead of QSA and iterate through them to collect the values if they have the checked attribute.

Categories