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