The following is a responsive, pure JavaScript only calendar that anybody can implement, modify, update, etc in under 5 minutes.

SUN
MON
TUE
WED
THUR
FRI
SAT

Overview

In this tutorial, I will cover rendering a calendar onto a webpage, from the months and years to the days using 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 updated

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

This is the first stroke in the painting. The calendar is essentially 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. These will be children of the months div up above.


<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>

And 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);
        }
    }

Creating the days

Now we're at the heart of the calendar. Day rendering is again, somewhat like the previous month and year functions. We're going to calculate the number of days in a specified year/month period and then create a <div> for each one of those days. This function gets called whenever the calendar requires redrawing, such as when we select a new month or a new year.

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)
    {
        var 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);
    }

And now, let's put it all together

In part 2...

At this point, you should have a calendar to display. It doesn't really do anything just yet, but it will. 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.

Files
Suggest the next blog post

Walter Guevara

Walter G. is a software engineer with over 10 years of professional experience. When he isn't blogging or being a CTO he enjoys coding randomly complex things that he hopes many people will get a chance to use one day.

Question or comment? (6)

L
Lynn
Did you ever do Part 2?
4/13/2018 8:13:13 AM
Walt
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!
4/29/2018 10:17:16 AM
U
Usama
When is the 2nd part coming? I don't get why it takes that long...
5/4/2018 12:24:15 PM
Walt
Part 2 is on its way.
11/4/2018 10:09:04 PM
N
Neil
Did part 2 come yet??
1/3/2019 9:54:23 AM
Walt
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
1/7/2019 11:28:32 AM

Add a comment

Send me your weekly newsletter filled with awesome ideas
Start
Score: 0
Use the following controls:
snake left
snake up
snake down
snake right