Append Element using DOM manipulation cannot loop through using querySelector - javascript

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>

Related

How to reload current page without losing added list items?

I'm creating something similar to a to-do-list project, but whenever I refresh the page I lose all the added items, I've tried using:
`
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list");
};
`
but still it doesn't work, I may have used it in the wrong place or wrong way. any help please?
here is my full code:
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://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<title>To Do List</title>
</head>
<body>
<section class="section-center">
<form class="todolist-form">
<h3>To Do List!</h3>
<div class="input-button">
<input type="text" id="items-input" placeholder="e.g. eggs" />
<input
type="button"
class="submit-btn"
onclick="addItems()"
value="Submit"
/>
</div>
<div class="added-items">
<ul id="faves"></ul>
</div>
</form>
</section>
<script src="main.js"></script>
</body>
</html>
`
Javascript:
`
function addItems() {
var li = document.createElement("LI");
li.setAttribute("id", "listItem");
var input = document.getElementById("items-input");
li.innerHTML = input.value;
input.value = "";
document.getElementById("faves").appendChild(li);
var deleteBtn = document.createElement("button");
deleteBtn.classList.add("delete-btn");
deleteBtn.innerHTML = "Delete";
deleteBtn.type = "button";
document.getElementById("faves").appendChild(deleteBtn);
var hrzBreak = document.createElement("br");
document.getElementById("faves").appendChild(hrzBreak);
/*********/
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list");
};
}
`
What am I doing wrong? I've included jQuery's CDN too, but still it doesn't work.
var texts = [];
function addItems() {
var input = document.getElementById("items-input");
createElement(input.value)
input.value = "";
}
function createElement(value) {
var li = document.createElement("LI");
li.setAttribute("id", "listItem");
li.innerHTML = value;
document.getElementById("faves").appendChild(li);
var deleteBtn = document.createElement("button");
deleteBtn.classList.add("delete-btn");
deleteBtn.innerHTML = "Delete";
deleteBtn.type = "button";
document.getElementById("faves").appendChild(deleteBtn);
var hrzBreak = document.createElement("br");
document.getElementById("faves").appendChild(hrzBreak);
texts.push(value)
}
window.onbeforeunload = function () {
// Store text array in storage
localStorage.setItem("list", JSON.stringify(texts));
};
window.onload = function () {
// get list grom storage
var list = localStorage.getItem("list");
if (list !== null) {
list = JSON.parse(list)
for (let index = 0; index < list.length; index++) {
const element = list[index];
// create your dom element
createElement(element)
}
}
};
Using an Array to manage the data flow. This will do the job but still a mess.
Try adding event listeners once and outside of your function
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list")
};
function addItems() {
...
}
Assuming that $("#listItem").val() will return the data you want, place below block outsite of the addItems() function
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list");
};

How can I replace element afer another query?

I am writing simple JS app that shows weather. After first query variables like searchTerm or every variable from array are appends to the specific element. But after another query they are not override but added next to the previous one. How can i fix that? Should I use innerHTML or just refresh the page after another API call?
const form = document.querySelector('#searchForm');
const currentTemp = document.querySelector('#temp');
const feelingTemp = document.querySelector('#feelingTemp');
const button = document.querySelector('button');
const img = document.createElement('img');
const searchCity = document.querySelector('#searchingCity');
const sky = document.querySelector('#skyStatus');
const bg_image = document.querySelector('.left-container');
const moreInfo = document.querySelector('.right-container');
const getWeather = async () => {
try{
const searchTerm = form.elements.query.value
const res = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${searchTerm}&units=metric&appid=3861eeae573a8188b76a2d6c0ceccfb9`)
let getTemp = res.data.main.temp,
getFeelsTemp = res.data.main.feels_like,
getTempMin = res.data.main.temp_min,
getTempMax = res.data.main.temp_max,
getPressure = res.data.main.pressure,
getHumidity = res.data.main.humidity;
getSkyIcon = res.data.weather[0].main
searchCity.append(searchTerm)
form.elements.query.value = '';
return [getTemp, getFeelsTemp, getTempMin, getTempMax, getPressure, getHumidity, getSkyIcon]
} catch (e){
return "WEATHER SERVICE IS DOWN :("
}
}
const runApp = async () => {
form.addEventListener('submit', async function (e) {
e.preventDefault()
const [resTemp, resFeelsTemp, resTempMin, resTempMax, resPressure, resHumidity, resSkyIcon] = await getWeather()
// Głowny kontener informacyjny
currentTemp.append(`${Math.floor(resTemp)}°C`)
if(resSkyIcon === 'Clear'){
img.src = "./img/sun.png"
let finalImg = document.querySelector('#skyStatus')
finalImg.appendChild(img)
bg_image.style.backgroundImage = "url('img/sunny_bg.jpg')"
}else if(resSkyIcon === 'Clouds'){
img.src = "./img/cloud.png"
let finalImg = document.querySelector('#skyStatus')
finalImg.appendChild(img)
bg_image.style.backgroundImage = "url('img/cloud_bg.jpg')"
}else{
img.src = "./img/rain.png"
let finalImg = document.querySelector('#skyStatus')
finalImg.appendChild(img)
bg_image.style.backgroundImage = "url('img/rain_bg.jpg')"
}
// Right box
const array = [
`Feels temp ${Math.floor(resFeelsTemp)}°C`,
`Temp min ${Math.floor(resTempMin)}°C`,
`Temp max ${Math.floor(resTempMax)}°C`,
`Pressure ${resPressure}HPa`,
`Humidity ${resHumidity}%`
]
const ul = document.querySelector('ul');
array.forEach((value) =>{
const li = document.createElement('li');
li.innerText = value
ul.appendChild(li)
})
})
}
runApp();
<!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>WeatherApp - Rob</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="left-container">
<div class="form-container">
<form id="searchForm">
<input type="text" placeholder="Weather in" name="query" id="searchInput">
</form>
</div>
<div class="weather-output">
<h2 id="temp"></h2>
<h2 id="searchingCity"></h2>
<h2 id="skyStatus"></h2>
</div>
<div class="right-container">
<h2 id="right-header">Informacje dodatkowe</h2>
<div class="more-info-container">
<ul></ul>
</div>
</div>
</div>
<script src="./app2.js"></script>
</body>
</html>
You need to clear result that you get before
Just add:
searchCity.innerHTML = '';
...
currentTemp.innerHTML = '';
....
ul.innerHTML = '';
const form = document.querySelector('#searchForm');
const currentTemp = document.querySelector('#temp');
const feelingTemp = document.querySelector('#feelingTemp');
const button = document.querySelector('button');
const img = document.createElement('img');
const searchCity = document.querySelector('#searchingCity');
const sky = document.querySelector('#skyStatus');
const bg_image = document.querySelector('.left-container');
const moreInfo = document.querySelector('.right-container');
const getWeather = async () => {
try{
const searchTerm = form.elements.query.value
const res = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${searchTerm}&units=metric&appid=3861eeae573a8188b76a2d6c0ceccfb9`)
let getTemp = res.data.main.temp,
getFeelsTemp = res.data.main.feels_like,
getTempMin = res.data.main.temp_min,
getTempMax = res.data.main.temp_max,
getPressure = res.data.main.pressure,
getHumidity = res.data.main.humidity;
getSkyIcon = res.data.weather[0].main
searchCity.innerHTML = '';
searchCity.append(searchTerm)
form.elements.query.value = '';
return [getTemp, getFeelsTemp, getTempMin, getTempMax, getPressure, getHumidity, getSkyIcon]
} catch (e){
return "WEATHER SERVICE IS DOWN :("
}
}
const runApp = async () => {
form.addEventListener('submit', async function (e) {
e.preventDefault()
const [resTemp, resFeelsTemp, resTempMin, resTempMax, resPressure, resHumidity, resSkyIcon] = await getWeather()
// Głowny kontener informacyjny
currentTemp.innerHTML = '';
currentTemp.append(`${Math.floor(resTemp)}°C`)
if(resSkyIcon === 'Clear'){
img.src = "./img/sun.png"
let finalImg = document.querySelector('#skyStatus')
finalImg.appendChild(img)
bg_image.style.backgroundImage = "url('img/sunny_bg.jpg')"
}else if(resSkyIcon === 'Clouds'){
img.src = "./img/cloud.png"
let finalImg = document.querySelector('#skyStatus')
finalImg.appendChild(img)
bg_image.style.backgroundImage = "url('img/cloud_bg.jpg')"
}else{
img.src = "./img/rain.png"
let finalImg = document.querySelector('#skyStatus')
finalImg.appendChild(img)
bg_image.style.backgroundImage = "url('img/rain_bg.jpg')"
}
// Right box
const array = [
`Feels temp ${Math.floor(resFeelsTemp)}°C`,
`Temp min ${Math.floor(resTempMin)}°C`,
`Temp max ${Math.floor(resTempMax)}°C`,
`Pressure ${resPressure}HPa`,
`Humidity ${resHumidity}%`
]
const ul = document.querySelector('ul');
ul.innerHTML = '';
array.forEach((value) =>{
const li = document.createElement('li');
li.innerText = value
ul.appendChild(li)
})
})
}
runApp();
<!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>WeatherApp - Rob</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="left-container">
<div class="form-container">
<form id="searchForm">
<input type="text" placeholder="Weather in" name="query" id="searchInput">
</form>
</div>
<div class="weather-output">
<h2 id="temp"></h2>
<h2 id="searchingCity"></h2>
<h2 id="skyStatus"></h2>
</div>
<div class="right-container">
<h2 id="right-header">Informacje dodatkowe</h2>
<div class="more-info-container">
<ul></ul>
</div>
</div>
</div>
<script src="./app2.js"></script>
</body>
</html>

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>

random string generators overwriting each other

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>

Target and update a specific element in a table with JavaScript

I have an assignment to build a simple static CRUD page using nothing but HTML, CSS, and JavaScript. I'm almost done but I can't for the life of me figure out how to make the update function work.
The idea is to click on the pencil icon and then rewrite whatever is in that field. However, I'm unable to figure out how to expand that functionality to all three fields, it just works on one.
Heres the page. If you click on "cadastrar-se" it will create three "td" with the pencil, but only one works(the one saying "locado?"). Snippets are below but I used localStorage so it won't run properly.
The function of interest is at the bottom of the page, called "updateItems()".
I thank you in advance for any help.
const createTd = item => {
const Td = document.createElement("td");
Td.innerHTML = item;
return Td;
};
const createTdWithI = item => {
const Td = document.createElement("td");
const i = document.createElement("i");
Td.innerHTML = item;
Td.setAttribute("class", "tdEdit");
Td.appendChild(i).setAttribute("class", "fas fa-edit");
return Td;
}
const appendChildren = (parent, children) => {
children.forEach(child => {
parent.setAttribute("class", "tr");
parent.appendChild(child);
});
};
document.querySelector("#addClientBtn").addEventListener("click", () => {
const clientName = document.querySelector("#name").value;
const clientMovie = document.querySelector("#movie").value;
const clientLocado = document.querySelector("#rentStatus").value;
localStorage.setItem("clientName", clientName);
localStorage.setItem("clientMovie", clientMovie);
localStorage.setItem("clientLocado", clientLocado);
const getTbody = document.querySelector("#tbody");
const createTr = document.createElement("tr");
const appendTr = getTbody.appendChild(createTr);
const items = [
createTdWithI(localStorage.getItem("clientName")),
createTdWithI(localStorage.getItem("clientMovie")),
createTdWithI(localStorage.getItem("clientLocado")),
createTd('<i class="fas fa-trash"></i>')
];
appendChildren(appendTr, items);
deleteRow();
updateItems();
});
// Deleta as linhas na tabela
function deleteRow() {
let trashIcon = document.querySelectorAll(".fa-trash");
trashIcon[trashIcon.length - 1].addEventListener("click", event => {
trashIcon = event.target;
trashIcon.parentNode.parentNode.parentNode.removeChild(trashIcon.parentNode.parentNode);
});
}
function updateItems() {
let editIcon = document.querySelectorAll(".fa-edit");
// let targetText = document.querySelectorAll(".tdEdit");
editIcon[editIcon.length - 1].addEventListener("click", event => {
editIcon = event.target;
editIcon.innerText = "test";
// for (let i = 0; i < editIcon.length; i++) {
// editIcon.length = i;
// editIcon[i] = event.target;
// editIcon[i].innerText = "testLocado";
// }
// if (editIcon.length === editIcon.length - 1) {
// editIcon = event.target;
// editIcon.innerText = "testLocado";
// } else if (editIcon.length === editIcon.length - 2) {
// editIcon = event.target;
// editIcon.parentNode.innerText = "testFilme";
// } else if (editIcon.length === editIcon.length - 3) {
// editIcon = event.target;
// editIcon.parentNode.innetText = "testNome";
// }
});
}
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8" />
<meta name="author" content="Renan Martineli de Paula" />
<meta name="description" content="locadora de filmes Nova Singular processo seletivo desenvolvimento - sistema" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.1/css/all.css" integrity="sha384-vp86vTRFVJgpjF9jiIGPEEqYqlDwgyBgEF109VFjmqGmIY/Y4HV4d3Gp2irVfcrp" crossorigin="anonymous">
<!-- <link type="text/css" rel="stylesheet" href="reset.css" /> -->
<link type="text/css" rel="stylesheet" href="styles.css" />
<script src="sistema.js" defer></script>
<title>Sistema</title>
</head>
<body>
<h1>Bem vindo(a), <span id="userNameWelcome"></span>.
<fieldset>
<legend>Cadastrar cliente</legend>
<label for="name">
<p>Nome</p>
<input type="text" id="name" required />
</label>
<label for="movie">
<p>Filme</p>
<input type="text" id="movie" required />
</label>
<br />
<label for="rentStatus">
<span>Locado?</span>
<select name="locado" id="rentStatus" required>
<option value="Sim">Sim</option>
<option value="Não">Não</option>
</select>
</label>
<br />
<button id="addClientBtn">Cadastrar</button>
</fieldset>
<input type="text" id="searchMenu" placeholder="Procure por clientes"/>
<table id="clientTable">
<thead>
<tr>
<th>Nome</th>
<th>Filme</th>
<th>Locado?</th>
<!-- <th>Modificar</th> -->
<th>Deletar</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</body>
<script>
// Mostra o nome do usuário na tela de boas vindas
document.querySelector("#userNameWelcome").innerHTML = localStorage.getItem("userName");
</script>
</html>
Try this
function updateItems() {
let editIcon = document.querySelectorAll(".fa-edit");
// let targetText = document.querySelectorAll(".tdEdit");
for(let icon of editIcon){
icon.addEventListener('click', (event)=>{
editIcon = event.target;
editIcon.innerText = "test";
}, false);
}

Categories

Resources