How to Add Full Calendar Icon to Monthly View Grid?

With and Without dayCellDidMount hook

To add an icon to a day, we need to identify the grid we want to add an icon to. For instance, today, past days, future days, weekends only, etc. Then we add the icon through JavaScript.

There are two ways to do that:

  1. Identify the cell to add an icon to inside the dayCellDidMount render hook, and add the icon
  2. Right After calendar render, select the cell element(s) through the combination of classes using querySelectorAll and add the icon to it/them

Here’s the calendar with a plus icon on all future days.

Here’s how to add it, using both methods.

Using dayCellDidMount

dayCellDidMount render hook gives us arg object, which has el in it that we can use to manipulate or add to the required cell.

document.addEventListener('DOMContentLoaded', function() {
    var calendarEl = document.getElementById('calendar');
    var calendar = new FullCalendar.Calendar(calendarEl, {
      initialView: 'dayGridMonth',
      dayCellDidMount : function(arg){
        if(arg.el.classList.contains("fc-day-future")){
          var theElement = arg.el.querySelectorAll(".fc-daygrid-day-frame > .fc-daygrid-day-events")[0]
          setTimeout(function(){
            if(theElement.querySelectorAll(".fc-daygrid-event-harness").length === 0){ // check there's no event
              theElement.innerHTML = theElement.innerHTML + '<div class="text-center"><i class="calendar-icon fas fa-plus"></i></span></div>';
            }
          }, 10)
        }
      }
    });
    calendar.render();  
  });

In case of events present on any of the days, we don’t want to show plus icon. For that, we check the existence of the .fc-daygrid-event-harness class inside the element, because it won’t be present on event-less days. Notice that this check is wrapped in setTimeout. It’s because .fc-daygrid-event-harness is always empty initially at the time dayCellDidMount is called.

Using querySelectorAll

The same thing as above can be done by identifying all the elements using document.querySelectorAll without using any hook.

document.addEventListener('DOMContentLoaded', function() {
  var calendarEl = document.getElementById('calendar');
  var calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'dayGridMonth'
  });
  calendar.render();

  var selectedDays = document.querySelectorAll('.fc-day-future > .fc-daygrid-day-frame > .fc-daygrid-day-events');
  for(var i = 0; i < selectedDays.length; ++i){
    if(selectedDays[i].querySelectorAll(".fc-daygrid-event-harness").length === 0){ // check there's no event
      selectedDays[i].innerHTML = selectedDays[i].innerHTML + '<div class="text-center"><i class="calendar-icon fas fa-plus"></i></span></div>';
    }
  }
});

We loop over future days by selecting them through .fc-day-future > .fc-daygrid-day-frame > .fc-daygrid-day-events selector.

Notice there’s a downside to this method. We only add icons on the initial render. So if we move between months by clicking today, next, or prev, the icons won’t appear in future months, and the current icons will vanish too.

To overcome this, we add a listener to .fc-button, which will be fired on clicking today, next, and prev, and call addIcon from inside of it. addIcon is a method where we move our original logic. We also call this method once outside click listener for initial rendering.

We also need to add an extra check to look for existing .fa-plus, or else multiple icons will appear on some days.

document.addEventListener('DOMContentLoaded', function() {
   var calendarEl = document.getElementById('calendar');
   var calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'dayGridMonth'
   });
   calendar.render();

   function addIcon(){
      var selectedDays = document.querySelectorAll('.fc-day-future > .fc-daygrid-day-frame > .fc-daygrid-day-events');
      for(var i = 0; i < selectedDays.length; ++i){
        if(selectedDays[i].querySelectorAll(".fc-daygrid-event-harness").length === 0 &&
        selectedDays[i].querySelectorAll(".fa-plus").length === 0){
          selectedDays[i].innerHTML = selectedDays[i].innerHTML + '<div class="text-center"><i class="calendar-icon fas fa-plus"></i></span></div>';
        }
      }
    }

    document.querySelectorAll('.fc-button').forEach(function(el){
      el.addEventListener('click', function() {
        addIcon()
      });
    }); 

    addIcon();
});

In both cases above, text-center is a bootstrap class to center the icon (Tailwind’s text-center will work the same), and calendar-icon is a class to change icon font and color.

.calendar-icon {
  font-size: 14px;
  color: lightgray;
}

The fontawesome can be replaced with glyphicon icon too:

selectedDays[i].innerHTML = selectedDays[i].innerHTML + 
  '<div class="text-center"><span class="calendar-icon glyphicon glyphicon-plus"></span></div>';

Other Selectors

Below are some useful query selectors examples for conditionally adding icons. That can be replaced in either of the methods mentioned above.

- Mondays

if(arg.el.classList.contains("fc-day-mon")) {
  //...
}

// OR

document.querySelectorAll('.fc-day-mon > .fc-daygrid-day-frame > .fc-daygrid-day-events');

- Future Mondays

if(arg.el.classList.contains("fc-day-mon") && arg.el.classList.contains("fc-day-future")) {
  //...
}

//OR

document.querySelectorAll('.fc-day-mon.fc-day-future > .fc-daygrid-day-frame > .fc-daygrid-day-events');

- Past Mondays

if(arg.el.classList.contains("fc-day-mon") && arg.el.classList.contains("fc-day-past")) {
  //...
}

// OR

document.querySelectorAll('.fc-day-mon.fc-day-past > .fc-daygrid-day-frame > .fc-daygrid-day-events');

- Weekends

if(arg.el.classList.contains("fc-day-sun") || arg.el.classList.contains("fc-day-sun")) {
  //...
}

// OR

document.querySelectorAll('.fc-day-sun,fc-day-sat > .fc-daygrid-day-frame > .fc-daygrid-day-events');

Add Multiple Icons On Different Days

For this, we need to get select multiple elements with different conditions and add our icons of choice. Using the second method, let’s add a cross icon on past days, and a plus on future days.

The code would be:

  document.addEventListener('DOMContentLoaded', function() {
    var calendarEl = document.getElementById('calendar');
    var calendar = new FullCalendar.Calendar(calendarEl, {
      initialView: 'dayGridMonth'
    });
    calendar.render();

    function addIcon() {
      var futureDays = document.querySelectorAll('.fc-day-future > .fc-daygrid-day-frame > .fc-daygrid-day-events');
      for (var i = 0; i < futureDays.length; ++i) {
        if (futureDays[i].querySelectorAll(".fc-daygrid-event-harness").length === 0 &&
          futureDays[i].querySelectorAll(".fa-plus").length === 0) {
          futureDays[i].innerHTML = futureDays[i].innerHTML + '<div class="text-center"><i class="calendar-icon fas fa-plus"></i></span></div>';
        }
      }

      var pastDays = document.querySelectorAll('.fc-day-past > .fc-daygrid-day-frame > .fc-daygrid-day-events');
      for (var i = 0; i < pastDays.length; ++i) {
        if (pastDays[i].querySelectorAll(".fc-daygrid-event-harness").length === 0 &&
          pastDays[i].querySelectorAll(".fa-times").length === 0) {
          pastDays[i].innerHTML = pastDays[i].innerHTML + '<div class="text-center"><i class="calendar-icon fas fa-times"></i></span></div>';
        }
      }
    }

    document.querySelectorAll('.fc-button').forEach(function(el){
      el.addEventListener('click', function() {
        addIcon()
      });
    }); 

    addIcon();
  });



When you purchase through links on techighness.com, I may earn an affiliate commission.