Coding A Calendar In JavaScript

Written by
Published on
Modified on
Category

Overview

In this tutorial I will cover rendering a calendar onto a webpage with a few lines of JavaScript. The calendar will include dropdowns for the months and the years using only plain old JavaScript. The process will be as follows:

  • Render the months onto a dropdown
  • Render the years onto a dropdown
  • Render the days for the currently selected month/year combination
  • Redraw the calendar when the months/years are changed

Changing the months and/or year will redraw the calendar to match the correct days for that given month and year.

If you are a beginner with JavaScript, or just need more insight, I highly recommend Secrets of the JavaScript Ninja which you can purchase on Amazon here. It's a solid read and the book gives a very deep dive into the many subtle aspects of JavaScript for those that are new to the language.

The final rendered calendar will look like the following.

Demo

SUN
MON
TUE
WED
THUR
FRI
SAT

The HTML

The calendar is comprised of a parent div with 3 main components inside of it. The first 2 components being the dropdowns for the months and another for a given range of years.

And because the days of the week are not likely to change anytime soon, I went ahead and created the calendars day headers manually. When the page loads, the script will grab the current users month and year from the browser and will draw a calendar based on the current date/time.

The HTML

<div class="calendar" id="calendar">
    <div class="calendar-btn month-btn" onclick="$('#months').toggle('fast')">
        <span id="curMonth"></span>
        <div id="months" class="months dropdown"></div>
    </div>

    <div class="calendar-btn year-btn" onclick="$('#years').toggle('fast')">
        <span id="curYear"></span>
        <div id="years" class="years dropdown"></div>
    </div>

    <div class="clear"></div>

    <div class="calendar-dates">
        <div class="days">
            <div class="day label">SUN</div>
            <div class="day label">MON</div>
            <div class="day label">TUE</div>
            <div class="day label">WED</div>
            <div class="day label">THUR</div>
            <div class="day label">FRI</div>
            <div class="day label">SAT</div>

            <div class="clear"></div>
        </div>

        <div id="calendarDays" class="days">
        </div>
    </div>
</div>

Creating the months

Lucky for us, there are only 12 months in the year and we can store them as a simple array of strings. This array will be used to create the dropdown in the div with the id of "months".


<script>
    var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

    function drawCalendarMonths()
    {
        for(var i = 0; i < months.length; i++)
        {
            var doc = document.createElement("div");
            doc.innerHTML = months[i];
            doc.classList.add("dropdown-item");

            doc.onclick = (function () {
                var selectedMonth = i;
                return function ()
                {
                    month = selectedMonth;
                    document.getElementById("curMonth").innerHTML = months[month];
                    loadCalendarDays();
                    return month;
                }
            })();

            document.getElementById("months").appendChild(doc);
        }
    }
</script>

Running that function, the result should be the following:

Building A Responsive Calendar In JavaScript Part 1

Make note of the loadCalendarDays() function being called when we select a new month. This function will redraw the calendar whenever a new month is selected to reflect the new month selection.

Creating the years

We can follow a similar process to render the years dropdown.


    function loadYears()
    {
        // whichever date range makes the most sense
        var startYear = 1900;
        var endYear = 2022;

        for(var i = startYear; i <= endYear; i++)
        {
            var doc = document.createElement("div");
            doc.innerHTML = i;
            doc.classList.add("dropdown-item");

            doc.onclick = (function(){
                var selectedYear = i;
                return function(){
                    year = selectedYear;
                    document.getElementById("curYear").innerHTML = year;
                    loadCalendarDays();
                    return year;
                }
            })();

            document.getElementById("years").appendChild(doc);
        }
    }

Note that I started the years dropdown at 1900 and ended it at 2022. You can of course update those variables to fit your own needs.

The process is essentially the same though as with rendering months. If any year is selected, the loadCalendarDays() function will be called in order to re-render the calendar days.

Creating the days

Now we're at the heart of the calendar. Day rendering is somewhat similar to the previous month and year generation functions. We're essentially going to calculate the number of days in a specified year/month period and then create a <div> for each one of the days calculated.

Also note that this function gets called whenever the calendar requires redrawing, such as when we select a new month or a new year from either of those dropdowns.

daysInMonth(): I created a helper function called daysInMonth() that will return the number of days in a month/year period selected. We'll essentially loop through these days and create a 'day' element onto our calendar for each one found.

getDay(): The JavaScript Date object provides us with the getDay() method which will return the day of the week for any given date. In our case, we want to know when the very first day of the month will lie on. And we'll ignore the previous days leaving up to that by creating empty 'day' elements with no particular meaning.


    function daysInMonth(month, year)
    {
        let d = new Date(year, month+1, 0);
        return d.getDate();
    }

    function loadCalendarDays()
    {
        document.getElementById("calendarDays").innerHTML = "";

        var tmpDate = new Date(year, month, 0);
        var num = daysInMonth(month, year);
        var dayofweek = tmpDate.getDay();       // find where to start calendar day of week

Here I'm clearing the "canvas", as it were, and calculating the total days in the month and the day of the week where we will begin the month.


        // create day prefixes
        for(var i = 0; i <= dayofweek; i++)
        {
            var d = document.createElement("div");
            d.classList.add("day");
            d.classList.add("blank");
            document.getElementById("calendarDays").appendChild(d);
        }

We'll want to ignore any days leading up to the first day of the calendar. The above loop will essentially add empty day elements to the calendar. And the following function will render the actual calendar days onto the main div container.


        // render the rest of the days
        for(var i = 0; i < num; i++)
        {
            var tmp = i + 1;
            var d = document.createElement("div");
            d.id = "calendarday_" + i;
            d.className = "day";
            d.innerHTML = tmp;
            document.getElementById("calendarDays").appendChild(d);
        }

        var clear = document.createElement("div");
        clear.className = "clear";
        document.getElementById("calendarDays").appendChild(clear);
    }

In part 2

At this point, you should have a calendar to display that can render the days for any given month and year combination. In part 2, I'll go over single date selections, date range selections and custom events for each day. In the meantime, feel free to download the resource files down below and update, modify, improve, and enjoy the code.

Update: Part 2 can be found right over here.

Comments

L
Lynn
4/13/2018 8:13:13 AM
Did you ever do Part 2?
Walt
4/29/2018 10:17:16 AM
Hey there Lynn, It will be coming soon! I have a backlog of posts to finish up, but this one is right around the corner!
U
Usama
5/4/2018 12:24:15 PM
When is the 2nd part coming? I don't get why it takes that long...
Walt
11/4/2018 10:09:04 PM
Part 2 is on its way.
N
Neil
1/3/2019 9:54:23 AM
Did part 2 come yet??
Walt
1/7/2019 11:28:32 AM
Hey there Neil, it indeed has, you can check it out right over here: https://www.thatsoftwaredude.com/content/8914/coding-a-calendar-in-javascript-part-2
M
4/15/2019 9:42:58 AM
where is part 2
Walter
6/25/2020 5:04:48 PM
Part 2 is linked to right at the end of this article. Many thanks!
s
saikumar
2/25/2020 2:27:55 AM
the above code is not working
J
Jan
9/23/2020 10:20:23 AM
thanks for the tutorial!
s
student-303
12/8/2020 2:29:17 AM
hey, I was wondering if I someone was to use this type of calander as a base for a project. (lets say a personal calender) what would happen after 31/12/2022. (DD/MM/YYYY)? would the calnder loop/ stop working?
s
student-303
12/8/2020 2:29:17 AM
hey, I was wondering if I someone was to use this type of calander as a base for a project. (lets say a personal calender) what would happen after 31/12/2022. (DD/MM/YYYY)? would the calnder loop/ stop working?
Walter Guevara is a software engineer, startup founder and currently teaches programming for a coding bootcamp. He is currently building things that don't yet exist.

Developer Poll 🐱‍💻

Q:

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post