Trouble looping through the inputs and adding them - javascript

Having an issue with peoplePaid() looping through all the inputs with the .persons class on a page through an add button. I believe this issue is that #paidTotal is trying to add contents from an array in .persons but can't access them (gives me an undefined error in console).
This variable works but only if there's one .persons class with a variable...
var personsCheck = parseFloat(document.getElementsByClassName('persons')[0].value);
However I need it to dynamically loop the values of the array that is created through .persons elements. What am I missing?
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = document.getElementById('paidTotal');
for (var i = 1; i < personsCheck.length; i += 1) {
paidTotal += personsCheck[i];
}
paidTotal.innerHTML = checkTotal - personsCheck;
}
$ <input type="text" id="check" value="" />
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person">
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>

paidTotal is an element. I believe you do not want to use += on the element itself. You should add the total to a variable.
Also, as the index of collections are 0 based, you have to start the value of i from 0. You have to take the value property from each element.
Please Note: It is good practice to use textContent instead of innerHTML when dealing with text only content.
Try the following way:
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = document.getElementById('paidTotal');
var pCheck = 0;
for (var i = 0; i < personsCheck.length; i += 1) {
pCheck += personsCheck[i].value;
}
paidTotal.textContent = checkTotal - pCheck;
}
$ <input type="text" id="check" value="" />
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person">
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>

Some mistakes exists in your code:
paidTotal is an element but in paidTotal += personsCheck[i]; you have used it some a numeric variable.
in your loop, index must starts from zero not one.
in this line: paidTotal += personsCheck[i]; you have added personsCheck[i] element to paidTotal instead of its value.
the corrected code is like this:
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = 0;
for (var i = 0; i < personsCheck.length; i += 1) {
paidTotal += personsCheck[i].value * 1;
}
document.getElementById('paidTotal').innerHTML = checkTotal - paidTotal;
}
$ <input type="text" id="check" value="" />
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person">
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>

Related

Calc two fields and set results in third

I have a problem with the script.
I am trying to count two input fields, and insert the result into the third field.
But it doesn't work, and unfortunately I can't figure out what's wrong.
function sum() {
var txtFirstNumberValue = document.querySelectorAll('#firstID > div > div > div > input').value;
var txtSecondNumberValue = document.querySelectorAll('#second > div > div > div > input').value;
if (txtFirstNumberValue == "")
txtFirstNumberValue = 0;
if (txtSecondNumberValue == "")
txtSecondNumberValue = 0;
var result = parseInt(txtFirstNumberValue) / parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.querySelectorAll('#third > div > div > div > input').value = result;
}
}
<div id="firstID"><div>
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" value="" maxlength="255">
</div>
</div>
</div></div>
<div id="second"><div>
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
</div></div>
<div id="third"><div>
<label>third</label>
<div>
<div>
<input name="drts[field_third][0]" type="number" value="" maxlength="255">
<div></div>
</div>
</div>
</div></div>
There are a few problems here.
Are you actually calling sum? I've added a call in the example code so you can run it.
Your query selectors are not right. There isn't actually anything in the divs with the IDs you query. I've moved the input boxes into the correct places. When debugging, you should check that you are actually finding elements in your querySelectorAll call before proceeding.
querySelectorAll doesn't have a value property. You would need to iterate over each element before getting the items. Given you specifically want one item, it would be better to use something more specific like getElementById. I've kept the original querySelectorAll but changed the IDs on the divs to classes so we can have more than one result for this example. Then, I iterate over them pulling out the value to add to result. I've moved the parseInt to the running calculation otherwise it would perform a string concatenation.
Even better than the above would be to access the input directly. There's probably no point accessing a div and drilling down to the input. I've included this example to output the result.
I've removed redundant html. It's not related to the answer but try to keep your markup clean.
function sum() {
var inputElements = document.querySelectorAll('.user-input > div > div > input');
var result = 0;
inputElements.forEach(element => {
result += element.value ? parseInt(element.value) : 0
})
document.getElementById('third').value = result
}
document.getElementById('run-button').addEventListener('click', sum)
<div class="user-input">
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" maxlength="255">
</div>
</div>
<div>
<div class="user-input">
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
<div>
<label>third</label>
<div>
<div>
<input id="third" name="drts[field_third][0]" type="number" value="" maxlength="255">
<div></div>
</div>
</div>
<div>
<button type="button" id="run-button">Run</button>
Try like this
function sum() {
let txtFirstNumberValue = document.querySelector('#firstID input').value;
let txtSecondNumberValue = document.querySelector('#second input').value;
let result = parseInt(txtFirstNumberValue) / parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.querySelector('#third input').value = result;
} else {
document.querySelector('#third input').value = '';
}
}
<div id="firstID"><div>
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" value="" maxlength="255">
</div>
</div>
</div></div>
<div id="second"><div>
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
</div></div>
<div id="third"><div>
<label>third</label>
<div>
<div>
<input name="drts[field_third][0]" type="number" value="" maxlength="255" disabled>
<div></div>
</div>
</div>
<div>
<button id="button" onclick="sum()">Calculate</button>
</div>
</div>
</div>
const input1 = document.querySelector('#input1');
const input2 = document.querySelector('#input2');
const input3 = document.querySelector('#input3');
const storeInputs = [input1, input2];
for(let i = 0; i < storeInputs.length; i++) {
storeInputs[i].addEventListener('input', function() {
// multiply input1 and input2 with 1 for converting there values from string to number
input3.value = input1.value * 1 + input2.value * 1;
});
};
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<label for="input1">First Input</label>
<input id="input1" type="number" value="0"></input>
<label for="input2">Second Input</label>
<input id="input2" type="number" value="0"></input>
<label for="input3">Third Input</label>
<input id="input3" type="number" value="0"></input>
</body>
</html>

How to grab values of checkboxes in an array

I have a div as follows:
<div class="questionholder" id="question5" style="display:none">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button" onclick="displayquestion(6);">Next</a>
</div>
The user is expected to select all the checkboxes that apply to his situation. Let's assume he selects all 3.
When he clicks "Next", the function displayquestion(); will fire.
function displayquestion(a) {
var Elements = '';
var b = a - 1;
Elements = document.querySelector("#question" + b + " input[name=ID1element]").value;
}
Basically, the function is meant to store all the checked values into var Elements, which is meant to be an array.
However, I'm only getting the value of the first selected answer instead of an array of all selected answers.
How do I grab all the selected answers into an array?
No jQuery please.
Use querySelectorAll to get an array-like NodeList instead of querySelector, and then you can use Array.from to transform that NodeList into an array containing only the .value of the selected inputs:
function displayquestion(a) {
const b = a - 1;
const elements = Array.from(
document.querySelectorAll('#question' + b + ' input:checked'),
input => input.value
);
console.log(elements);
}
<div class="questionholder" id="question5">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button" onclick="displayquestion(6);">Next</a>
</div>
Here is the script that you can use for that:
I haven't changed anything in your HTML structure. Except I have removed the display: none; from the style attribute of the class questionholder.
<script>
function displayquestion(b) {
let checkboxList = document.querySelectorAll("#question" + b + " input:checked");
let obj = [];
if (checkboxList.length > 0) { //Code works only if some checbox is checked
checkboxList.forEach(function(item) {
obj.push(item.value); //Contains the value of all the selected checkboxes.
});
}
console.log(obj); //array list containing all the selected values
}
</script>
<div class="questionholder" id="question5" style="">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button" onclick="displayquestion(5);">Next</a>
</div>
Here is a JSFiddle link for that.
I hope this is helpful.
So first of I would make a variable for your
<a class="text2button">Next</a>. And I have removed the
onclick="displayquestion(6)" from your html.
Here is the variable.
var text2button = document.getElementsByClassName("text2button")[0];
text2button.addEventListener("click", displayquestion);
Here we have the function, so what I've done is.
I have created a variable var elements = []; Which is a empty array.
Then I create this variable var inputs = document.getElementsByClassName("input5");
This variable gets all the inputs with class input5.
Next I would loop through each of the inputs from the var inputs. Like this.
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
elements.push(inputs[i].value);
}
}
So what I do here is loop through each input for (var i = 0; i < inputs.length; i++) and then I check if any of the inputs are checked if (inputs[i].checked), then I push them to the array var elements with elements.push(inputs[i].value);.
And then I use console.log(elements); so show it in the console.
Check out the snippet below to see it in effect.
Hope this helps.
var text2button = document.getElementsByClassName("text2button")[0];
text2button.addEventListener("click", displayquestion);
function displayquestion() {
var elements = [];
var inputs = document.getElementsByClassName("input5");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
elements.push(inputs[i].value);
}
}
console.log(elements);
}
<div class="questionholder" id="question5">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button">Next</a>
</div>

Output wont show (javascript)

I have 1 input. And it has to print out 2 outputs 1 with -1 to the output and the other with -2. But the output doesn't show anything. can someone tell me what I'm doing wrong here.
Code:
// Meters en Centimeters value
function updateTotal() {
const list = document.getElementsByClassName("AutosubmitCalculator");
const values = [];
for (let i = 0; i < list.length; ++i) {
values.push(parseFloat(list[i].value));
}
let total = values.reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
});
document.getElementById("schermentotaal").value = total - 2;
document.getElementById("schermentotaal2").value = total - 1;
}
HTML Input:
<div class="InputField InputMeters">
<input type="tel" name="iFenceMeters" id="FenceMeters" class="AutosubmitCalculator" data-minimum-length="1" tabindex="1" placeholder="00" maxlength="3" value="">
<div class="FormExclamation Tipped Hidden" id="FormCalculatorExclamationFence">0</div>
</div>
HTML Output:
<div class="SummaryRow">
<strong>Schermen</strong>
<input name="schermentotaal" type="text" id="schermentotaal" value=""></input>
</div>
<div class="SummaryRow">
<strong>Palen en onderplaten</strong>
<input name="schermentotaal2" type="text" id="schermentotaal2" value=""></input>
</div>
Thanks in advance :D
You're not calling your updateTotal anywhere. I suggest you run this function on the oninput event on your input field. This will make it so that whenever you enter a number it will run the function updateTotal.
You also have some additional errors, such as you are trying to get the element with the id total but don't have an element with this id in your HTML.
document.getElementById("total").value
I've changed this to be schermentotaal2 which is a valid id in your HTML:
document.getElementById("schermentotaal2").value
See working example below:
function updateTotal() {
const list = document.getElementsByClassName("AutosubmitCalculator");
const values = [];
for (let i = 0; i < list.length; i++) {
values.push(parseFloat(list[i].value));
}
let total = values.reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
});
document.getElementById("schermentotaal").value = (total - 2) || '';
document.getElementById("schermentotaal2").value = (total - 1) || '';
}
<div class="InputField InputMeters">
<input type="tel" name="iFenceMeters" id="FenceMeters" class="AutosubmitCalculator" data-minimum-length="1" tabindex="1" placeholder="00" maxlength="3" value="" oninput="updateTotal()" />
<div class="FormExclamation Tipped Hidden" id="FormCalculatorExclamationFence">0</div>
</div>
<div class="SummaryRow">
<strong>Schermen</strong>
<input name="schermentotaal" type="text" id="schermentotaal" value="" />
</div>
<div class="SummaryRow">
<strong>Palen en onderplaten</strong>
<input name="schermentotaal2" type="text" id="schermentotaal2" value="" />
</div>
Also, if you only have one input you may want to reconsider using a class to get the input value for this as you don't require a loop to get the value from one input field.

jQuery add ID increment to .html() appending on input onchange and refresh onchange value

I apologize for the wordy title but I haven't found a solution to my problem yet. I am a newbie with jQuery and web development so any guidance would be appreciated.
I have a <input> that allows user to enter a value (number) of how many rows of a set of input fields they want populated. Here's my example:
<div id="form">
<input id="num" name="num" type="text" />
</div>
<p> </p>
<div id="form2">
<form action="" method="post" class="form_main">
<div class="data">
<div class="item">
<input id="name" name="name[]" type="text" placeholder="name" /><br/>
<input id="age" name="age[]" type="text" placeholder="age" /><br/>
<input id="city" name="city[]" type="text" placeholder="city" /><br/>
<hr />
</div>
</div>
<button type="submit" name="submit">Submit</button>
</form>
My jQuery:
<script>
var itemNum = 1;
$("#num").on("change", function() {
var count = this.value;
var item = $(".item").parent().html();
//item.attr('id', 'item' + itemNum);
for(var i = 2; i <= count; i++) {
itemNum++;
$(".data").append(item);
}
})
</script>
I'm having problems adding an ID item+itemNum increment to <div class="item">... item.attr() didn't work. It doesn't append once I added that line of code.
Also, how can I get it so that once a user enters a number that populates rows of input fields, that if they change that number it will populate that exact number instead of adding to the already populated rows? Sorry if this doesn't make any sense. Please help!
Here is a DEMO
var itemNum = 1;
$("#num").on("change", function() {
$('.data div').slice(1).remove(); //code for removing previously populated elements.
var count = this.value;
console.log(count);
var item;
//item.attr('id', 'item' + itemNum);
var i;
for(i = 1; i <= count; i++) {
console.log(i);
item = $("#item0").clone().attr('id','item'+itemNum);
//prevent duplicated ID's
item.children('input[name="name[]"]').attr('id','name'+itemNum);
item.children('input[name="age[]"]').attr('id','age'+itemNum);
item.children('input[name="city[]"]').attr('id','city'+itemNum);
itemNum++;
$(".data").append(item);
}
})
Use clone() instead of html()
Try
var itemNum = 1,
item = $(".data .item").parent().html();;
$("#num").on("change", function () {
var count = +this.value;
if (itemNum < count) {
while (itemNum < count) {
itemNum++;
$(item).attr('id', 'item' + itemNum).appendTo('.data')
}
} else {
itemNum = count < 1 ? 1 : count;
$('.data .item').slice(itemNum).remove();
}
})
Demo: Fiddle

add div based on value in number input

I have a set of number fields, each with a class "product-quantity", and a set of empty divs. the number fields are set with a data-attr small, medium, and goes up to 5xl. The empty div's are set with a data-attr small, medium, and goes up to 5xl as well because the small number field is associated with the small div and so one.
When you increase or decrease the number inside the small number field a div "small" should insert after the empty div with the attr small.
When you increase or decrease the number inside the medium number field a div "medium" should insert after the empty div with the attr medium.... and so on
additionally, all of the above belongs to a product x container, and there are multiple products on a page.
I have this jsfiddle that simulates what I am trying to do:
http://jsfiddle.net/7PhJZ/25/
however, right now when I add/subtract a number to the small number fields, it adds/subtracts a div to both the empty small/ medium div as well as in both products. and same for the medium.
I am having a hard time trying to associate which number field belongs to which empty div, which belongs to which product.
html:
<div id="product-1">
<div class="size-field">
<div id="size-label">
s
</div>
<div class="number-input">
<input id="Small" class="product-quantity" type="number" name="Small" min="0"
max="9999" data-product-id="1">
</input>
</div>
</div>
<div id="size-label">
m
</div>
<div class="number-input">
<input id="Medium" class="product-quantity" type="number" name="Medium"
min="0" max="9999" data-product-id="1">
</input>
</div>
<div class="name-number-header"><h5>HEADER<h5></div>
<div class="name-number-field-container" data-size="Small">small:
</div>
<div class="name-number-field-container" data-size="Medium">medium:
</div>
</div>
<br clear="all">
<div id="product-2">
<div class="size-field">
<div id="size-label">
s
</div>
<div class="number-input">
<input id="Small" class="product-quantity" type="number" name="Small" min="0"
max="9999" data-product-id="2">
</input>
</div>
</div>
<div id="size-label">
m
</div>
<div class="number-input">
<input id="Medium" class="product-quantity" type="number" name="Medium"
min="0" max="9999" data-product-id="2">
</input>
</div>
<div class="name-number-header"><h5>HEADER<h5></div>
<div class="name-number-field-container" data-size="Small">small:
</div>
<div class="name-number-field-container" data-size="Medium">medium:
</div>
</div>
js:
$('.product-quantity').on('change',function(){
$('.name-number-field').remove();
var val = $(this).val();
for (var i = 0; i < parseInt(val); i++){
$('<div/>',{'class':'name-number-field'}).insertAfter($("[data-size]"));
}
});
$('.product-quantity').on('change', function () {
var val = $(this).val(),
ele = $(this).closest('[id^="product"]').find('[data-size="'+this.name+'"]');
ele.nextUntil('[data-size]').remove();
for (var i = 0; i < parseInt(val); i++) {
$('<div/>', {
'class': 'name-number-field'
}).insertAfter(ele);
}
});
FIDDLE
EDIT:
Based on the comments, what you're really trying to do is just add one if the value increments, and remove the last if the value decrements, and for that the approach would be somewhat different:
$('.product-quantity').each(function() {
$(this).data('val', this.value);
}).on('change', function () {
var val = $(this).val(),
old = $(this).data('val'),
ele = $(this).closest('[id^="product"]').find('[data-size="'+this.name+'"]'),
inc = val >= old;
if (inc) {
$('<div/>', {
'class': 'name-number-field'
}).insertAfter(ele);
}else {
$('.name-number-field', ele.parent()).last().remove();
}
$(this).data('val', this.value);
});
FIDDLE
Make Use of your data-product-id and hook the textbox's parent and target the required elements.
Try this,
$('.product-quantity').on('change',function(){
$('.name-number-field').remove();
var val = $(this).val();
for (var i = 0; i < parseInt(val); i++){
$('<div/>',{'class':'name-number-field'})
.insertAfter($(this).parents('#product-' + $(this).data('product-id')).find("[data-size]"));
}
});
DEMO
Edit:
$('.product-quantity').on('change',function(){
$('.name-number-field').remove();
var val = $(this).val();
for (var i = 0; i < parseInt(val); i++){
$('<div/>',{'class':'name-number-field'})
.insertAfter($(this).parents('#product-' + $(this).data('product-id')).find("[data-size='"+ $(this).attr('name') +"'][data-size]"));
}
});
NEW - DEMO

Categories