How to calculate avg dynamically and flexibly in html+js? - javascript

I want to receive data from the user.
I want to make it possible for the user to add or delete buttons.
And I want to average the results entered by the user.
How can I know how many buttons a user has created?
How do I know the average of the values entered by the user?
<form>
<div id="box">
<input type="text" class="sj"> <input type="button" value="add" onclick="add_textbox()">
</div>
</form>
<script>
const add_textbox = () => {
const box = document.getElementById("box");
const newP = document.createElement('p');
newP.innerHTML = "<input type='text'> <input type='button' value='delete' onclick='remove(this)'>";
box.appendChild(newP);
}
const remove = (obj) => {
document.getElementById('box').removeChild(obj.parentNode);
}
</script>

const add_textbox = () => {
const box = document.getElementById("box");
const newP = document.createElement('p');
newP.innerHTML = "<input type='number' class='sj'> <input type='button' value='delete' onclick='remove(this)'>";
box.appendChild(newP);
}
const remove = (obj) => {
document.getElementById('box').removeChild(obj.parentNode);
}
const resultButton = document.querySelector('[data-button-result]');
const getResult = () => {
const result = [...document.querySelectorAll('.sj')].reduce((acc, input) => {
if (input.valueAsNumber)
return acc += input.valueAsNumber
else return acc
}, 0)
const resultElement = document.querySelector('[data-result]');
resultElement.innerText = result
}
resultButton.addEventListener('click', getResult)
<form>
<div id="box">
<input type="number" class="sj"> <input type="button" value="add" onclick="add_textbox()">
</div>
</form>
<button data-button-result>Get results</button>
<div data-result></div>

Related

Calculate total sum of all the numbers previously entered in a field

i want to calculate the total of the numbers entered by the user. After a user has added item name and the amount, i want to display the total. How can i do this? i just need to display the total.
For example
item name : 10
item name : 5
total = 15
http://jsfiddle.net/81t6auhd/
<body>
<header>
<h1>Exercise 5-2</h1>
</header>
<p>Item: <input type="text" id="item" size="30">
<p>Amount: <input type="text" id="amount" size="30">
<p><span id="message">*</span>
<p><input type="button" id="addbutton" value="Add Item" onClick="processInfo();">
<script>
var $ = function(id) {
return document.getElementById(id);
};
var myTransaction = [];
function processInfo ()
{
var myItem = $('item').value;
var myAmount = parseFloat($('amount').value);
var myTotal = myItem + ":" + myAmount;
var myParagraph = $('message');
myParagraph.innerHTML = "";
myTransaction.push(myTotal);
myParagraph.innerHTML += myTransaction.join("<br>");
};
(function () {
$("addbutton").onclick = processInfo;
})();
</script>
</body>
you have to stored the previous value somewhere in memory to be able to reuse it at next iteration
one proposal can be to stored it in dataset of the field
if ($('amount').dataset.previous) {
myAmount += parseFloat($('amount').dataset.previous);
}
$('amount').dataset.previous = myAmount
var $ = function(id) {
return document.getElementById(id);
};
var myTransaction = [];
function processInfo ()
{
var myItem = $('item').value;
var myAmount = parseFloat($('amount').value);
if ($('amount').dataset.previous) {
myAmount += parseFloat($('amount').dataset.previous);
}
$('amount').dataset.previous = myAmount;
var myTotal = myItem + ":" + myAmount;
var myParagraph = $('message');
myParagraph.innerHTML = "";
myTransaction.push(myTotal);
myParagraph.innerHTML += myTransaction.join("<br>");
};
(function () {
$("addbutton").onclick = processInfo;
})();
<p>Item: <input type="text" id="item" size="30">
<p>Amount: <input type="text" id="amount" size="30">
<p><span id="message">*</span>
<p><input type="button" id="addbutton" value="Add Item" onClick="processInfo();">

Typing in the firt input without focusing

I have an Virtual keyboard with Javascript the keyboard is typing in two inputs after reached maxlength it is focusing to second input. my problem is when i want to type in first input i should clicked to first input to focus it than typing with keyboard numbers
My question is How i can typing using this keyboard without clicking inside input, the first input should start typing immediately after i clicked on the buttons numbers
const maxLength = 7;
const firstInput = document.querySelector("#pin");
const secondInput = document.querySelector("#key");
const changedEvent = new Event("change")
let activeInput;
firstInput.addEventListener("focus", (event) => {
activeInput = event.target;
});
firstInput.addEventListener("change", (event) => {
console.log("i'm changing!");
if (firstInput.value.length >= maxLength) {
activeInput = secondInput;
secondInput.focus();
}
});
secondInput.addEventListener("focus", (event) => {
activeInput = event.target;
});
function resetNumber() {
if (!activeInput) {
console.log("pin");
return;
}
activeInput.value = "";
}
function setNumber(number) {
if (!activeInput) {
console.log("pin");
return;
}
activeInput.value = activeInput.value === number ? "" : (activeInput.value += number);
// manually tell the input that it has changed, so that the event listener defined above gets called. this usually only will happen with actual keyboard input
activeInput.dispatchEvent(changedEvent);
}
<button onclick="resetNumber()">Reset</button>
<button onclick="setNumber(0)">0</button>
<button onclick="setNumber(1)">1</button>
<button onclick="setNumber(2)">2</button>
<button onclick="setNumber(3)">3</button>
<button onclick="setNumber(4)">4</button>
<button onclick="setNumber(5)">5</button>
<button onclick="setNumber(6)">6</button>
<button onclick="setNumber(7)">7</button>
<button onclick="setNumber(8)">8</button>
<button onclick="setNumber(9)">9</button>
<br />
<input type="text" id="pin" />
<input type="text" id="key" />
<button id="reset" onclick="resetNumber()">Reset</button>
<br />
<input type="text" id="pin" />
<input type="text" id="key" />
<script>
const maxLength = 7;
const firstInput = document.querySelector('#pin');
const secondInput = document.querySelector('#key');
const resetBtn = document.querySelector('#reset');
for (let i = 9; i >= 0; i--) {
const numBtn = document.createElement('button');
numBtn.className = 'number';
numBtn.innerText = i;
resetBtn.parentElement.insertBefore(numBtn, resetBtn.nextSibling);
}
const numberBtns = document.querySelectorAll('.number');
const resetNumber = () => {
firstInput.setAttribute('value', '');
secondInput.setAttribute('value', '');
};
const setVal = (e) => {
const num = parseInt(e.target.innerText, 10);
if (firstInput.value.length <= maxLength) return firstInput.setAttribute('value', firstInput.value + num);
secondInput.setAttribute('value', secondInput.value + num);
};
numberBtns.forEach((btn) => btn.addEventListener('click', setVal));
</script>

need to append user data to array

my original question got answered but I realize that every time I try to push user data in the arrays it wouldn't allow me to do is there any another to append data to arrays or is the push method the only way. or should i create a new array................................................................
"use strict"
const names = ["Ben", "Joel", "Judy", "Anne"];
const scores = [88, 98, 77, 88];
const $ = selector => document.querySelector(selector);
const addScore = () => {
// get user entries
const name = $("#name").value;
const score = parseInt($("#score").value);
let isValid = true;
// check entries for validity
if (name == "") {
$("#name").nextElementSibling.textContent = "This field is required.";
isValid = false;
} else {
$("#name").nextElementSibling.textContent = "";
}
if (isNaN(score) || score < 0 || score > 100) {
$("#score").nextElementSibling.textContent = "You must enter a valid score.";
isValid = false;
} else {
$("#score").nextElementSibling.textContent = "";
}
if (isValid) {
names.push("#name");
scores.push("#score");
names[names.length] = name;
scores[scores.length] = score;
$("#name").value = "";
$("#score").value = "";
}
$("#name").focus();
};
// display scores
const displayScores = () => {
for (let i = 0; i < names.length; i++) {
document.getElementById("scores_display").textContent += names[i] + " = " +
scores[i] +
"\n";
}
};
document.addEventListener("DOMContentLoaded", () => {
$("#add").addEventListener("click", addScore);
$("#display_scores").addEventListener("click", displayScores())
$("#name").focus();
});
<main>
<h1>Use a Test Score array</h1>
<div>
<label for="name">Name:</label>
<input type="text" id="name">
<span></span>
</div>
<div>
<label for="score">Score:</label>
<input type="text" id="score">
<span></span>
</div>
<div>
<label> </label>
<input type="button" id="add" value="Add to Array">
<input type="button" id="display_scores" value="Display Scores">
</div>
<div>
<textarea id="scores_display"></textarea>
</div>
</main>
All my previous notes were incorrect. Your adhoc $ const threw me off! My apologies.
The issue was you weren't calling displayScores() after updating the array. Plus, I added a line to that function to clear the existing text before looping through your data.
"use strict"
const names = ["Ben", "Joel", "Judy", "Anne"];
const scores = [88, 98, 77, 88];
const $ = selector => document.querySelector(selector);
const addScore = () => {
// get user entries
const name = $("#name").value;
const score = parseInt($("#score").value);
let isValid = true;
// check entries for validity
if (name == "") {
$("#name").nextElementSibling.textContent = "This field is required.";
isValid = false;
} else {
$("#name").nextElementSibling.textContent = "";
}
if (isNaN(score) || score < 0 || score > 100) {
$("#score").nextElementSibling.textContent = "You must enter a valid score.";
isValid = false;
} else {
$("#score").nextElementSibling.textContent = "";
}
if (isValid) {
names.push("#name");
scores.push("#score");
names[names.length] = name;
scores[scores.length] = score;
$("#name").value = "";
$("#score").value = "";
// add to the textarea
displayScores()
}
$("#name").focus();
};
// display scores
const displayScores = () => {
document.getElementById("scores_display").textContent = "";
for (let i = 0; i < names.length; i++) {
document.getElementById("scores_display").textContent += names[i] + " = " +
scores[i] +
"\n";
}
};
document.addEventListener("DOMContentLoaded", () => {
$("#add").addEventListener("click", addScore);
$("#display_scores").addEventListener("click", displayScores())
$("#name").focus();
});
<main>
<h1>Use a Test Score array</h1>
<div>
<label for="name">Name:</label>
<input type="text" id="name">
<span></span>
</div>
<div>
<label for="score">Score:</label>
<input type="text" id="score">
<span></span>
</div>
<div>
<label> </label>
<input type="button" id="add" value="Add to Array">
<input type="button" id="display_scores" value="Display Scores">
</div>
<div>
<textarea rows="6" id="scores_display"></textarea>
</div>
</main>

Output/Displaying the value in the HTML

So I am a newbie and I am just practice
const userInput = document.getElementById("input-text");
const addBtn = document.getElementById("add");
const output = document.getElementById("output");
function displayOutput(text) {
output.textContent = text;
}
function getUserInput() {
return userInput.value;
}
function addValue() {
const enteredValue = getUserInput();
const displayValue = enteredValue;
displayOutput(displayValue);
}
addBtn.addEventListener('click', addValue);
<form action="">
<input type="text" id="input-text">
<button id="add">add value</button>
</form>
<p>Data: <span id="output"></span></p>
my first lesson of JS is function and with .textcontent. So I wrote a code that will output the value/ number I entered on the input field after I click the add value button but somehow my code doesn't work.
DISCLAIMER> I HAVENT LEARN LOOPS< IF STATEMENTS OR WHATSOEVER I just want to practice my lesson.
You just need to e.preventDefault() to prevent the form from submission and reload the page. It is the default behavior, so you need to prevent this behavior.
const userInput = document.getElementById("input-text");
const addBtn = document.getElementById("add");
const output = document.getElementById("output");
function displayOutput(text) {
output.textContent = text;
}
function getUserInput() {
return userInput.value;
}
function addValue(e) {
e.preventDefault();
const enteredValue = getUserInput();
const displayValue = enteredValue;
displayOutput(displayValue);
}
addBtn.addEventListener("click", addValue);
<form action="">
<input type="text" id="input-text">
<button id="add">add value</button>
</form>
<p>Data: <span id="output"></span></p>
Like some other people already mentioned, it's the <form> that's being submitted.
I'd recommend removing the <form></form> since there no use for it now:
const userInput = document.getElementById("input-text");
const addBtn = document.getElementById("add");
const output = document.getElementById("output");
function displayOutput(text) {
output.textContent = text;
}
function getUserInput() {
return userInput.value;
}
function addValue() {
const enteredValue = getUserInput();
const displayValue = enteredValue;
displayOutput(displayValue);
}
addBtn.addEventListener('click', addValue);
<input type="text" id="input-text">
<button id="add">add value</button>
<p>Data: <span id="output"></span></p>
Small side-note:
function addValue() {
const enteredValue = getUserInput();
const displayValue = enteredValue;
displayOutput(displayValue);
}
Can be simplified to just:
function addValue() {
displayOutput(getUserInput());
);
const userInput = document.getElementById("input-text");
const addBtn = document.getElementById("add");
const output = document.getElementById("output");
function displayOutput(text) {
output.textContent = text;
}
function getUserInput() {
return userInput.value;
}
function addValue() {
displayOutput(getUserInput());
}
addBtn.addEventListener('click', addValue);
<input type="text" id="input-text">
<button id="add">add value</button>
<p>Data: <span id="output"></span></p>

Adding an event listener to DOM elements pushed into an array

Apologies for the poorly-worded question. It's my first question here!
I am trying to make an application whereby one can log the scores of players from any game and see the results at the end of the game (see the code snippet below).
So far, I have managed to push players and their scores (initially empty arrays) into the main array and thereby presented these players in a list (see below):
HTML
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
JavaScript
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
This gives me a list with the players' names, inputs to enter scores and buttons to log the scores. So far, so good.
But...
I am just trying to get each button to work. As you can see above, I gave each submit button classes ("submitScoreBtn"). I'm at the stage where I want to make sure that my new buttons work. Here's my code so far:
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
for (var x = 0; x < submitScore.length; x++){
submitScore[x].addEventListener("click", () => {
alert("selected");
});
}
I initially was getting errors without adding a for loop. Now I don't get any errors, but I also don't get any alerts. I'm just not sure why these buttons do not work.
Please see the code snippet below.
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
for (var x = 0; x < submitScore.length; x++){
submitScore[x].addEventListener("click", () => {
alert("selected");
});
}
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
Being as you're dynamically creating the buttons, it might be easier to simply add the function to the button's onclick.
You can still access the event object from this click by sending it as a parameter, like:
<input type='submit' onclick='submitScoreClick(event)' class='submitScoreBtn'>
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' onclick='submitScoreClick(event)' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
function submitScoreClick (e) {
alert("selected");
};
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
At the point in time when this code is run:
for (var x = 0; x < players.length; x++){
submitScore[x].addEventListener("click", (event) => {
event.alert("selected");
});
}
players.length is equal to 0. So the code is essentially never executed.
remove the for loop and add this code
document.addEventListener('click', function (event) {
if ( event.target.classList.contains( 'submitScoreBtn' ) ) {
alert("selected");
}
}, false);
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push({
player: entered,
score: []
});
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i = 0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className = "each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
document.addEventListener('click', function(event) {
if (event.target.classList.contains('submitScoreBtn')) {
alert("selected");
}
}, false);
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
The easiest solution is to use variables and createElement just like you do with toAdd. This way each created entry will remember its own inputs (local variables to the function), and you can use for example the score input variable in the click handler without confusion of which number input belongs to which entry.
I removed the class for the inputs because it's not needed to select them anymore, but you can still add some for styling for example. If you want to add classes to select them all, be sure to run querySelectorAll each time, so that added elements are actually selected.
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
var addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
var createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " ";
var enterScore = document.createElement("input");
enterScore.type = 'number';
enterScore.placeholder = 'enter score';
var submitScore = document.createElement("input");
submitScore.type = 'submit';
submitScore.addEventListener("click", () => {
alert("selected score: " + enterScore.value);
});
newLi.appendChild(enterScore);
newLi.appendChild(submitScore);
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>

Categories