How to limit a function to run 5 times? Javascript - javascript

I'm trying to limit a function to run 5 times only with no success.
So the idea of the exercise is to create a function Person() that ask for a person's [name, surname and age] and ask for the user information 5 times.
My problem is to limit the function, at the moment i can add as many user's as i want not only 5.
<body>
<div class="container">
<div class="form-box">
<h1 id="title">Exercise</h1>
<form>
<div class="input-group" id="name-field">
<input type="text" placeholder="Nome" class='firstName' id="firstName-input">
<input type="text" placeholder="Apelido" class="lastName" id="lastName-input">
<input type="text" placeholder="Idade" class="age" id="age-input">
<div class="btn-field">
<button type="button" class="btn-adicionar" id="btn-adicionar" onclick="Person()">Add</button>
<button type="button" class="btn-mostrar" id="btn-mostrar" onclick="Show()">Show</button>
</div>
<p id="p"></p>
</div>
</form>
</div>
</div>
let Persona = [];
Persona.values = {
inputs: [],
labels: {
n: ' Name: ',
a: ' Surname: ',
i: ' Age: ',
},
};
function Adicionar() {
let firstName = document.getElementById('firstName-input').value;
let lastName = document.getElementById('lastName-input').value;
let age = document.getElementById('age-input').value;
Persona.values.inputs.push({
firstName: firstName,
lastName: lastName,
age: age,
});
}
function Show() {
let text = '';
for (var i = 0; i < Persona.values.inputs.length; i++) {
text += "<div class='outrow'>";
text += "<span class='lab'>" + Persona.values.labels.n + '</span>';
text +=
"<span class='outv'>" +
Persona.values.inputs[i].firstName +
'</span>';
text += "<span class='lab'>" + Persona.values.labels.a + '</span>';
text +=
"<span class='outv'>" +
Persona.values.inputs[i].lastName +
'</span>';
text += "<span class='lab'>" + Persona.values.labels.i + '</span>';
text +=
"<span class='outv'>" + Persona.values.inputs[i].age + '</span>';
text += '</div>';
}
let result = document.getElementById('p');
result.innerHTML = text;
}
I've tried to use an if statement but still have the same result.
function Person() {
let number = 0
if (number < 5) {
let firstName = document.getElementById('firstName-input').value;
let lastName = document.getElementById('lastName-input').value;
let age = document.getElementById('age-input').value;
Persona.values.inputs.push({
firstName: firstName,
lastName: lastName,
age: age,
});
number++
}
}```

I think you don't need the counter variable at all, just check Persona.values.inputs.length.
function Person() {
if (Persona.values.inputs.length < 5) {
let firstName = document.getElementById('firstName-input').value;
let lastName = document.getElementById('lastName-input').value;
let age = document.getElementById('age-input').value;
Persona.values.inputs.push({
firstName: firstName,
lastName: lastName,
age: age,
});
}
}
You can also assign input values directly to the object and avoid creating unnecessary variables
function Person() {
if (Persona.values.inputs.length < 5) {
Persona.values.inputs.push({
firstName: document.getElementById('firstName-input').value,
lastName: document.getElementById('lastName-input').value,
age: document.getElementById('age-input').value,
});
}
}

You are adding your number counter variable inside the function that you want to limit, so everytime you call this function number will be reset to zero having no effect on the following condition. You actually want to declare your number variable as a global variable so it doesn't reset:
let number = 0
function Person() {
if(number < 5) {...}
number++
}

You can use a counter to track how many times the function has been called and return early if the limit has been reached. Here's an example:
let counter = 0;
function Person() {
if (counter === 5) {
return;
}
const name = prompt("Enter your name:");
const surname = prompt("Enter your surname:");
const age = prompt("Enter your age:");
console.log(`Name: ${name} Surname: ${surname} Age: ${age}`);
counter++;
}
This way, the function Person will stop running after the 5th time.

If for whatever reason you need to keep track of this on the function itself you can use a closure:
let Person = (function () {
let number = 1;
return function () {
if(number <= 5) {
console.log(`Called ${number} times`);
}
number++
}
})();
for (let i = 0; i < 100;i++) Person();
This defines a function along with a variable which is external to that function.

Related

I was practicing a way to loop numbers to create a times table but the loop only runs one time

I am practicing creating a function that loops whatever number I put into the input into a times table. I used a for loop to achieve this but I ran into an issue. My for loop only runs one time and it only get my input * 10 for some reason. Can someone please help. Thank you.
function myFunction() {
var inputNumber = document.querySelector(".input-field").value;
inputNumber = parseInt(inputNumber);
if (isNaN(inputNumber) || inputNumber == "" || inputNumber == null) {
document.querySelector(".output h1").innerHTML = "Please enter a number!";
} else {
for (i = 1; i <= 10; i++) {
let product = inputNumber * i;
document.querySelector(".output").innerHTML = "<br>" + inputNumber + " * " + i + " = " + product + "<br>";
}
}
}
Looks like you update the HTML on every iteration. However, I think you want to expand the innerHTML to include all elements?
I would look into creating html elements in javascripts and adding them in html like this (draft, untested):
const element = document.createElement("div")
for (let i = 1; i < 10; i++) {
let product = inputNumer * i;
element.appendChild(document.createTextNode(`${inputNumer} ${product}`);
}
Please study this. It is using recommended event listener and a map
const arr = [...Array(11).keys()].slice(1); // numbers from 1 to 10
const h1 = document.querySelector("#output h1"),
result = document.getElementById("result"),
inputField = document.getElementById("inputField");
inputField.addEventListener("input", function() {
const inputNumber = +this.value;
console.log(inputNumber)
h1.classList.toggle("hide", inputNumber); // keep hide if ok number
result.innerHTML = inputNumber ? arr.map(i => `${inputNumber} * ${i} = ${inputNumber*i}`).join(`<br/>`) : "";
});
.hide {
display: none;
}
<input type="number" id="inputField" class=".input-field" />
<hr/>
<div id="output">
<h1 class="error hide">Please enter a number!</h1>
<div id="result">
</div>
</div>

JavaScript arrays adding last element instead of recently added input

Good evening. I am new to JavaScript and I need help with my mini-project and I have only one issue here and it is in the this.Add = function ().
It works properly when I enter a duplicate value from my list therefore it displays an alert that no dupes are allowed. But... when I enter a unique value, it only adds up the last element present (Wash the dishes) from myTasks list. instead of the one I recently entered and the list goes on adding the same ones. Did I just misplace something?
This is my final activity yet and I want to finish it to move to the next function. Thank you in advance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tasks CRUD</title>
<style>
#tasks{
display: none;
}
</style>
</head>
<body>
<center>
<form action="javascript:void(0);" method="POST" onsubmit="app.Add()">
<input type="text" id="add-task" placeholder="Add another card">
<input type="submit" value="Add">
</form>
<div id="tasks" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-task">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
<table>
<tr>
<th>Name</th>
</tr>
<tbody id="myTasks">
</tbody>
</table>
</center>
<script>
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
if (task ) {
for(task of this.myTasks)
{
var ctr = 0;
if(document.getElementById("add-task").value == task){
ctr = 1;
break;
}
}
if(ctr == 1)
{
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task.trim());
// Reset input value
el.value = '';
// Dislay the new list
this.FetchAll();
}
}
};
this.Edit = function (item) {
var el = document.getElementById('edit-task');
// Display value in the field
el.value = this.myTasks[item];
// Display fields
document.getElementById('tasks').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
// Get value
var task = el.value;
if (task) {
// Edit value
self.myTasks.splice(item, 1, task.trim());
// Display the new list
self.FetchAll();
// Hide fields
CloseInput();
}
}
};
this.Delete = function (item) {
// Delete the current row
this.myTasks.splice(item, 1);
// Display the new list
this.FetchAll();
};
}
app.FetchAll();
function CloseInput() {
document.getElementById('tasks').style.display = 'none';
}
</script>
</body>
</html>
In your for loop:
for (task of this.myTask) {
}
You are not declaring a new task variable, but instead assigning to the outer task variable, hence the repeated addition of tasks already in your list.
You can declare a new variable in the for scope like so:
for (const task of this.myTask) {
}
Your HTML as it is.
And your Javascript goes like below. You have a bug while checking if the task already exists in the array. As you're comparing string value either use simple for loop with triple equals or do as i have attached below.
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
console.log(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
console.log(task);
if (task ){
var arrayContainsTask = (this.myTasks.indexOf(task) > -1);
if(arrayContainsTask == true){
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task);
// Reset input value
el.value = '';
}
// Dislay the new list
this.FetchAll();
}
}
}

Javascript passing variable and elementId to an function

var ingaveA = {
stuks: ""
};
var ingaveB = {
prijs: ""
};
var uitgave = {
totaal: ""
};
update(ingaveA, "testa", ingaveB, "testb", uitgave, "testc");
function update(refA, argsA, refB, argsB, refC, argsC) {
refA.stuks = document.getElementById(argsA).value;
refB.prijs = document.getElementById(argsB).value;
refC.totaal = refA.stuks * refB.prijs;
document.getElementById(argsC).value = refC.totaal;
}
ingaveA = ingaveA.stuks;
ingaveB = ingaveB.prijs;
uitgave = uitgave.totaal;
alert("Stuks=" + ingaveA + " Prijs=" + ingaveB + " Totaal=" + uitgave);
<input id="testa" value="10">
<input id="testb" value="6">
<input id="testc" value="">
Is there an better way to do this? always 3 variable names and 3 elements.
Maybe using an array ?
thanks in advance
Instead of using document.getElementById() for every input, you can use document.querySelectorAll() and [id^=test] to select all 3 and put them in a NodeList (think of it as an array).
[id^=test] means every id that starts with test
You can also make one general object, and update it as needed like below.
var ingave = {
ingaveA: {
stuks: ""
},
ingaveB: {
prijs: ""
},
uitgave: {
totaal: ""
}
};
var inputs = document.querySelectorAll("[id^=test]");
update(ingave, inputs);
function update(ref, inputs) {
ref.ingaveA.stuks = inputs[0].value;
ref.ingaveB.prijs = inputs[1].value;
ref.uitgave.totaal = ref.ingaveA.stuks * ref.ingaveB.prijs;
inputs[2].value = ref.uitgave.totaal;
}
var ingaveA = ingave.ingaveA.stuks;
var ingaveB = ingave.ingaveB.prijs;
var uitgave = ingave.uitgave.totaal;
alert("Stuks=" + ingaveA + " Prijs=" + ingaveB + " Totaal=" + uitgave);
<input id="testa" value="10">
<input id="testb" value="6">
<input id="testc" value="">
I'm not really sure what the question is here, but you don't need to create 3 separate objects.
let ingaveA = ""
let ingaveB = ""
let uitgave = ""
then just pass these 3 to your function:
function update(refA, refB, refC) {
refA = document.getElementById("testa").value;
refB = document.getElementById("testb").value;
refC = refA * refB;
document.getElementById("testc").value = refC.totaal;
}
Again, it's hard to optimize it as we don't know your specifics of the code.

javascript document.getElementById Loop

I am trying to make this print out the grades in the array that I created. I can get my for loop to cycle through all of the grades in the array but it only prints out the last grade. I have it set up to print the grade out each time the for loop completes one cycle, but as I said, it is only printing out the last grade. I also tried to use the .innerHTML but that did not work either as you will see in the code:
var arrayTest = [78, 65, 41, 99, 100, 81];
var arrayLength = arrayTest.length;
var midtermTest = 60;
var msg = "";
var grade;
arrayOfGrades();
addBonus();
function tellGrade() {
if (grade > 100) {
msg = "Grade is higher than 100!, " + grade;
}
else if (grade >= 90) {
msg = "You got an A " + grade + "!!, ";
}
else if (grade >= 80) {
msg = "You got a B " + grade + "!!, ";
}
else if (grade >= 70) {
msg = "You got a C " + grade + "!!, ";
}
else if (grade >= 60) {
msg = "You got a D " + grade + "!!, ";
}
else if (grade <= 59) {
msg = "You got a F " + grade + "!! :(, ";
}
else if (grade < 0) {
msg = "Grade is less than 0, " + grade;
}
}
function arrayOfGrades() {
for (var i = 0; i < arrayLength; i++) {
grade = arrayTest[i];
tellGrade(grade);
writeGrade();
}
}
function addBonus()
{
midtermTest = midtermTest + (midtermTest * .05);
grade = midtermTest;
tellGrade(grade);
writeMidtermGrade();
}
function writeGrade() {
//document.getElementById("test").innerHTML = "Test grade letter: " + msg.toString() + "<br />";
var el = document.getElementById('test');
el.textContent = "Test grade letter: " + msg.toString();
}
function writeMidtermGrade() {
var el = document.getElementById('midterm');
el.textContent = "Midterm test grade letter: " + msg.toString();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>DecisionsAndLoopsAssignment1_Byrd</title>
<link href="css/default.css" rel="stylesheet" />
</head>
<body>
<div id="test">Missing grade!!</div>
<div id="midterm">Missing grade!!</div>
<script src="js/main.js"></script>
</body>
</html>
function writeGrade() overwrites whatever might already by in the elements it outputs to. So when called more than once only the last value is preserved. Using .innerHTML would do the same thing. Accumulating the content strings to a single var then making a single call to output them is one option to fix this.
I also note that you're passing temporary values around in global vars, which is generally considered poor form.
You are setting the ENTIRE content of the element not just adding on to it. This will constantly overwrite the work of the previous iteration of the loop, therefore you will only see the last result, cause computers are fast.
You have two options, read the textContent of the element, and continue adding to it. This concept is called self assignment.
var aMessage = "Hello, ";
aMessage += "World!";
console.log(aMessage") // => "Hello, World!"
Though general we would create a new element and append that element as a child
var msg = "A+"; // this should be a variable to our function vs a global va
function writeGrade() {
var el = document.getElementById('test');
var newEl = document.createElement("p");
newEl.textContent = "Test grade letter: " + msg.toString();
el.appendChild(newEl)
}
writeGrade()
<div id="test">
</div>

TypeScript Error

I am getting this awful error when I run this typescript... It says I am passing in the wrong 'type' of argument... This is my first time using typescript, any help would be appreciated.
Here is the error:
Could not apply type 'number' to argument 1 which is of type 'HTMLElement'.
And here is my TS code:
class Offer {
quantity: number;
price: number;
client: string;
constructor (quantity: number, price: number, client: string) {
this.quantity = quantity;
this.price = price;
this.client = name;
}
getSelectedItem() {
var option = $('#ddown :selected').text();
}
}
class Bid {
quantity: number;
price: number;
client: string;
constructor (quantity: number, price: number, client: string) {
this.quantity = quantity;
this.price = price;
this.client = name;
}
getSelectedItem() {
var option = $('#ddown :selected').text();
}
}
function getBid() {
var x = document.getElementById("quantity");
var y = document.getElementById("price");
console.log(y);
var n = document.getElementById("name");
return new Bid(x, y, n);
// $("<tr><td>" + n.value + "</td><td>" + x.value + "X$" + y.value + "</td></tr>").appendTo("#table");
}
function getOffer() {
var x = document.getElementById("quantity");
var y = document.getElementById("price");
console.log(y);
var n = document.getElementById("name");
return new Offer(x, y, n);
// $("<tr><td>" + n.value + "</td><td></td><td>" + x.value + "X$" + y.value + "</td></tr>").appendTo("#table");
}
function append_bid(bid) {
alert("efff you");
$("<tr><td>" + bid.client + "</td><td>" + bid.quantity + "X$" + bid.price+ "</td></tr>").appendTo("#table");
}
function append_offer(offer) {
$("<tr><td>" + offer.client + "</td><td></td><td>" + offer.quantity + "X$" + offer.price + "</td></tr>").appendTo("#table");
}
var bids = [];
var offers = [];
$(document).ready(function(){
$("#submit").click(function(){
var msg = $("#ddown option:selected").text();
if (msg == 'Bid'){
bids.push(getBid());
alert(bids.peek);
append_bid(bids.peek);
console.log('here');
return false;
} else {
offers.push(getOffer());
console.log('whatever');
console.log(offers[0].price);
append_offer(offers.peek);
}
return false;
});
return false;
});
I suppose some HTML wouldn't hurt either...
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Make Dem Trades Boi</title>
</head>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="class.js"></script>
<table id="table">
<tr>
<th>name</th>
<th>bids</th>
<th>offers</th>
</tr>
</table>
<select id="ddown">
<option selected="selected" value="bid">Bid</option>
<option value="offer">Offer</option>
</select>
<form id="form">
Quantity:<input id="quantity" type="number"><br>
Price:<input id="price" type="number"><br>
Name:<input id="name" type="string">
<input id="submit" type="submit" value="Buy">
</form>
</body>
</html>
In getOffer(), here:
return new Offer(x, y, n);
x is an element (and so are y and n). If you want x’s value as a Number, you can use +x.value (or Number(x.value), if you like to be explicit).
The constructor on Bid takes a number, another number and a string:
constructor (quantity: number, price: number, client: string)
You are passing a HTMLElement to each of these. To satisfy the types of the Bid constrcutor, you need to get the data out of each element and parse it, which is reasonably easy to do...
var x = +(<HTMLInputElement>document.getElementById("quantity")).value;
var y = +(<HTMLInputElement>document.getElementById("price")).value;
var n = (<HTMLInputElement>document.getElementById("name")).value;
return new Bid(x, y, n);
To break this answer down, you need to tell the compiler that the HTMLElement is in fact a HTMLInputElement and use the + operator to slacker parse the two numbers.
If you don't like the shorthand + operation, you can use:
var x = parseInt((<HTMLInputElement>document.getElementById("quantity")).value, 10);
var y = parseInt((<HTMLInputElement>document.getElementById("price")).value, 10);
var n = (<HTMLInputElement>document.getElementById("name")).value;
return new Bid(x, y, n);

Categories

Resources