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é
andPrix
equal0,99
, andTaux de TVA
equal12%
, result is1,1088
and as suchTotal TTC
should 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\$