random string generators overwriting each other - javascript

I am very new to Javascript and am writing a little webapp that, among other things, generates random strings (used for visualisation, doesn't need to be perfectly random).
The site consists of three divs, which each should generate a random string. On pageload, the divs display 20 hyphens as visual placeholders. Within each div I then want to replace one hyphen after the other with a random character, waiting 100ms between each iteration.
I got this working just fine with one div. But as soon as I do this with multiple divs, each randomly generated character gets immediately overwritten by the almost simultaneously randomly generated character in the following div.
I also added a console.log, so you can see that initially, each div generates a random character, but then the third div overwrites the character in the two other divs.
I'm assuming this is something I'm just not getting yet, so my question:
How can I keep this from happening, so that each div keeps its own string (and why is this happening in the first place)?
Thanks for your help, let me know if you need anything else!
const placeholderLength = 20;
let valueForm = [],
valueModus = [],
valueInhalt = [],
placeholder = [];
let valueJoined;
const outputForm = document.getElementById("outputForm");
const outputModus = document.getElementById("outputModus");
const outputInhalt = document.getElementById("outputInhalt");
const randomCharacter = () => {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
return characters.charAt(Math.floor(Math.random() * characters.length));
};
const initialValues = (value, destination, identifier) => {
let i = 0;
const loop = () => {
setTimeout(() => {
value[i] = randomCharacter();
valueJoined = value.join("");
destination.innerHTML = valueJoined;
i++;
if (i < placeholderLength) {
loop();
}
console.log(identifier, valueJoined);
}, 100);
};
loop();
};
const main = () => {
for (let i = 0; i < placeholderLength; i++) {
placeholder.push("-");
}
valueForm = valueModus = valueInhalt = placeholder;
initialValues(valueForm, outputForm, "value 1");
initialValues(valueModus, outputModus, "value 2");
initialValues(valueInhalt, outputInhalt, "value 3");
};
main();
.output {
font-family: monospace;
letter-spacing: 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="main.css" />
<title>Document</title>
</head>
<body>
<h1>Random Values</h1>
<h2>Value 1</h2>
<div id="outputForm" class="output"></div>
<h2>Value 2</h2>
<div id="outputModus" class="output"></div>
<h2>Value 3</h2>
<div id="outputInhalt" class="output"></div>
</body>
<script src="app.js"></script>
</html>

The problem is that you assign the same placeholder array to all three generators. Since arrays are objects and objects are passed (and assigned) by reference, after this line:
valueForm = valueModus = valueInhalt = placeholder
...they will point to the same array object. Mutating that object will change it for each generator.
To solve the issue, remove that line:
const placeholderLength = 20;
let valueForm = [],
valueModus = [],
valueInhalt = [],
placeholder = [];
let valueJoined;
const outputForm = document.getElementById("outputForm");
const outputModus = document.getElementById("outputModus");
const outputInhalt = document.getElementById("outputInhalt");
const randomCharacter = () => {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
return characters.charAt(Math.floor(Math.random() * characters.length));
};
const initialValues = (value, destination, identifier) => {
let i = 0;
const loop = () => {
setTimeout(() => {
value[i] = randomCharacter();
valueJoined = value.join("");
destination.innerHTML = valueJoined;
i++;
if (i < placeholderLength) {
loop();
}
console.log(identifier, valueJoined);
}, 100);
};
loop();
};
const main = () => {
for (let i = 0; i < placeholderLength; i++) {
placeholder.push("-");
}
//valueForm = valueModus = valueInhalt = placeholder;
initialValues(valueForm, outputForm, "value 1");
initialValues(valueModus, outputModus, "value 2");
initialValues(valueInhalt, outputInhalt, "value 3");
};
main();
.output {
font-family: monospace;
letter-spacing: 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="main.css" />
<title>Document</title>
</head>
<body>
<h1>Random Values</h1>
<h2>Value 1</h2>
<div id="outputForm" class="output"></div>
<h2>Value 2</h2>
<div id="outputModus" class="output"></div>
<h2>Value 3</h2>
<div id="outputInhalt" class="output"></div>
</body>
<script src="app.js"></script>
</html>
To assign hyphens to the arrays, you can clone the array (e.g. by using Array#slice()):
const placeholderLength = 20;
let valueForm = [],
valueModus = [],
valueInhalt = [],
placeholder = [];
let valueJoined;
const outputForm = document.getElementById("outputForm");
const outputModus = document.getElementById("outputModus");
const outputInhalt = document.getElementById("outputInhalt");
const randomCharacter = () => {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
return characters.charAt(Math.floor(Math.random() * characters.length));
};
const initialValues = (value, destination, identifier) => {
let i = 0;
const loop = () => {
setTimeout(() => {
value[i] = randomCharacter();
valueJoined = value.join("");
destination.innerHTML = valueJoined;
i++;
if (i < placeholderLength) {
loop();
}
console.log(identifier, valueJoined);
}, 100);
};
loop();
};
const main = () => {
for (let i = 0; i < placeholderLength; i++) {
placeholder.push("-");
}
valueForm = placeholder.slice();
valueModus = placeholder.slice();
valueInhalt = placeholder.slice();
initialValues(valueForm, outputForm, "value 1");
initialValues(valueModus, outputModus, "value 2");
initialValues(valueInhalt, outputInhalt, "value 3");
};
main();
.output {
font-family: monospace;
letter-spacing: 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="main.css" />
<title>Document</title>
</head>
<body>
<h1>Random Values</h1>
<h2>Value 1</h2>
<div id="outputForm" class="output"></div>
<h2>Value 2</h2>
<div id="outputModus" class="output"></div>
<h2>Value 3</h2>
<div id="outputInhalt" class="output"></div>
</body>
<script src="app.js"></script>
</html>
You can also move the slicing part to the initialvalues function, you don't have to repeat yourself:
const placeholderLength = 20;
let valueForm,
valueModus,
valueInhalt,
placeholder = [];
let valueJoined;
const outputForm = document.getElementById("outputForm");
const outputModus = document.getElementById("outputModus");
const outputInhalt = document.getElementById("outputInhalt");
const randomCharacter = () => {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
return characters.charAt(Math.floor(Math.random() * characters.length));
};
const initialValues = (originalValue, destination, identifier) => {
let i = 0;
const value = originalValue.slice()
const loop = () => {
setTimeout(() => {
value[i] = randomCharacter();
valueJoined = value.join("");
destination.innerHTML = valueJoined;
i++;
if (i < placeholderLength) {
loop();
}
console.log(identifier, valueJoined);
}, 100);
};
loop();
};
const main = () => {
for (let i = 0; i < placeholderLength; i++) {
placeholder.push("-");
}
valueForm = valueModus = valueInhalt = placeholder;
initialValues(valueForm, outputForm, "value 1");
initialValues(valueModus, outputModus, "value 2");
initialValues(valueInhalt, outputInhalt, "value 3");
};
main();
.output {
font-family: monospace;
letter-spacing: 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="main.css" />
<title>Document</title>
</head>
<body>
<h1>Random Values</h1>
<h2>Value 1</h2>
<div id="outputForm" class="output"></div>
<h2>Value 2</h2>
<div id="outputModus" class="output"></div>
<h2>Value 3</h2>
<div id="outputInhalt" class="output"></div>
</body>
<script src="app.js"></script>
</html>

Related

How do I get the result of this this Random Numbers generated in Javascript? I mean so I can alert or send to console

This piece of javascript successfully generated random number but I'm having challenge in fetching the variable value so I can use it as desired. below is the working code:
let btn = document.querySelector('button');
let output = document.querySelector('#output');
function getRandomNumber(min, max) {
let step1 = max - min + 1;
let step2 = Math.random() * step1;
let result = Math.floor(step2) + min;
return result;
}
function createArrayOfNumbers(start, end){
let myArray = [];
for(let i = start; i <= end; i++) {
myArray.push(i);
}
return myArray;
}
let numbersArray = createArrayOfNumbers(1,10);
btn.addEventListener('click', () => {
if(numbersArray.length == 0){
output.innerText = 'No More Random Numbers';
return;
}
let randomIndex = getRandomNumber(0, numbersArray.length-1);
let randomNumber = numbersArray[randomIndex];
numbersArray.splice(randomIndex, 1)
output.innerText = randomNumber;
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>Generate</button>
<h1 id="output" style="text-align: center">Random Number</h1>
<script src="script.js"></script>
</body>
</html>
There are several ways of doing but the easiest would be to create a global variable outside the function and then when that random number is generated assign that number to that global variable you can write it like this:
var myvariable = 0;
let btn = document.querySelector('button');
let output = document.querySelector('#output');
//all of your code and then at the end
numbersArray.splice(randomIndex, 1)
output.innerText = randomNumber;
myvariable = randomNumber;
});
Now this variable is accessible outside the function. Hope that helps!

caroussel not displaying image in JS

i've a problem with my caroussel in JS
He just don't recognize my innerHTML, in fact when i look on the inspector, he don't recognize the on my innerHTML, i've done some research and didn't found anything (showing
<img src = unknown/>.
My img array is an url array not in any folder.
Here's what i already have
function slideShow() {
var counter = 0;
slideShow();
const diapoImages = [
"https://images.unsplash.com/photo-1652044049927-7142ea82c81d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1639718561716-b59d3995d886?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1653593349937-1a2a29a614d2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1742&q=80",
"https://images.unsplash.com/photo-1653629154297-d01874fe01c7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1653537649117-821e01f707c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
];
var imgDiv = document.getElementById("header");
if (counter < diapoImages.length) {
var img = diapoImages[counter];
imgDiv.innerHTML = `<img src=${img}/>`;
counter += 1;
}
else {
counter = 0;
}
setTimeout(slideShow, 5000)
}
here's the HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://kit.fontawesome.com/c9b7852654.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="css/style.css">
<title>Diaporama</title>
</head>
<body>
<i id = "nav-gauche" class="fa-solid fa-arrow-left-long"></i>
<i id = "nav-droite" class="fa-solid fa-arrow-right-long"></i>
<div class="container">
<h1>Javascript Caroussel</h1>
<h2>Test d'un caroussel en JS</h2>
<div id="header">
</div>
</div>
<script src=""></script>
</body>
</html>
You should create the image tag using document.createElement("img"). Then, you should set the src of image tag. At the end of the function, you should append the image tag into the div tag.
function slideShow() {
var counter = 0;
slideShow();
const diapoImages = [
"https://images.unsplash.com/photo-1652044049927-7142ea82c81d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1639718561716-b59d3995d886?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1653593349937-1a2a29a614d2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1742&q=80",
"https://images.unsplash.com/photo-1653629154297-d01874fe01c7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1653537649117-821e01f707c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
];
var imgDiv = document.getElementById("header");
var image = document.createElement("img")
for (var ind in diapoImages)
while ( ind < (diapoImages.length + 1)){
if (counter < diapoImages.length) {
var img = diapoImages[counter];
imgDiv.appendChild(image)
counter += 1;
image.src = img
}
else {
counter = 0;
}
}
}
setTimeout(slideShow, 5000)
I don't know about innerHTML error, but I could see two important points that maybe help you.
The line 3 (slideShow();) causes recursive calls.
Whenever the function is invoked, line 2 (counter = 0;) will reset the value. So the second image will never be rendered.
function slideShow(counter = 0) {
const diapoImages = [
"https://images.unsplash.com/photo-1652044049927-7142ea82c81d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1639718561716-b59d3995d886?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1653593349937-1a2a29a614d2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1742&q=80",
"https://images.unsplash.com/photo-1653629154297-d01874fe01c7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
"https://images.unsplash.com/photo-1653537649117-821e01f707c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80",
];
var imgDiv = document.getElementById("header");
if (counter < diapoImages.length) {
var img = diapoImages[counter];
imgDiv.innerHTML = `<img src=${img}/>`;
counter += 1;
} else {
counter = 0;
}
setTimeout(() => slideShow(counter), 5000)
}
slideShow();
<div id="header"></div>

Using PokeAPI to fetch data. Can't figure out why span element is not updating

So I'm using the PokeAPI to fetch the name of a Pokemon, then shuffling that name, and the user is supposed to guess what it is in the input. If they don't know then they can click the next button and it reshuffles a new mon. If they guess right they can press the same next button for a new mon. Each time they guess right the score increases by 1. That's working but I cant figure out why the out of/total games span isn't updating as well. Please excuse my terrible attempt at JS I'm very new if you can help me make my code look better that would be great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="style.css" />
<title>Who's that Pkmn?</title>
</head>
<body>
<header>
<h1>Who's that Pokemon?!</h1>
</header>
<div id="jumble">?????</div>
<div class="container">
<input id="guess" type="text" placeholder="enter pkmn name" />
<button id="submit" class="btn" type="submit">go</button>
<button id="next" class="btn">next</button>
<p id="msg">unshuffle the letters</p>
</div>
<div id="scorekeepers">
<p>Score: <span id="score">0</span>
out of: <span id="gamesPlayed">0</span></p>
</div>
<script src="script.js"></script>
</body>
</html>
let jumbledName = document.querySelector("#jumble");
let guessInput = document.querySelector('#guess')
let submitButton = document.querySelector('#submit')
let nextButton=document.querySelector('#next')
let messageDisplay = document.querySelector('#msg')
let score = document.querySelector('#score')
let gamesPlayed = document.querySelector('#gamesPlayed')
score = 0;
gamesPlayed = 0;
let getPokemonName = function() {
fetch(`https://pokeapi.co/api/v2/pokemon/${Math.floor(Math.random()*151+1)}/`)
.then(function(response) {
return response.json();
})
.then(function(data) {
const pokeName = data.name;
const pokeNameJumbled = pokeName.shuffle();
displayInfomation(pokeName, pokeNameJumbled);
});
};
getPokemonName();
guessInput.value=''
// pokeNameJumbled=''
const displayInfomation = function(name, jumbledName) {
pokeName = name;
pokeNameJumbled = jumbledName;
jumble.textContent = jumbledName;
};
const displayMessage = function(message) {
document.querySelector("#msg").textContent = message;
};
const checkName = function () {
document.querySelector("#guess").textContent = guessInput;
const guess = document.querySelector("#guess").value.toLowerCase();
if (!guess) {
displayMessage("No guess entered!");
} else if (guess === pokeName) {
displayMessage(`Thats correct! It's ${pokeName}!`)
score++
document.querySelector("#score").textContent = score;
guessInput.value=''
} else if (guess != pokeName) {
displayMessage(`Wrong!`);
document.querySelector("#gamesPlayed").textContent = gamesPlayed;
}
};
submitButton.addEventListener('click', checkName)
nextButton.addEventListener('click',getPokemonName)
String.prototype.shuffle = function() {
var a = this.split(""),
n = a.length;
for (var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
};

How to calculate cashback value using .reduce() method from input value?

I need to make a form where the user can enter the name of the purchase and its value. With each addition, the cashback costs should be calculated automatically (via reduce method). Cashback is 0.5%. All purchases must be contained in the purchases array and have exactly three properties:
id - number
name - string (name of Purchase)
price - number (price of Purchase)
I can't seem to figure out how to use reduce method to calculate cashback value. Besides each cashback value, total cashback should be displayed as well.
let nextId = 1;
const purchases = [];
const cashback = 0.005;
const commentForm = document.querySelector('[data-id="purchase-form"]');
const nameInput = commentForm.querySelector('[data-input="name"]');
const priceInput = commentForm.querySelector('[data-input="price"]');
const button = commentForm.querySelector('[data-input="price"]');
const purchasesList = document.querySelector('[data-id="purchases-list"]');
button.addEventListener('click', () => {
if (nameInput.value != '' && priceInput.value != '') {
purchases.push({
id: nextId++,
name: nameInput.value,
price: priceInput.value,
});
}
createElement(nameInput.value);
nameInput.value = '';
});
function createElement(ci) {
const newPurchase = document.createElement('li');
newPurchase.setAttribute('data-comment-id', nextId - 1);
newPurchase.textContent = `${ci} for sum of ${priceInput.value} $. (cashback- ${cashbackSum})`;
purchasesList.appendChild(newPurchase);
}
function cashbackSum() {
return Number(priceInput, 10) * cashback;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<link rel="stylesheet" href="./css/styles.css" />
</head>
<body>
<div id="root">
<form data-id="purchase-form">
<input data-input="name" />
<input data-input="price" />
<button type="button" data-action="add">Add</button>
</form>
<ul data-id="purchases-list"></ul>
<div>Total cashback is: <span data-id="total cashback"></span></div>
</div>
<script src="./js/app.js"></script>
</body>
</html>
There seemed to be a few bugs in the given snippet:
You are not getting the value of input box on each click so array is not going to contain the new values. [Make them let instead of const and fetch value on each button click event]
CashbackSum function was not being called.
Created a function for totalCashback that uses the reduce method of array to get the total cashback sum.
let nextId = 1;
const purchases = [];
const cashback = 0.005;
const commentForm = document.querySelector('[data-id="purchase-form"]');
let nameInput = commentForm.querySelector('[data-input="name"]');
let priceInput = commentForm.querySelector('[data-input="price"]');
const button = commentForm.querySelector('[data-action="add"]');
const purchasesList = document.querySelector('[data-id="purchases-list"]');
const totalCashback = document.querySelector('[data-id="total cashback"]');
const errorMsg = document.querySelector('[data-id="error"]');
button.addEventListener('click', () => {
nameInput = commentForm.querySelector('[data-input="name"]');
priceInput = commentForm.querySelector('[data-input="price"]');
if (nameInput.value != '' && priceInput.value != '') {
purchases.push({
id: nextId++,
name: nameInput.value,
price: priceInput.value,
});
createElement(nameInput.value);
nameInput.value = '';
errorMsg.textContent = '';
totalCashback.textContent = calculateTotalCashback() + ' $.';
}else{
errorMsg.textContent = 'Please fill both the fields: [name and price]';
}
});
function createElement(ci) {
const newPurchase = document.createElement('li');
newPurchase.setAttribute('data-comment-id', nextId - 1);
newPurchase.textContent = `${ci} for sum of ${priceInput.value} $. (cashback- ${cashbackSum()})`;
purchasesList.appendChild(newPurchase);
}
function cashbackSum() {
return Number(priceInput.value, 10) * cashback;
}
function calculateTotalCashback() {
return purchases.reduce((sum, item) => {
return sum + (parseFloat(item.price, 10) * cashback);
}, 0);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<link rel="stylesheet" href="./css/styles.css" />
</head>
<body>
<div id="root">
<form data-id="purchase-form">
<input data-input="name" />
<input data-input="price" />
<button type="button" data-action="add">Add</button>
<br /><span data-id="error"></span>
</form>
<ul data-id="purchases-list"></ul>
<div>Total cashback is: <span data-id="total cashback"></span></div>
</div>
<script src="./js/app.js"></script>
</body>
</html>

Append Element using DOM manipulation cannot loop through using querySelector

I'm trying to loop through the element that i create using DOM manipulation. it was successfully reflected in the html page but when i loop through in it using queryselector, its not looping. I also tried using getElementByClassName and still not looping.
here is the part of the code which I'm pointing out:
I also attached the whole javascript code with html for reference:
const selected = document.querySelector(".selected");
const optionsContainer = document.querySelector(".options-container");
window.addEventListener('DOMContentLoaded', () => {
createNewOption1();
createNewOption2();
});
const optionsList = document.querySelectorAll(".option");
selected.addEventListener("click", () => {
optionsContainer.classList.toggle("active");
});
optionsList.forEach(o => {
o.addEventListener("click", () => {
selected.innerHTML = o.querySelector("label").innerHTML;
optionsContainer.classList.remove("active");
});
});
const createNewOption1 = () => {
const div1 = document.createElement('div');
const input1 = document.createElement('input');
const label1 = document.createElement('label');
div1.className = 'option';
input1.type = 'radio';
input1.className = 'radio';
input1.name = 'category';
label1.htmlFor = 'Rejuvenating';
label1.innerHTML = 'Rejuvenating Set';
div1.appendChild(input1);
div1.appendChild(label1);
optionsContainer.appendChild(div1);
}
const createNewOption2 = () => {
const div2 = document.createElement('div');
const input2 = document.createElement('input');
const label2 = document.createElement('label');
div2.className = 'option';
input2.type = 'radio';
input2.className = 'radio';
input2.name = 'category';
label2.htmlFor = 'Maintenance';
label2.innerHTML = 'Maintenance Set';
div2.appendChild(input2);
div2.appendChild(label2);
optionsContainer.appendChild(div2);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database Project</title>
<script src="https://kit.fontawesome.com/d6307e6979.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2>Sales</h2>
<div class="select-box">
<div class="options-container">
</div>
<div class="selected">
<p>Select Item</p>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
You're creating the options in the DOMContentLoaded event listener. But you're calling querySelectorAll(".option") outside the listener, so the options don't exist yet. Move that code inside the listener.
const selected = document.querySelector(".selected");
const optionsContainer = document.querySelector(".options-container");
window.addEventListener('DOMContentLoaded', () => {
createNewOption1();
createNewOption2();
const optionsList = document.querySelectorAll(".option");
optionsList.forEach(o => {
o.addEventListener("click", () => {
selected.innerHTML = o.querySelector("label").innerHTML;
optionsContainer.classList.remove("active");
});
});
});
selected.addEventListener("click", () => {
optionsContainer.classList.toggle("active");
});
const createNewOption1 = () => {
const div1 = document.createElement('div');
const input1 = document.createElement('input');
const label1 = document.createElement('label');
div1.className = 'option';
input1.type = 'radio';
input1.className = 'radio';
input1.name = 'category';
label1.htmlFor = 'Rejuvenating';
label1.innerHTML = 'Rejuvenating Set';
div1.appendChild(input1);
div1.appendChild(label1);
optionsContainer.appendChild(div1);
}
const createNewOption2 = () => {
const div2 = document.createElement('div');
const input2 = document.createElement('input');
const label2 = document.createElement('label');
div2.className = 'option';
input2.type = 'radio';
input2.className = 'radio';
input2.name = 'category';
label2.htmlFor = 'Maintenance';
label2.innerHTML = 'Maintenance Set';
div2.appendChild(input2);
div2.appendChild(label2);
optionsContainer.appendChild(div2);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database Project</title>
<script src="https://kit.fontawesome.com/d6307e6979.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2>Sales</h2>
<div class="select-box">
<div class="options-container">
</div>
<div class="selected">
<p>Select Item</p>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>

Categories

Resources