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…
Related
I am trying to create a score keeper display.
I want to keep track of the score using html and javascript. I have everything figured out I think but I can't figure out why the line doesn't break here.
Relevant code:
var br = document.createElement("br");
var nes = document.createTextNode("---------");
scorechart.appendChild(br);
scorechart.appendChild(nc);
if(tot) {
scorechart.appendChild(br);
scorechart.appendChild(nes);
scorechart.appendChild(br);
scorechart.appendChild(tot);
}
(For a full view: https://hastebin.com/osuduluvaj.js)
It breaks for everything but the "------" part: https://media.discordapp.net/attachments/240883852350980096/497957073481629696/sAAAAASUVORK5CYII.png
(I cant upload images yet as a new member)
Thank you :)
document.createElement() creates a single element, which you can only append to the DOM once. If you want to reuse the <br> element you created, you need to clone it and you can insert the cloned copy into the DOM. See: Node.cloneNode().
var score = [];
var scoreadd_button = document.querySelector('#scoreadd-button');
var scoreadd_input = document.querySelector('#scoreadd-input');
let sc1 = 0;
let sc2 = 0;
var scorechart = document.querySelector('.scores');
function totalScores() {
var i;
var sum = 0;
for (i = 0; i < score.length; i++) {
sum += score[i];
}
return sum;
}
function newScore(amm) {
score.push(amm);
if (!score[1]) {
var nc = document.createTextNode(amm)
} else {
var nc = document.createTextNode(" + " + amm);
}
if (sc1 == 0) {
sc1 = amm;
} else {
sc2 = amm;
}
if (sc2 != 0) {
var tot = document.createTextNode("= " + totalScores());
sc1 = amm;
sc2 = 0;
}
var br = document.createElement("br");
var nes = document.createTextNode("---------");
scorechart.appendChild(nc);
if (tot) {
scorechart.appendChild(br.cloneNode(true));
scorechart.appendChild(nes);
scorechart.appendChild(br.cloneNode(true));
scorechart.appendChild(tot);
}
}
scoreadd_button.addEventListener('click', function() {
var amm = scoreadd_input.value;
newScore(parseInt(amm, 10));
});
<button id="scoreadd-button">button</button>
<input type="text" id="scoreadd-input" />
<div class="scores"></div>
Okay so I fixed the issue by instead of using a variable just creating the element in the statement.
var nes = document.createTextNode("---------");
scorechart.appendChild(document.createElement("br"));
scorechart.appendChild(nc);
if(tot) {
scorechart.appendChild(document.createElement("br"));
scorechart.appendChild(nes);
scorechart.appendChild(document.createElement("br"));
scorechart.appendChild(tot);
}
Thank you :)
You just need to defined unique variables for each new created element on javascript, otherwise they will counted as one.
This code should works
var scorechart = document.querySelector('.scores');
var br = document.createElement("br");
var br2 = document.createElement("br");
var nes = document.createTextNode("---------");
scorechart.appendChild(br);
scorechart.appendChild(nes);
scorechart.appendChild(br2);
<span class="scores">
text before
</span>
after text
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
I have created a button using JavaScript, and I have a list that is supposed to get a random number when I "roll the dice"
I need to list of numbers to say "You rolled a 1" for example. How do I do that? And also I only need it to show the last 10 numbers.
var rollNumber = 0;
var values = [];
function dieRolled() {
rollNumber += 1;
var numRolled = Math.ceil(Math.random() * 6);
values.push(numRolled);
document.getElementById("results").innerHTML = "";
for (var x = values.length-1 ; x>=0; x--) {
var newRoll = document.createElement("li");
newRoll.innerHTML = values [x] +"You rolled a";
document.getElementById("results").appendChild(newRoll);
if (x == 11)break;
}
}
How about this?
var output = document.getElementById("Output");
var values = [];
function roll()
{
values.push(Math.ceil(Math.random() * 6));
// If the history is too big, drop the oldest...
if (values.length > 10)
{
values.shift();
}
// Rewriting the history log
var text = "";
for (var i in values)
{
text += "You rolled a " + values[i] + "\n";
}
output.innerHTML = text;
}
// Rolling multiple times
setInterval(function(){ roll(); }, 1000);
<pre id="Output"></pre>
Try this:
var list = document.getElementById('demo');
var count = 0;
function changeText2() {
count++;
if(count <= 10)
{
var numRolled = Math.ceil(Math.random() * 6);
var entry = document.createElement('li');
entry.appendChild(document.createTextNode("You rolled:"+numRolled));
list.appendChild(entry);
}
}
<input type='button' onclick='changeText2()' value='Submit' />
<p>Dices you rolled</p>
<ol id="demo"></ol>
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
I designed a table where you can add dynamic rows, the user can select a quantity and a price for each of them. I have a series of very simple functions that allow me to delete, empty the entire table or calculate the total of all products plugged.
So far everything works fine, the problem occurs when I create 3 rows, I add it to each of their values, then I decided to delete the second row and calculate the total. As you can see, the calculation is flawed, in fact I only returns the total of the first product added to the table. I can not understand why the script does not work properly. Can anyone help me solve this problem?
<html>
<table style='width:100%' id='table'>
<tr>
<td colspan='3'><input type="button" style="background-color:#00FA9A" value="add product" onclick="add()" id="button"><input type="button" style="background-color:red" value="Delete all" onclick="deleteall()" id="button">
</td>
</tr>
<tr>
<td>Quantity</td>
<td>€</td>
<td>Delete</td>
</tr>
</table>
<input type="button" id="button" value="Calc total" onclick="total()"><input type="text" class='input' id="total">€
</html>
<script>
var idx = 0;
var cont = 0;
var buttcont = 0;
var quantity, priece;
function deleteall()
{
location.reload();
}
function add()
{
var tableRef = document.getElementById('table').getElementsByTagName('tbody')[0];
var newRow = tableRef.insertRow(tableRef.rows.length);
newRow.id = "row" + cont;
cont++;
var newCell1 = newRow.insertCell(0);
var newCell2 = newRow.insertCell(1);
var newCell3 = newRow.insertCell(2);
var input1 = document.createElement('input'),
input2 = document.createElement('input');
input3 = document.createElement('button');
input1.type = 'number';
input1.style.width = "100%";
input1.id = "priece" + idx;
input1.min = 0;
input1.value = 1;
input2.type = 'text';
input2.min = 1;
input2.style.width = "100%";
input2.id = "quantity" + idx;
input3.class = 'button';
input3.innerHTML = "Delete";
if(input3.attachEvent) input3. attachEvent('onclick',function(e){deleted(e);})
else if(input3.addEventListener) input3.addEventListener('click',function(e){deleted(e);},false)
newCell1.appendChild(input1);
newCell2.appendChild(input2);
newCell3.appendChild(input3);
idx++;
}
function deleted(e)
{
if(document.removeChild && document.getElementById && document.getElementsByTagName)
{
if(!e) e = window.event;
var srg = (e.target)?e.target:e.srcElement;
while(srg.tagName != "TR"){srg = (srg.parentNode)?srg.parentNode:srg.parentElement}
var tb = document.getElementById('table').getElementsByTagName('TBODY')[0];
tb.removeChild(srg);
cont--;
idx--;
}
}
function total()
{
var total = 0;
for(var i = 0; i < idx; i++)
{
quantity = document.getElementById('quantity' + i).value;
priece = document.getElementById('priece' + i).value;
total += quantity * priece;
document.getElementById('total').value = total;
}
}
The problem comes from the fact that when you delete a row inside a table (not the last one) you have a gap in ids. getElementById will return null and your total function will raise an exception.
Add 3 products: idx is 3, ids in the DOM are 0, 1, 2;
Remove product 1: idx is 2, ids in the DOM are 0, 2; => total will throw for i == 1
Actually you can avoid looping through ids by assigning a class to your inputs. Demo.
function total()
{
var total = 0,
prices = document.querySelectorAll('.price'),
quantities = document.querySelectorAll('.quantity'),
i = 0, len = prices.length;
for(; i < len; i++) {
total += prices[i].value*quantities[i].value;
}
document.getElementById('total').value = total;
}