Hello this is my first post, i have been learning javascript for a week. I want to make a little app that calculate how much do you spend on subscription per month.
You can add a new subscription with the name and the subscription price with two inputs --> and it creates 2 new div(one is subscriptionName the other is subscriptionPrice) they are store into a new div (newSubscription).
Now i would like to store all the subscriptionPrice var into an array and addition all of them. (is it the right logic to apply ? maybe im wrong).
I also thought about doing the addition of the :
.abo-list > .abo:nth-child(1) > .abo-price
.abo-list > .abo:nth-child(1 1) > .abo-price
...
I have tried with this technic but the consol do not show even the first oneAboPrice.
var pricesValues = [];
for (var i = 0; i < oneAboPrice.length; i ) {
pricesValues.push(oneAboPrice[i].textContent);
}
console.log(pricesValues); /*dont show the values of every oneAboPrice*/
//Selectors
const nameInput = document.querySelector('.name');
const price = document.querySelector('.price');
const validate = document.querySelector('.validate');
const abosList = document.querySelector('.abo-list');
const montantTotal = document.querySelector('.montant-total');
//event listeners
validate.addEventListener('click', addAbo);
abosList.addEventListener('click', clickModify);
//functions
function addAbo(event){
event.preventDefault();
//creating the NewAbo DIV
const Abodiv = document.createElement('div');
Abodiv.classList.add('abo');
//creating a LI
const newAbo = document.createElement('li');
newAbo.innerText = nameInput.value ' ' ;
newAbo.classList.add('abo-item');
Abodiv.appendChild(newAbo);
//creating a div Price of one Sub
const oneAboPrice = document.createElement('div');
oneAboPrice.classList.add('abo-price');
oneAboPrice.innerText = price.value;
Abodiv.appendChild(oneAboPrice);
//modify button
const modifyAbo = document.createElement('button');
modifyAbo.innerHTML = '<i ></i>';
modifyAbo.classList.add('modifyAbo');
Abodiv.appendChild(modifyAbo);
//trash button
const trashAbo = document.createElement('button');
trashAbo.innerHTML = '<i ></i>';
trashAbo.classList.add("trashAbo");
Abodiv.appendChild(trashAbo);
//append to Abo-list
abosList.appendChild(Abodiv);
//total Amount of every newAboPrice
//reset input value
nameInput.value ="";
price.value="";
//store every .abo price (oneAboPrice)value into an array (this is where i need help)
var pricesValues = [];
for (var i = 0; i < oneAboPrice.length; i ) {
pricesValues.push(oneAboPrice[i].textContent);
}
console.log(pricesValues); /*dont show the values of every oneAboPrice*/
montantTotal.innerHTML = parseFloat(oneAboPrice.textContent); /* oneAboPrice nth:child(2) ....*/
}
function clickModify(e) {
const item = e.target;
//Delete newAbo
if(item.classList[0] === "trashAbo"){
const abo = item.parentElement;
abo.remove();
}
//modify newAbo (To do)
}
@import url('https://fonts.googleapis.com/css2?family=Bebas Neue&family=Poppins&family=Saira Extra Condensed:wght@500&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content-container{
display: flex;
justify-content: space-around;
}
.abo{
display: flex;
justify-content: space-between;
list-style-type: none;
}
.abo li{
flex: 1;
}
.fa-trash{
pointer-events: none;
}
.abo-price{
background: red;
}
<!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="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="style.css">
<title>Gestionnaire d'abonnements</title>
</head>
<body>
<div >
<div >
<p>Nom de l'abonnement</p><input type="text" placeholder="netflix">
<p>Prix mensuel</p><input type="number" placeholder="13,49">
<input type="button" value="Valide" >
</div>
<div >
<h1>MES ABOS</h1>
<ul >
</ul>
<p ></p>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
CodePudding user response:
I understand that you want to show the array of all items using this loop:
for (var i = 0; i < oneAboPrice.length; i ) {
pricesValues.push(oneAboPrice[i].textContent);
}
The problem is, oneAboPrice
is not the all items that you want, it's a new element that you just created with this code:
//creating a div Price of one Sub
const oneAboPrice = document.createElement('div');
oneAboPrice.classList.add('abo-price');
oneAboPrice.innerText = price.value;
Abodiv.appendChild(oneAboPrice);
Solution
So, to correctly loop through all items, this is what the loop should be:
document.querySelectorAll('.abo-price').forEach(item => {
pricesValues.push(parseFloat(item.innerHTML));
});
Let's me explain. document.querySelectorAll('.abo-price')
will select all of your oneAboPrice
at the time being. Then you can use item.innerHTML
to get the text inside of each item, not item.textContent
.
//Selectors
const nameInput = document.querySelector('.name');
const price = document.querySelector('.price');
const validate = document.querySelector('.validate');
const abosList = document.querySelector('.abo-list');
const montantTotal = document.querySelector('.montant-total');
//event listeners
validate.addEventListener('click', addAbo);
abosList.addEventListener('click', clickModify);
//functions
function addAbo(event) {
event.preventDefault();
//creating the NewAbo DIV
const Abodiv = document.createElement('div');
Abodiv.classList.add('abo');
//creating a LI
const newAbo = document.createElement('li');
newAbo.innerText = nameInput.value ' ';
newAbo.classList.add('abo-item');
Abodiv.appendChild(newAbo);
//creating a div Price of one Sub
const oneAboPrice = document.createElement('div');
oneAboPrice.classList.add('abo-price');
oneAboPrice.innerText = price.value;
Abodiv.appendChild(oneAboPrice);
//modify button
const modifyAbo = document.createElement('button');
modifyAbo.innerHTML = '<i ></i>';
modifyAbo.classList.add('modifyAbo');
Abodiv.appendChild(modifyAbo);
//trash button
const trashAbo = document.createElement('button');
trashAbo.innerHTML = '<i ></i>';
trashAbo.classList.add("trashAbo");
Abodiv.appendChild(trashAbo);
//append to Abo-list
abosList.appendChild(Abodiv);
//total Amount of every newAboPrice
//reset input value
nameInput.value = "";
price.value = "";
//store every .abo price (oneAboPrice)value into an array (this is where i need help)
var pricesValues = [];
document.querySelectorAll('.abo-price').forEach(item => {
pricesValues.push(parseFloat(item.innerHTML));
});
console.log(pricesValues); /*dont show the values of every oneAboPrice*/
montantTotal.innerHTML = parseFloat(oneAboPrice.textContent); /* oneAboPrice nth:child(2) ....*/
}
function clickModify(e) {
const item = e.target;
//Delete newAbo
if (item.classList[0] === "trashAbo") {
const abo = item.parentElement;
abo.remove();
}
//modify newAbo (To do)
}
@import url('https://fonts.googleapis.com/css2?family=Bebas Neue&family=Poppins&family=Saira Extra Condensed:wght@500&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content-container {
display: flex;
justify-content: space-around;
}
.abo {
display: flex;
justify-content: space-between;
list-style-type: none;
}
.abo li {
flex: 1;
}
.fa-trash {
pointer-events: none;
}
.abo-price {
background: red;
}
<!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="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<link rel="stylesheet" href="style.css">
<title>Gestionnaire d'abonnements</title>
</head>
<body>
<div >
<div >
<p>Nom de l'abonnement</p><input type="text" placeholder="netflix">
<p>Prix mensuel</p><input type="number" placeholder="13,49">
<input type="button" value="Valide" >
</div>
<div >
<h1>MES ABOS</h1>
<ul >
</ul>
<p ></p>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
CodePudding user response:
Here is a start. I need to get lunch
//Selectors
const nameInput = document.querySelector('.name');
const price = document.querySelector('.price');
const validate = document.querySelector('.validate');
const abosList = document.querySelector('.abo-list');
const montantTotal = document.querySelector('.montant-total');
//event listeners
validate.addEventListener('click', addAbo);
abosList.addEventListener('click', clickModify);
const abos = []
const render = () => {
const sum = 0;
abosList.innerHTML = abos.map(({name,price}) => {
sum = price;
return `<div ><li>${name}</li><div >${price}</div>
<button type="button" ><i ></i></button>
<button type="button" ><i ></i></button>
</div>`
});
montantTotal.innerHTML = sum.toFixed(2)
}
function addAbo(event) {
event.preventDefault();
abos.push({
name: nameInput.value,
price: price.value})
//reset input value
nameInput.value = "";
price.value = "";
render();
sum();
}
function clickModify(e) {
const item = e.target.closest('button');
//Delete newAbo
if (item.classList.contains("trashAbo")) {
const parent = item.closest('div')
const name = parent.querySelector('li').textContent;
parent.remove();
abos.find(name).remove();
}
}
@import url('https://fonts.googleapis.com/css2?family=Bebas Neue&family=Poppins&family=Saira Extra Condensed:wght@500&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content-container {
display: flex;
justify-content: space-around;
}
.abo {
display: flex;
justify-content: space-between;
list-style-type: none;
}
.abo li {
flex: 1;
}
.fa-trash {
pointer-events: none;
}
.abo-price {
background: red;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<title>Gestionnaire d'abonnements</title>
<div >
<div >
<p>Nom de l'abonnement</p><input type="text" placeholder="netflix">
<p>Prix mensuel</p><input type="number" placeholder="13,49">
<input type="button" value="Valide" >
</div>
<div >
<h1>MES ABOS</h1>
<ul >
</ul>
<p ></p>
</div>
</div>
CodePudding user response:
If your only purpose is to get the total value of all subscriptions, you don't need an array. just call the function below every time a new subscription is added (call it inside addAbo
).
// this will select all the `div` items with the class `.abo-price`
const subscriptionEls = document.querySelectorAll('.abo-price');
function calculateTotal() {
let total = 0;
// loop through each '.abo-price' element
subscriptionEls.forEach((el) => {
const textValue = el.innerText; // '12,49' (string)
const numericValue = parseInt(textValue); // 12,49 (number)
total = numericValue; // add each numerical value to the total
})
montantTotal.innerText = total;
}