Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Building a simple calendar with Vanilla JS
EliHood
EliHood

Posted on • Edited on

     

Building a simple calendar with Vanilla JS

In todays post, we'll be building a simple calendar using just vanilla JS. I will be using typescript, and using tsc to build out the index.js.

note: I'll be focusing more on the engine / loop part specifically, which i find to be the most important when it comes to this calendar algorithm.

The basis of making a calendar, requires two things really.

Lets make some generic html markup.

HTML

<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><metahttp-equiv="X-UA-Compatible"content="ie=edge"/><title>Some Calendar</title><linkrel="stylesheet"href="style.css"/></head><body><divclass="container"><divclass="calendar-body"><divid="header"><h1id="month-heading"></h1><div><buttonid="backButton">Back</button><buttonid="nextButton">Next</button></div></div><divid="weekdays"><div>Sunday</div><div>Monday</div><div>Tuesday</div><div>Wednesday</div><div>Thursday</div><div>Friday</div><div>Saturday</div></div><divid="calendar"></div></div></div><scriptsrc="dist/index.js"></script></body></html>
Enter fullscreen modeExit fullscreen mode

Some CSS

body,html{height:100%;width:100%;padding:0px;margin:0px;}#month-heading{padding:0.1em;font-size:1.4em;box-sizing:border-box;}.container{display:flex;justify-content:center;width:770px;height:auto;margin:0auto;}#header{padding:10px;display:flex;justify-content:space-between;}.day+#currentDay{background-color:#e8f4fa;}.prev-day{background-color:#FFFCFF!important;box-shadow:none!important;}#weekdays{width:100%;display:flex;border-top:1pxsolid#000;border-bottom:1pxsolid#000;}#weekdaysdiv{width:100px;padding:10px;}.calendar-body{background-color:#eee;margin:auto;width:800px;height:auto;position:relative;}#calendar{width:100%;margin:auto;display:flex;flex-wrap:wrap;}.day{width:100px;padding:10px;height:100px;box-sizing:border-box;margin:5px;background-color:#fff;box-shadow:0px0px3px#CBD4c2;display:flex;flex-direction:column;justify-content:space-between;}
Enter fullscreen modeExit fullscreen mode

So lets get into the JS part.

Getting the first day of the month

// specify the weekdaysconstweekDays=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",];
Enter fullscreen modeExit fullscreen mode

Setting up the Date Api.

functionmain(){constdt=newDate();constmonth=dt.getMonth();// 10constyear=dt.getFullYear();// 2023// gets first day of month based on the above paramsconstfirstDayOfMonth=newDate(year,month,1);// Wed Nov 01 2023 00:00:00 GMT-0400 (Eastern Daylight Time)// tolocaleString parse the above date in a readable format.constdateString=firstDayOfMonth.toLocaleString("en-us",{weekday:"long",year:"numeric",month:"numeric",day:"numeric",});// Wednesday, 11/1/2023/**   *  we want to get the first weekday of the month,    *  so we have a string of Wednesday, 11/1/2023.     *    *  We want just the Wednesday part... so were going to make this string into an array.    * so we split the string into array elements for every comma "," and leading white space.    * dateString.split(", ") which gives us the following:   *    * (2) ['Wednesday', '11/1/2023']   */constgetFirstDayMonth=dateString.split(",")[0];// Wednesdayconstdays=weekDays.indexOf(getFirstDayMonth);// returns an index of 3 being that Wednesday is the 3rd array element.}
Enter fullscreen modeExit fullscreen mode

So we have some of the basis for our calendar program.

Lets get into the looping aspect...

The Loop

...mainfunctioncontinued..constdaysInMonth=newDate(year,month+1,0).getDate();// 30/**   * lets then add days plus the days in the month so   *   * 3 + 30   */constdaysAndMonthTotal=days+daysInMonth;// 33/**   * we could create an array to reference its length   */constdaysArr=newArray(daysAndMonthTotal);// 33constday=dt.getDate();// 26for(leti=1;i<=daysArr.length;i++){constsquare=document.createElement("div")asany;square.classList.add("day");/**     * here we are saying substract the index from the days.     *     *     * e.g     *      * Days will always be 3 in this case, and will always increment.     *      * So      * 1 - 3 = -2      * 2 - 3 = -1     * 3-3 =  0     * 4-3 = 1 // we start here      *      */constaddedDay=i-days;....}
Enter fullscreen modeExit fullscreen mode

Image description

...continuedconstaddedDay=i-days;// so we start when i is greater than 3.if(i>days){square.innerText=addedDay;// if addedDay is today, lets give it a special color.if(addedDay===day){square.id="currentDay";}}}
Enter fullscreen modeExit fullscreen mode

The complete code so far with some javascript event listeners added and etc.

letnav=0;constgetCalendar=document.getElementById("calendar")asany;constweekDays=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",];functionnextButton(){document.getElementById("nextButton")?.addEventListener("click",()=>{nav++;main();});}functionbackButton(){document.getElementById("backButton")?.addEventListener("click",()=>{nav--;main();});}functionmain(){constdt=newDate();if(nav!==0){dt.setMonth(newDate().getMonth()+nav);}constmonth=dt.getMonth();constyear=dt.getFullYear();constfirstDayOfMonth=newDate(year,month,1);constdateString=firstDayOfMonth.toLocaleString("en-us",{weekday:"long",year:"numeric",month:"numeric",day:"numeric",});constlastDayOfLastMonth=newDate(year,month,0).getDate();(document.getElementById("month-heading")asany).innerText=`${dt.toLocaleDateString("en-us",{month:"long"})}${year}`;getCalendar.innerHTML="";/**   *  we want to get the first weekday of the month,   *  so we have a string of Wednesday, 11/1/2023.   *   *  We want just the Wednesday part... so were going to make this string into an array.   * so we split the string into array elements for every comma "," and leading white space.   * dateString.split(", ") which gives us the following:   *   * (2) ['Wednesday', '11/1/2023']   */constgetFirstDayMonth=dateString.split(",")[0];// Wednesdayconstdays=weekDays.indexOf(getFirstDayMonth);/**   * Lets get the days in the current month by the following   */constdaysInMonth=newDate(year,month+1,0).getDate();// 30/**   * lets then add days plus the days in the a month so   *   * 3 + 30   */constdaysAndMonthTotal=days+daysInMonth;// 33/**   * we could create an array the reference its length   */constdaysArr=newArray(daysAndMonthTotal);// 33constday=dt.getDate();// 26/**   * We use the for loop to iterate through the daysArr   *   * If I = 1, and 1 is less than 33, render us some squares.. essentially   */for(leti=1;i<=daysArr.length;i++){constsquare=document.createElement("div")asany;square.classList.add("day");/**     * here we are saying substract the index from the days.     *     *     * e.g     *     * Days will always be 3 in this case, and I will always increment.     *     * So     * 1 - 3 = -2     * 2 - 3 = -1     * 3-3 =  0     * 4-3 = 1 // we start here     *     */constaddedDay=i-days;/**     * if the index is greater than the first day of the month add text for numbers     *     * else add padding squares     */if(i>days){square.innerText=addedDay;if(addedDay===day&&nav===0){square.id="currentDay";}}getCalendar?.appendChild(square);}}nextButton();backButton();main();
Enter fullscreen modeExit fullscreen mode

Image description

Last thing, lets add the previous days of last month.

if(i>days){square.innerText=addedDay;if(addedDay===day&&nav===0){square.id="currentDay";}}else{// enter the last few days of last month heresquare.innerText=lastDayOfLastMonth-days+i;square.classList.add("prev-day");}
Enter fullscreen modeExit fullscreen mode

lastDayOfLastMonth is the 31st of October. But were just getting the number not the month.

So we do 31 - 3 + i(1) = 29,

And then 31 - 3 + i(2) = 30, etc.

Image description

Completed Code

letnav=0;constgetCalendar=document.getElementById("calendar")asany;constweekDays=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",];functionnextButton(){document.getElementById("nextButton")?.addEventListener("click",()=>{nav++;main();});}functionbackButton(){document.getElementById("backButton")?.addEventListener("click",()=>{nav--;main();});}functionmain(){constdt=newDate();if(nav!==0){dt.setMonth(newDate().getMonth()+nav);}constmonth=dt.getMonth();constyear=dt.getFullYear();constfirstDayOfMonth=newDate(year,month,1);constdateString=firstDayOfMonth.toLocaleString("en-us",{weekday:"long",year:"numeric",month:"numeric",day:"numeric",});constlastDayOfLastMonth=newDate(year,month,0).getDate();(document.getElementById("month-heading")asany).innerText=`${dt.toLocaleDateString("en-us",{month:"long"})}${year}`;getCalendar.innerHTML="";/**   *  we want to get the first weekday of the month,   *  so we have a string of Wednesday, 11/1/2023.   *   *  We want just the Wednesday part... so were going to make this string into an array.   * so we split the string into array elements for every comma "," and leading white space.   * dateString.split(", ") which gives us the following:   *   * (2) ['Wednesday', '11/1/2023']   */constgetFirstDayMonth=dateString.split(",")[0];// Wednesdayconstdays=weekDays.indexOf(getFirstDayMonth);/**   * Lets get the days in the current month by the following   */constdaysInMonth=newDate(year,month+1,0).getDate();// 30/**   * lets then add days plus the days in the a month so   *   * 3 + 30   */constdaysAndMonthTotal=days+daysInMonth;// 33/**   * we could create an array the reference its length   */constdaysArr=newArray(daysAndMonthTotal);// 33constday=dt.getDate();// 26/**   * We use the for loop to iterate through the daysArr   *   * If I = 1, and 1 is less than 33, render us some squares.. essentially   */for(leti=1;i<=daysArr.length;i++){constsquare=document.createElement("div")asany;square.classList.add("day");/**     * here we are saying substract the index from the days.     *     *     * e.g     *     * Days will always be 3 in this case, and I will always increment.     *     * So     * 1 - 3 = -2     * 2 - 3 = -1     * 3-3 =  0     * 4-3 = 1 // we start here     *     */constaddedDay=i-days;/**     * if the index is greater than the first day of the month add text for numbers     *     * else add padding squares     */if(i>days){square.innerText=addedDay;if(addedDay===day&&nav===0){square.id="currentDay";}}else{// enter the last few days of last month here.square.innerText=lastDayOfLastMonth-days+i;square.classList.add("prev-day");}getCalendar?.appendChild(square);}}nextButton();backButton();main();
Enter fullscreen modeExit fullscreen mode

Demo

Image description

Conclusion

Hopefully this was helpful, cheers 🥳

Credits:

https://unsplash.com/photos/a-calendar-with-red-push-buttons-pinned-to-it-bwOAixLG0uc

https://youtu.be/m9OSBJaQTlM?si=WQQkJHeqD8yPmvQc (inspiration)

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Joined

More fromEliHood

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp