I've just created a simple VAT calculator. The script works fine though some animations seem a little buggy. Being a javascript beginner I'd like to ask more experienced programmers their opinion about my code. Do you have any helpful criticism to make my code more performant?
document.addEventListener('DOMContentLoaded',function(){
//animation after DOM loaded
var all = document.querySelectorAll('p, h1, h4, input, button');
for(var i=0 ; i<all.length ; i++) {
all[i].animate({
opacity: [ 0, 1 ],
transform: [ 'translateY(50%)','translateY(0%)' ]
}, 1000);
};
//general variables
var btnNew = document.getElementById('newEntry');
var btnArray = [];
var btnList = document.getElementById('showListe');
var list = document.getElementById('liste');
var listHeight = list.getBoundingClientRect().height;
var startHeight = listHeight;
list.classList.add('hide');
var animer = document.querySelector('.animate');
var resultBlock = document.getElementById('resultats');
//details button (opne and close the list) + animations
btnList.addEventListener('click',function(){
list.classList.toggle('animate-up');
list.classList.toggle('animate-down');
if (list.classList.contains('animate-down')){
animer.animate({
opacity: [ 0, 1 ],
transform: ['translateY(-100%)','translateY(0%)']
}, 500);
list.classList.toggle('hide');
resultBlock.animate({
transform: ['translateY('+-startHeight+'px)','translateY(0%)']
}, 500);
} else {
animer.animate({
opacity: [ 1, 0 ],
transform: ['translateY(0%)','translateY(-100%)']
}, 500);
setTimeout(function(){list.classList.toggle('hide')},500);
var listHeight = list.getBoundingClientRect().height;
resultBlock.animate({
transform: ['translateY(0%)','translateY('+-listHeight+'px)']
}, 500);
};
});
function countTotal() {
//calculate sums then display them in the DOM
var arrayHT = document.querySelectorAll('#addHT');
var countHT = 0;
for (var i=0 ; i<arrayHT.length ; i++) {
countHT+=parseFloat(arrayHT[i].innerHTML);
};
var arrayTTC = document.querySelectorAll('#addTTC');
var countTTC = 0;
for (var i=0 ; i<arrayTTC.length ; i++) {
countTTC+=parseFloat(arrayTTC[i].innerHTML);
};
document.getElementById('totalHT').value = Math.round(countHT*100)/100;
document.getElementById('totalTTC').value =Math.round(countTTC*100)/100;
};
//reinitialise input fields to default value
function reinitialiseInput() {
document.getElementById('nom').value ='';
document.getElementById('qte').value ='';
document.getElementById('prix').value ='';
};
//calculate and add new entry to DOM
btnNew.addEventListener('click', function(){
//create basic values
var VATrate = document.getElementById('txTVA').value;
var entryName = document.getElementById('nom').value;
var quantity = document.getElementById('qte').value;
var price = document.getElementById('prix').value;
var sumHT = price*quantity;
var VAT = (VATrate/100)*sumHT;
var sumTTC = sumHT+VAT;
//create html elements and assign them a value
var elementName = document.createElement('p');
elementName.innerHTML = entryName;
var elementUnitPrice = document.createElement('p');
elementUnitPrice.innerHTML= price;
var elementQuantity = document.createElement('p');
elementQuantity.innerHTML = quantity;
var elementVATrate = document.createElement('p');
elementVATrate.innerHTML = VATrate+'%';
var elementVAT = document.createElement('p');
elementVAT.innerHTML = VAT.toFixed(2);
var elementSumHT = document.createElement('p');
elementSumHT.innerHTML = sumHT;
elementSumHT.id ="addHT";
var elementSumTTC = document.createElement('p');
elementSumTTC.innerHTML = sumTTC;
elementSumTTC.id ="addTTC";
var btnDelete = document.createElement('button');
btnDelete.innerHTML = 'Effacer';
btnDelete.classList.add('btn', 'btn-danger');
btnDelete.id = "deleteBtn";
var newRow = document.createElement('div');
newRow.classList.add('row', 'list-row');
//put all elements in array
var elementArray = [elementName,elementUnitPrice,elementQuantity,elementVATrate,elementVAT,elementSumHT,elementSumTTC,btnDelete];
//loop this array to add a class to each element, then add them into a row
for (var i=0 ; i<elementArray.length ; i++) {
elementArray[i].classList.add('list-element');
newRow.appendChild(elementArray[i]);
};
//add new row to the list
list.appendChild(newRow);
//animation when adding a new row with list openned
var rowHeight = newRow.getBoundingClientRect().height;
if (list.classList.contains('animate-down')){
newRow.animate({
opacity: [ 0, 1 ],
transform: [ 'translateY(-100%)','translateY(0%)' ]
}, 500);
resultBlock.animate({
transform: ['translateY('+-rowHeight+'px)','translateY(0%)']
}, 500);
} ;
//reinitialise inputs and calculate sums
reinitialiseInput()
countTotal();
//delete row + animation
btnArray.push(btnDelete);
(function(){
btnArray[btnArray.length-1].addEventListener('click',function(){
var thisRow = this.parentNode;
var thisRowHeight = thisRow.getBoundingClientRect().height;
thisRow.animate({
opacity: [ 1, 0 ],
transform: [ 'translateY(0%)','translateY(-100%)' ]
}, 500);
setTimeout(function(){
thisRow.parentNode.removeChild(thisRow);
},500);
resultBlock.animate({
transform: ['translateY(0%)','translateY('+(-thisRowHeight)*0.75+'px)']
}, 500);
setTimeout(function(){
countTotal();
},500);
});
}());
});
});
.container{
display: flex;
flex-flow: column nowrap;
}
.section {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.section:not(.section1):not(.section4){
display:flex;
flex-flow: row nowrap;
}
.section2 {align-items: baseline;}
.section3 {
justify-content: space-between;
align-items: flex-end;
}
.section3 div {flex-grow: 1;}
.section3 button {flex-grow: 6;}
.section4 {flex-flow: column nowrap;}
.section5, .section6 {justify-content: flex-end;}
.section1, .section2, .section4 {justify-content: flex-start;}
input{
border: 1px solid #d3d3d3;
text-align: right;
}
.list-container {
overflow: hidden;
}
.list-row{
display: flex;
flex-flow: row nowrap;
margin-bottom: 0.5em;
overflow: hidden;
}
.list-element {
width:12.5%;
}
.hide {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<title>Cacul TVA</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 section section1">
<h1>Calcul de TVA</h1>
<p>Entrez vos dépenses hors-taxe ci-dessous afin d'obtenir le total HT et le total TTC.</p>
</div>
</div>
<div class="row">
<div class="col-md-8 section section2">
<p>Taux de TVA:</p>
<input type="number" value="20" id="txTVA">
<p>%</p>
</div>
</div>
<div class="row">
<div class="col-md-8 section section3">
<div class="input_block">
<p>Nom</p>
<input type="text" id="nom">
</div>
<div class="input_block">
<p>Quantité</p>
<input type="number" id="qte">
</div>
<div class="input_block">
<p>Prix</p>
<input type="number" id="prix">
</div>
<button class="btn btn-primary" id="newEntry">Entrée</button>
</div>
</div>
<div class="row ">
<div class="col-md-8 section section4">
<h4 id="showListe">Détails<span class="caret"></span></h4>
</div>
</div>
<div class="row list-container">
<div class="col-md-8 section section4 animate animate-up" id="liste">
<div class="row list-row">
<h5 class="list-element">Nom</h5>
<h5 class="list-element">Prix Unitaire</h5>
<h5 class="list-element">Quantité</h5>
<h5 class="list-element">Taux TVA</h5>
<h5 class="list-element">TVA</h5>
<h5 class="list-element">Somme HT</h5>
<h5 class="list-element">Somme TTC</h5>
<h5></h5>
</div>
<hr>
</div>
</div>
<div id="resultats">
<div class="row">
<div class="col-md-8 section section5">
<h4>Total HT:</h4>
<input type="number" name="" placeholder="0" id="totalHT" readonly="true">
</div>
</div>
<div class="row">
<div class="col-md-8 section section6">
<h4>Total TTC:</h4>
<input type="number" name="" placeholder="0" id="totalTTC" readonly="true">
</div>
</div>
<hr>
</div>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
Nom,QuantitéandPrixequal0,99, andTaux de TVAequal12%, result is1,1088and as suchTotal TTCshould read1,11, while it reads1,10. When talking money and such, always operate on cents (more generally, smallest indivisible unit). Flaws like that has been used in the past to steal relatively large amounts. \$\endgroup\$