ProgrammingJavascriptCareerProductivityGadgetsASP.NETWeb Design

Coding A Calendar In JavaScript: Part 2

Written by
Published on
Modified on
Filed under
Coding A Calendar In JavaScript: Part 2

The following is the follow up to the ever so popular Coding a Calendar in JavaScript, in which I created a calendar widget in JavaScript.

SUN
MON
TUE
WED
THUR
FRI
SAT

Before you continue with this post, you should head on over to that post and get familiar with that process as I will be using the same code to render the following.

I will be continuing the implementation by allowing users to select multiple days, both by clicking on date regions and by dragging multiple dates at once.

1. New variables

We are going to need to add the following new variables to the calendar script.


        var selectedDays = new Array();
        var mousedown = false;
    

The selectedDays array will be used to keep track of the currently selected dates on the calendar and the mousedown boolean expression will be used to monitor the current state of the mouse. Essentially, we want to know if we are currently mid-drag or not, for when selecting multiple days.

2. Single Day Selection

Let's begin by allowing your users to select single days on the calendar, which is most often than not the most required feature for any online calendar. The following is the loadCalendarDays() function from part 1. It has 2 new additions that you will need to make, and those are adding a new dataset to the 'day' div, to make it simpler to retrieve the selected date. And we will be adding the click event handler, that will take care of adding/removing the selected date from the selectedDays array.

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

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

    for (var i = 0; i < num; i++) {
        var tmp = i + 1;
        var d = document.createElement("div");
        d.id = "calendarday_" + tmp;
        d.className = "day";
        d.innerHTML = tmp;
        d.dataset.day = tmp;              // easier to retrieve the date


/* ****************** Click Event ********************** */ d.addEventListener('click', function(){ this.classList.toggle('selected'); if (!selectedDays.includes(this.dataset.day)) selectedDays.push(this.dataset.day); else selectedDays.splice(selectedDays.indexOf(this.dataset.day), 1); });
/* **************************************************** */

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

Let's take a look at the click event in more detail. Essentially, we're adding or removing a class to the day element, that shows that it is selected. And we will be checking if the currently selected date exists already in the selectedDays array. If it does not, it is pushed to the array, otherwise, it is spliced out.


        /* ****************** Click Event ********************** */
        d.addEventListener('click', function(){
            this.classList.toggle('selected');

            if (!selectedDays.includes(this.dataset.day))
                selectedDays.push(this.dataset.day);

            else
                selectedDays.splice(selectedDays.indexOf(this.dataset.day), 1);
        });
/* **************************************************** */

Multiple Day Selection

Multiple days can be selected by dragging the mouse through the calendar, selecting the desired days along the way. And for that we're going to be needing a few of the mouse event handlers that JavaScript provides, starting with the mousedown event, following along with the mousemove event and finishing off with the mouseup event.

mousedown - The mousedown event will simply keep track of when the mouse key is being held down. This will help ensure that we only select the days if the mouse key is indeed pressed down.


         d.addEventListener('mousedown', function(e){
            e.preventDefault();
            mousedown = true;
        });
    

mouseup - The mouseup event is essentially the same as the mousedown event. Once the mouse key has been depressed, we want to reset the mousedown variable so that it can stop selecting days.


        d.addEventListener('mouseup', function(e){
            e.preventDefault();
            mousedown = false;
        });
    

mousemove - The mousemove event is where the selection actually happens. It is very similar to the click event. The first thing we want to do is to check if the mouse key is currently pressed, which if it is, it means we are dragging our move around. In which case, we will want to pretty much replicate the click event, except we don't want to toggle the selections, we just want to make sure that they get selected.


         d.addEventListener('mousemove', function(e){
           e.preventDefault();
            if (mousedown)
            {
                this.classList.add('selected');

                if (!selectedDays.includes(this.dataset.day))
                    selectedDays.push(this.dataset.day);
            }
        });
    

Note that if you wanted to, you could likely have the days deselected on mousemove as well.

Upgrades

There's plenty that you can do with a calendar widget. While this was a good start into creating a realistically functional version of a calendar, you can go further and build out any of the following.

  • Select based on 'number of day' ranges
  • Select whole months
  • Select whole weeks

In a future post, I will be addressing these features and more.

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.

Comments

A
Anon
9/27/2019 9:09:51 AM
Thank you for this . would you please to a tutorial on how to add custom events on the calendar. Thank you
S
Seege
10/4/2019 2:46:50 PM
How would you add functionality for events?
Walt
10/10/2019 12:43:11 PM
Hey there. Many thanks for checking out the post and for the question. The best route I would say is to create a collection of objects. And each object item can represent a list of events + a calendar date. This would only be local of course, and long term storage would depend on your tech stack. Perhaps something I can cover in a part 3! If you would like a further breakdown feel free to let me know and I would be happy to extend the functionality on the calendar. Many thanks!
S
Seege
10/10/2019 12:51:17 PM
If you could do a part 3 on this subject, that would be AWESOME!!! :)
Walt
10/17/2019 3:23:26 PM
Part 3 is on its way and should be published shortly. Will cover local event storage.
R
Robert
10/27/2019 3:43:53 AM
Hi! Great stuff. I might have a dumb question, but I cannot run the source code from the part 1. It spits out an error while trying to go through the lines with c("div"). I can't find any function like this in the code or am I doing something wrong? I've included script into index file and created new object with an id of a DIV for the constructor parameter and then called render() method.
Walt
10/27/2019 9:04:37 AM
Hey there Robert. Many thanks for the words and for catching that! I have updated the .js file to include the c(el) function. It's really just a wrapper to the document.createElement function. I shorthanded it to c(el) for ease of use. Thanks again!
R
Robert
10/29/2019 11:39:39 PM
Thank You, that worked :D .. though now I got problem with how its being displayed, but I will figure it out :) *using bootstrap 4 and latest stable jQuery version
Walt
10/30/2019 12:32:18 PM
Awesome to hear Robert! Feel free to send me a link if you post it online dude. Always enjoy looking at people's custom implementations!
E
Evelyn Acosta
7/20/2020 2:18:59 PM
Hi, I was wondering if you could email me a copy of this with the ability to highlight the current date and to create, edit, and delete events to the calendar? Thank you.
C
Crystal
5/23/2022 8:23:51 AM
Hi, this is so nice and I have a Wonderfull working copy of this. Thank you so much! I am trying to get the calendar to keep the weekends from being clickable and disable with a visual grey color. I cant get the date.getDay()===0 or date.getDay()===6 to color weekend divs. Can you help me?
C
Crystal
5/23/2022 8:25:15 AM
var dayOfWeek = date.getDay(); //var isWeekend = (dayOfWeek === 6) || (dayOfWeek === 0); // 6 = Saturday, 0 = Sunday if( (dayOfWeek === 6) || (dayOfWeek === 0) ) { // 6 = Saturday, 0 = Sunday console.log("getDay test :: " + i + " :: "+ (date.getDay()-1)); d.className="day taken"; }

Developer Poll

Q:

Stay up to date

Sign up for my FREE newsletter. Get informed of the latest happenings in the programming world.

Add a comment

Keep me up to date on the latest programming news
Add Comment

Stay up to date

Get informed of the latest happenings in the programming world.

No thanks