Coding A Calendar In JavaScript

Written by
Published on
Modified on

SUN
MON
TUE
WED
THUR
FRI
SAT

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, years and days using and will only use 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 per month and the correct offset in the week.

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 that 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 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 months is selected.

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.

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.

Leave a comment

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!

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post