50projectsIn50days – Day 16: Drink Water
A chanllenging project which shows how a cup is filled by a water. The HTML looks quite simple becase we have 8 cups of 250ml. But, we can select one cup or a range which is cool. In fact, the HTML is as we can see here:
<div class="cup">
<div class="remained" id="remained">
<span id="liters"></span>
<small>Remained</small>
</div>
<div class="percentage" id="percentage"></div>
</div>
<p class="text">Select how many glasses of water that you have drank</p>
<div class="cups">
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
<div class="cup cup-small">250 ml</div>
</div>
So, we have a big cup and 8 small cups. However in the javascript we can see 4 elements selected:
- Each Small Cup -> ‘.cup-small’
- Liters from the big cup -> ‘liters’
- Percetage from the big cup -> ‘percentage’
- Remainder from the big cup -> ‘remainder’
In the javascript you can see it in the first lines:
const smallCups = document.querySelectorAll('.cup-small')
const liters = document.getElementById('liters')
const percentage = document.getElementById('percentage')
const remained = document.getElementById('remained')
As we see that when we click the small cup the big one is filled. So the event lister is on the small cups:
smallCups.forEach((cup, idx) => {
cup.addEventListener('click', () => highlightCups(idx))
})
And the higlight cup has the responsability of add the class list ‘full’, or remove it. Depend the case.
function highlightCups(idx) {
if( smallCups[idx].classList.contains('full') &&
!smallCups[idx].nextElementSibling.classList.contains('full')) {
idx--
}
smallCups.forEach((cup, idx2) => {
if(idx2 <= idx) {
cup.classList.add('full')
} else {
cup.classList.remove('full')
}
})
updateBigCup()
}
In the beggining of the project and inside the highlightCups functions there is a call to the UpdateBugCup which first is used to update the style for the big Cup.
function updateBigCup(){
const fullCups = document.querySelectorAll('.cup-small.full').length
const totalCups = smallCups.length
if(fullCups === 0){
percentage.style.visibility = 'hidden'
percentage.style.height = 0
} else {
percentage.style.visibility = 'visible'
percentage.style.height = `${fullCups / totalCups * 330}px`
percentage.innerText = `${fullCups / totalCups * 100}%`
}
if(fullCups === totalCups) {
remained.style.visibility = 'hidden'
remained.style.height = 0
} else {
remained.style.visibility = 'visible'
liters.innerText = `${(2 - 250 * fullCups/1000)}L`
}
}
You can see the code in this GitHub Repository: 16.drink_water and the demo of the project is here: Drink Water