Age Calculator

Age Calculator

The challenge

The challenge is part of frontend challenge where you have to build out a age calculator app and get it looking as close to the design as possible.

Users should be able to:

  • View an age in years, months, and days after submitting a valid date through the form

    Receive validation errors if:

  • Any field is empty when the form is submitted

  • The day number is not between 1-31

  • The month number is not between 1-12

  • The date is in the future

  • View the optimal layout for the interface depending on their device's screen size

See hover and focus states for all interactive elements on the page.

HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;1,900&display=swap" rel="stylesheet">

    <script src="index.js"></script>
    <title>Document</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <div class="div-main">
    <div class="div-date" id="div-date">

        <div class="day">
               <p id="text-day">Day</p>
               <input type="text"  class="input-date" id="input-date" placeholder="DD" >
               <p id="error-date" class="error-text"></p>
        </div>
        <div class="day">
            <p id="text-mon">Month</p>
            <input type="text" class="input-date" id="input-mon" placeholder="MM">
            <p id="error-mon" class="error-text"></p>
        </div>
        <div class="day">
            <p id="text-year">Year</p>
            <input type="text" class="input-date" id="input-year" placeholder="YYYY" >
            <p id="error-year" class="error-text"></p>
        </div>

    </div><br/>
    <div class="line">

    </div>
    <div class="circle">
        <svg xmlns="http://www.w3.org/2000/svg" width="46" height="44" style="margin-left: 7%;margin-top: 5%;" viewBox="0 0 46 44" onclick="cal()"><g fill="none" stroke="#FFF" stroke-width="2"><path d="M1 22.019C8.333 21.686 23 25.616 23 44M23 44V0M45 22.019C37.667 21.686 23 25.616 23 44"/></g></svg>
    </div>
    <div class="cal">
   <p><span id="year">- -  </span> years<br/>
  <span id="month">- - </span> Months<br/>
  <span id="date">- -  </span> Days</p>
    </div>
    </div>
</body>
</html>

CSS CODE

body{
    background-color: hsl(0, 0%, 86%);

}
.div-main{
    background-color: white;
    width: 45%;
    margin-left:25%;
    margin-top: 5%;

    border-radius: 15px;
    border-bottom-right-radius:160px;

}
.div-date{

    display: flex;
    margin-top: 16%;
    width: 100%;
}
.div-date p{
    font-size: 14px;
    text-transform: uppercase;
    color: rgb(127, 125, 125);
    font-family: 'Poppins', sans-serif;
    font-weight: bolder;
}
.day{
    width: 20%;
    gap:-6px;
    margin-left: 4%;
   margin-right: 2px;
    margin-top: 5%;
}
.input-date{
    width: 60%;
    height: 2rem;
    border: 2px solid rgb(233, 233, 233);
    border-radius: 5px;
   margin-top: -5%;
   font-weight: bold;
   font-size: 20px;
   font-family: 'Poppins', sans-serif;
   cursor: pointer;
}
.line{
    border: 1px solid rgb(239, 239, 239);
    width:80%;
    margin-left: 4%;
}
.circle{
    background-color: rgb(128, 61, 253);
    width:60px;
    height: 60px;
    border-radius: 50px;
    margin-left: 85%;
    margin-top: -3%;
    cursor: pointer;
}
.arrow{
    margin-left: 5%;
    color: black;
}
.cal{
    width:80%;
    margin-top: -10%;
    margin-left: 4%;
    margin-bottom: 10px;


}
.cal p{
    font-size: 55px;
    font-style: italic;
   margin-left: 10%;
   font-family: 'Poppins', sans-serif;
   text-transform: lowercase;
   font-weight: 900;

}
p span{
    color:rgb(128, 61, 253);

}
.error{
    border-color: hsl(0, 100%, 67%);
}
.error-text{
    color:red
}

@media screen and (min-width: 280px) and (max-width:760px){
    .div-main{
        width: 95%;
        margin-left:2%;
        border-bottom-right-radius:100px;
    }
    .day{
        width: 26%; 
    }
    .cal p{
        font-size: 40px;
    }
    .cal{
        width:80%;
        margin-top: -10%;
        margin-left: 4%;
        margin-bottom: 10px;  
    }
    p span{
        color:rgb(128, 61, 253)
    }
    .circle{
        margin-left: 35%;
        margin-top: -8%;
    }
    .line{
        margin-top: 4%;
    }
}
@media screen and (min-width: 760px) and (max-width:1000px){
    .div-main{
        width: 95%;
        margin-left:2%;
    }

}

JAVASCRIPT CODE

Step 1 - Getting the Present date using JS date module.

const d = new Date()
let yearCurr=d.getFullYear();
let monCurr=d.getMonth()+1
let dateCurr=d.getDate()

Explanation -

  • Date objects are created with new Date()

  • by using getFullYear() we can get the present year.

  • by using getMonth we can get the month ( but month starts with 0 we add +1 ).

  • by using getDate() we can get the date .

  • for reference - w3schools.com/jsref/jsref_obj_date.asp

Step 2 - Validation

let checkDate=(userDate=='' || userDate==0|| userDate>31)
let checkMon=(userMonth=='' || userMonth==0||userMonth>12)
let checkYear=(userYear==''||userYear>yearCurr)
let checkTotal=checkDate || checkMon || checkYear

Explanation -

  • checks if the user data is valid (between ranges ) and not null .

  • adding CSS for validation using DOM elements

      if(checkTotal){    
                  if(userDate==''){
                      document.getElementById('input-date').classList.add('error')
                      document.getElementById('error-date').innerText='The field is required'
                      document.getElementById('error-date').style.color='hsl(0, 100%, 67%)'
                      document.getElementById('text-day').style.color='hsl(0, 100%, 67%)'
                  }else if(userDate==0 || userDate>31){
                      document.getElementById('input-date').classList.add('error')
                      document.getElementById('error-date').innerText='Must be a valid day'  
                      document.getElementById('error-date').style.color='hsl(0, 100%, 67%)'
                      document.getElementById('text-day').style.color='hsl(0, 100%, 67%)'
                  }
                  if(userMonth==''){
                      document.getElementById('input-mon').classList.add('error')
                      document.getElementById('error-mon').innerText='The field is required'
                      document.getElementById('error-mon').style.color='hsl(0, 100%, 67%)'
                      document.getElementById('text-mon').style.color='hsl(0, 100%, 67%)'
                  }else if(userMonth==0 || userMonth>12){
                      document.getElementById('input-mon').classList.add('error')
                      document.getElementById('error-mon').innerText='Must be a valid month'
                      document.getElementById('error-mon').style.color='hsl(0, 100%, 67%)'
                      document.getElementById('text-mon').style.color='hsl(0, 100%, 67%)'
                  }
                  if(userYear==''){
                      document.getElementById('input-year').classList.add('error')
                      document.getElementById('error-year').innerText='The field is required'
                      document.getElementById('error-year').style.color='hsl(0, 100%, 67%)'
                      document.getElementById('text-year').style.color='hsl(0, 100%, 67%)'
                  }else if(userYear==0 || userYear>yearCurr){
                      document.getElementById('input-year').classList.add('error')
                      document.getElementById('error-year').innerText='Must be in the past'
                      document.getElementById('error-year').style.color='hsl(0, 100%, 67%)'
                      document.getElementById('text-year').style.color='hsl(0, 100%, 67%)'   
                  }
    

Step 3 - Logic

  • Step 1: First, calculate the number of years by subtracting the birth year from the current year. ( Current Year-Birth Year )

  •   totalYear=yearCurr-userYear
    
  • Step 2: Second calculate the number of years by subtracting birth month from the current year. If (current Month<birth month) then subtract the full years by 1 and add 12 to current months .

  •   if(monCurr<userMonth){  
                  totalYear--
                  monCurr+=12
                  monTotal=monCurr-userMonth
       }else{
                  monTotal=monCurr-userMonth
       }
    
  • Step 3: Last calculate the number of days by subtracting birth date from current date. if(current date<birth date) then subtract the month by 1 and adding number of days the previous month of current month has .

  •   if(dateCurr<userDate){
                  monTotal--
                  let previousMonth=monCurr-1
                  if(previousMonth===1||previousMonth===3||previousMonth===5||previousMonth===7||previousMonth===8||previousMonth===10||
                      previousMonth===12){
                      dateTotal=date+31
                  }else if(previousMonth===2){
                      dateTotal=date+28
                  }else{
                      dateTotal=date+30
                  }
                 }else{
                  dateTotal=dateCurr-userDate
                 }
    
const d = new Date()
let yearCurr=d.getFullYear();
let monCurr=d.getMonth()+1
let dateCurr=d.getDate()
let yearText
let totalYear
let monTotal
let monText
let dateTotal
let dateText
let userDate
function cal(){

    let userDate=document.getElementById('input-date').value
   let userMonth=document.getElementById('input-mon').value
    let userYear =document.getElementById('input-year').value
    yearText=document.getElementById('year')
    monText=document.getElementById('month')
    dateText=document.getElementById('date')

        //validation 
        let checkDate=(userDate=='' || userDate==0|| userDate>31)
        let checkMon=(userMonth=='' || userMonth==0||userMonth>12)
        let checkYear=(userYear==''||userYear>yearCurr)
        let checkTotal=checkDate || checkMon || checkYear
        if(checkTotal){    
            if(userDate==''){
                document.getElementById('input-date').classList.add('error')
                document.getElementById('error-date').innerText='The field is required'
                document.getElementById('error-date').style.color='hsl(0, 100%, 67%)'
                document.getElementById('text-day').style.color='hsl(0, 100%, 67%)'
            }else if(userDate==0 || userDate>31){
                document.getElementById('input-date').classList.add('error')
                document.getElementById('error-date').innerText='Must be a valid day'  
                document.getElementById('error-date').style.color='hsl(0, 100%, 67%)'
                document.getElementById('text-day').style.color='hsl(0, 100%, 67%)'
            }
            if(userMonth==''){
                document.getElementById('input-mon').classList.add('error')
                document.getElementById('error-mon').innerText='The field is required'
                document.getElementById('error-mon').style.color='hsl(0, 100%, 67%)'
                document.getElementById('text-mon').style.color='hsl(0, 100%, 67%)'
            }else if(userMonth==0 || userMonth>12){
                document.getElementById('input-mon').classList.add('error')
                document.getElementById('error-mon').innerText='Must be a valid month'
                document.getElementById('error-mon').style.color='hsl(0, 100%, 67%)'
                document.getElementById('text-mon').style.color='hsl(0, 100%, 67%)'
            }
            if(userYear==''){
                document.getElementById('input-year').classList.add('error')
                document.getElementById('error-year').innerText='The field is required'
                document.getElementById('error-year').style.color='hsl(0, 100%, 67%)'
                document.getElementById('text-year').style.color='hsl(0, 100%, 67%)'
            }else if(userYear==0 || userYear>yearCurr){
                document.getElementById('input-year').classList.add('error')
                document.getElementById('error-year').innerText='Must be in the past'
                document.getElementById('error-year').style.color='hsl(0, 100%, 67%)'
                document.getElementById('text-year').style.color='hsl(0, 100%, 67%)'   
            }
        }else{
            document.getElementById('input-date').classList.remove('error')
            document.getElementById('input-mon').classList.remove('error')
            document.getElementById('input-year').classList.remove('error')
            document.getElementById('error-year').innerText=''
            document.getElementById('error-mon').innerText=''
            document.getElementById('error-date').innerText=''
            document.getElementById('text-year').style.color='rgb(127, 125, 125)'
            document.getElementById('text-mon').style.color='rgb(127, 125, 125)'
            document.getElementById('text-day').style.color='rgb(127, 125, 125)'
            userDate=parseInt(userDate)
            userMonth=parseInt(userMonth)
            userYear=parseInt(userYear)
           //step1 
           totalYear=yearCurr-userYear
           //step2 
           if(monCurr<userMonth){  
            totalYear--
            monCurr+=12
            monTotal=monCurr-userMonth
           }else{
            monTotal=monCurr-userMonth
           }
           //step 3 
           if(dateCurr<userDate){
            monTotal--
            let previousMonth=monCurr-1
            if(previousMonth===1||previousMonth===3||previousMonth===5||previousMonth===7||previousMonth===8||previousMonth===10||
                previousMonth===12){
                dateTotal=date+31
            }else if(previousMonth===2){
                dateTotal=date+28
            }else{
                dateTotal=date+30
            }
           }else{
            dateTotal=dateCurr-userDate
           }
           yearText.innerText=totalYear
           monText.innerText=monTotal
           dateText.innerText=dateTotal
}

       date=0
       document.getElementById('input-date').value=''
       document.getElementById('input-mon').value=''
       document.getElementById('input-year').value=''


}