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

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>

Related

i want to know if my code is correct and after i want when user give age<18 the onclick button disappears

i try to do this: Create a web page using HTML and JavaScript. On the website where your name will appear. · Fill in a table with Student Objects. · These objects have 3 fields (fullname, age, amka). The creation of these objects will be done using Constructor (Note the fullname field is the name and is given as follows: "First name - Last name" · The table that is filled until an object is given under the age of 18. ATTENTION this object does not will be inserted in the table.
<!DOCTYPE html>
<html lang="en">
<script>
function createPerson() {
var fullname = document.getElementById('inputValueFullname').value;
var age = document.getElementById('inputValueAge').value;
var amka = document.getElementById('inputValueAmka').value;
function person(fullname, age, amka) {
this.fullname = fullname;
this.age = age;
this.amka = amka;
}
var myArray = [];
var NewPerson = new person(fullname, age, amka);
if(age && age>= 18 && fullname && amka){
myArray.push(NewPerson)
} else {
}
console.log(NewPerson);
}
</script>
<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>Document</title>
</head>
<body>
<label>Fullname: <input type="text" id="inputValueFullname"></label>
<label>Age:<input type="text" id="inputValueAge"></label>
<label>Amka:<input type="text" id="inputValueAmka"></label>
<button type="button" onclick=" createPerson();">Add</button>
<table id="table">
<thead>
<tr>
<th>Name/Surname</th>
<th>Age</th>
<th>AMKA</th><br><br><br><br><br>
</tr>
</thead>
</table>
</body>
</html>
First off, I assume AMKA is an identification number as when i tried searching what is that about and the only result i got was a company or a greek citizen ID. The JavaScript function to print data to table can be done without using any array.
<script>
function publishToTable() {
const fullname = document.getElementById('fullname').value;
const age = document.getElementById('age').value;
const amka = document.getElementById('amka').value;
const error = document.getElementById('error');
if (age && age>= 18 && fullname && amka) {
const tableElement = document.getElementById('table');
const trElement = document.createElement('tr');
const tbodyElement = document.createElement('tbody');
const fullnameEle = document.createElement('td');
const ageEle = document.createElement('td');
const amkaEle = document.createElement('td');
fullnameEle.innerHTML = fullname;
ageEle.innerHTML = age;
amkaEle.innerHTML = amka;
trElement.appendChild(fullnameEle);
trElement.appendChild(ageEle);
trElement.appendChild(amkaEle);
tbodyElement.appendChild(trElement);
tableElement.appendChild(tbodyElement);
}
}
</script>
I think i fixed your issue:
js_issue_solved.html
Full Code:
// <!DOCTYPE html>
<html lang="en">
<script>
function publishToTable() {
const fullname = document.getElementById('fullname').value;
const age = document.getElementById('age').value;
const amka = document.getElementById('amka').value;
const error = document.getElementById('error');
if (age && age>= 18 && fullname && amka) {
const tableElement = document.getElementById('table');
const trElement = document.createElement('tr');
const tbodyElement = document.createElement('tbody');
const fullnameEle = document.createElement('td');
const ageEle = document.createElement('td');
const amkaEle = document.createElement('td');
fullnameEle.innerHTML = fullname;
ageEle.innerHTML = age;
amkaEle.innerHTML = amka;
trElement.appendChild(fullnameEle);
trElement.appendChild(ageEle);
trElement.appendChild(amkaEle);
tbodyElement.appendChild(trElement);
tableElement.appendChild(tbodyElement);
}
}
</script>
<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>
</head>
<body>
<div class="complete">
<div class="form">
<label>Fullname: <input id="fullname" type="text"></label>
<label>Age: <input id="age" type="number"></label>
<label>AMKA: <input id="amka" type="text"></label>
<span id="error"></span>
<button onclick="publishToTable()">Submit</button>
</div>
<div id="tables">
<table id="table">
<thead>
<tr>
<th>|Name/Surname| </th>
<th>|Age| </th>
<th>|AMKA| </th><br><br><br><br><br>
</tr>
</thead>
</table>
</div>
</div>
</body>
</html>

Trying to add together multiple inputs in the same input field to get total value

tried cutting the code down as much as possible.
Issue: I'm trying to get the total price of new array objects that are being created from inputs by the user, i tried making a new function that grabs the input, but it changes to the new value in the input field whenever a new item is added. Price also wont change when the user deletes an object from the array.
const itemTotalPrice = document.getElementById("total-price")
const itemContainer = document.getElementById("item-container")
const itemListmore = document.getElementById("item-list-more")
var itemArrayMore = [];
//Functions for user input for item name and price
function additemmore () {
let itemNameInput = document.getElementById("item-name-more").value;
let itemPriceInput = document.getElementById("item-price-more").value;
if(document.getElementById("item-name-more").value.length == 0)
{
alert("Need a name")
return false;
}
if(document.getElementById("item-price-more").value.length == 0)
{
alert("Need a price")
return false;
}
if(document.getElementById("item-price-more").value === 0)
{
alert("Value cannot be 0 or lower")
return false;
}
itemArrayMore.push({
name: itemNameInput,
price: itemPriceInput + "kr",
});
console.log("New Array:", itemArrayMore);
listItemsMore();
priceTotal()
}
function listItemsMore(){
itemListmore.innerHTML ="";
for(let i = 0; i < itemArrayMore.length; i++){
itemListmore.innerHTML += `<li><h1>${itemArrayMore[i].name}</h1>
<h2 id="item-price">${itemArrayMore[i].price}</h2>
<button id="delete-btn" onclick="deleteitemmore(${i})">Delete</button></li>`;
}
}
function deleteitemmore(i) {
let del = "Are you sure you want to delete the selected item?";
if (confirm(del) == true) {
itemArrayMore.splice(i, 1);
listItemsMore();
} else {
alert
}
}
//Function for total price. Goal is to get every input and display it as a total price for the user.
//If possible also remove value if related item is deleted.
function priceTotal() {
var price = document.getElementById("item-price-more").value;
var total = +price;
document.getElementById("total-price").innerHTML = total;
}
<!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>Document</title>
</head>
<body>
<h1>Shopping list</h1>
<div id="item-container" class="row">
<div class="column">
<input
type="text"
id="item-name-more"
placeholder="Item name"
/>
<!--for some reason you can add the letter e in the input for price-->
<input
type="number"
id="item-price-more"
placeholder="Write name of item!"
/>
<button onclick="additemmore()">Add</button>
<ul id="item-list-more"></ul>
<ul>Total Price: <span id="total-price">0</span></ul>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
Make total a global variable. Then you can add to it when you add a new item, and subtract from it when you delete an item.
const itemTotalPrice = document.getElementById("total-price")
const itemContainer = document.getElementById("item-container")
const itemListmore = document.getElementById("item-list-more")
var itemArrayMore = [];
var total = 0;
//Functions for user input for item name and price
function additemmore() {
let itemNameInput = document.getElementById("item-name-more").value;
let itemPriceInput = document.getElementById("item-price-more").value;
if (document.getElementById("item-name-more").value.length == 0) {
alert("Need a name")
return false;
}
if (document.getElementById("item-price-more").value.length == 0) {
alert("Need a price")
return false;
}
if (document.getElementById("item-price-more").value === 0) {
alert("Value cannot be 0 or lower")
return false;
}
itemArrayMore.push({
name: itemNameInput,
price: itemPriceInput + "kr",
});
console.log("New Array:", itemArrayMore);
listItemsMore();
priceTotal()
}
function listItemsMore() {
itemListmore.innerHTML = "";
for (let i = 0; i < itemArrayMore.length; i++) {
itemListmore.innerHTML += `<li><h1>${itemArrayMore[i].name}</h1>
<h2 id="item-price">${itemArrayMore[i].price}</h2>
<button id="delete-btn" onclick="deleteitemmore(${i})">Delete</button></li>`;
}
}
function deleteitemmore(i) {
let del = "Are you sure you want to delete the selected item?";
if (confirm(del) == true) {
total -= +itemArrayMore[i].price.replace('kr', '');
document.getElementById("total-price").innerHTML = total;
itemArrayMore.splice(i, 1);
listItemsMore();
} else {
alert
}
}
//Function for total price. Goal is to get every input and display it as a total price for the user.
//If possible also remove value if related item is deleted.
function priceTotal() {
var price = document.getElementById("item-price-more").value;
total += +price;
document.getElementById("total-price").innerHTML = total;
}
<!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>Document</title>
</head>
<body>
<h1>Shopping list</h1>
<div id="item-container" class="row">
<div class="column">
<input type="text" id="item-name-more" placeholder="Item name" />
<!--for some reason you can add the letter e in the input for price-->
<input type="number" id="item-price-more" placeholder="Write name of item!" />
<button onclick="additemmore()">Add</button>
<ul id="item-list-more"></ul>
<ul>Total Price: <span id="total-price">0</span></ul>
</div>
</div>
<script src="index.js"></script>
</body>
</html>

How to insert hypen exactly after 3 & 2 places after respectively in a string?

I am creating like a template which accepts user input and hide it with *. I just need to insert hyphens in between like a SSN number. I am almost done just the places are not proper.
<!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>Vue</title>
</head>
<body>
<div id="app">
<input type="text" #input="onInput" v-model="someData" maxlength="11" />
</div>
<script src="https://unpkg.com/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/v-mask/dist/v-mask.min.js"></script>
<script>
Vue.filter("uppercase", function (value) {
const ssnValue = value.substr(0,3) + '-' + value.substr(3, 6) + '-' + value.substr(6);
console.log('fil',ssnValue)
return ssnValue.replace(/\d/g, '*')
});
const app = new Vue({
el: "#app",
data() {
return {
someData: "",
maskedData: "",
};
},
computed: {
getMaskedData() {
return this.maskedData;
},
},
methods: {
onInput(e) {
let originalString = e.data
if(!!originalString)
this.maskedData += originalString;
console.log('mask', this.getMaskedData)
this.someData = this.$options.filters.uppercase(e.target.value);
},
},
});
</script>
</body>
</html>
I referred Insert hyphens in javascript and put dash after every n character during input from keyboard but i am unclear how can i implement those in my case.
When user is entering 123456789, I want like ***-**-****. (Please don't recommend using input type password or changing font family)
If I understand you correctly try following snippet:
<!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>Vue</title>
</head>
<body>
<div id="app">
<input type="text" #input="onInput" v-model="someData" maxlength="11" />
</div>
<script src="https://unpkg.com/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/v-mask/dist/v-mask.min.js"></script>
<script>
Vue.filter("uppercase", function (value) {
let ssnValue =value
if(value.length === 3 || value.length === 6) {
ssnValue = value + '-'
}
console.log('fil',ssnValue)
return ssnValue.replace(/\d/g, '*')
});
const app = new Vue({
el: "#app",
data() {
return {
someData: "",
maskedData: "",
};
},
computed: {
getMaskedData() {
return this.maskedData;
},
},
methods: {
onInput(e) {
let originalString = e.data
if(!!originalString)
this.maskedData += originalString;
console.log('mask', e.data)
if(e.data) this.someData = this.$options.filters.uppercase(e.target.value);
},
},
});
</script>
</body>
</html>
I saw one of the links that you put in your question there is a format function which you can use:
function format(input, format, sep) {
input = input.replaceAll("-", "");
var output = "";
var idx = 0;
for (var i = 0; i < format.length && idx < input.length; i++) {
output += input.substr(idx, format[i]);
if (idx + format[i] < input.length) output += sep;
idx += format[i];
}
output += input.substr(idx);
return output;
}
Vue.filter("uppercase", function (value) {
let ssnValue = format(value, [3, 3, value.length - 6], "-");
console.log("fil", ssnValue);
return ssnValue.replace(/\d/g, "*");
});

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