Tuesday, 5 May 2015

Disabling Time Slots in JQuery Full Calendar


Suppose you have some feature implemented on fullCalendar.js where user can click on calendar slots and perform some actions.

This post will show you how to block or make the slots unavailable to users i.e stop the action to be performed on unavailable slots.


For example there's a requirement where a user is available from morning 8 to 11 o'clock and then from 3 to 6 o'clock in the evening.
 So you have to make slots from 11 to 3 unavailable/unclickable for user.

 How to do.... ? 

Step 1:

 Make an array of user's available timings as shown below
 var availableTimings = [[08:00,11:00],[15:00,18:00]];

Step 2:

Write the following javascript function:

This function will iterate all the slots in your calendar and find out the time during which user is unavailable and will block the slots

function BlockingUnavailableSlots(availableTimings) {
        if ($(".fc-slats").find("tr").length > 0) {
            var numberofRows = $("# YOUR CALENDAR ID COMES HERE").find(".fc-slats").find("tr").length;
            for (var iCount = 0 ; iCount < numberofRows; iCount++) {
                var slotTiming = $(".fc-slats").find("tr:eq(" + iCount + ")").find("td span").text().split(":");
                for (var jCount = 0; jCount < availableTimings.length; jCount++) {
                        var startTiming = availableTimings[jCount][0] != null ? availableTimings[jCount][0].split(":") : "";
                        var endTiming = availableTimings[jCount][1] != null ? availableTimings[jCount][1].split(":") : "";
                        if (startTiming != "" && endTiming != "" && startTiming.length > 0 && endTiming.length > 0) {
                            var difference = getTimeDifference(startTiming[0], startTiming[1], endTiming[0], endTiming[1], slotTiming[0], slotTiming[1]);
                            if (difference == 1) {
                                $(".fc-slats").find("tr:eq(" + iCount + ")").find("td:eq(1)").removeClass("blocked");
                                $(".fc-slats").find("tr:eq(" + iCount + ")").find("td:eq(1)").addClass("available-slot");
                                $(".fc-slats").find("tr:eq(" + iCount + ")").find("td:eq(1)").removeAttr("title");
                            }
                            else {
                                if ($(".fc-slats").find("tr:eq(" + iCount + ")").find("td:eq(1)").attr("class").indexOf("available-slot") < 0) {
                                    $(".fc-slats").find("tr:eq(" + iCount + ")").find("td:eq(1)").addClass("blocked");
                                    $(".fc-slats").find("tr:eq(" + iCount + ")").find("td:eq(1)").attr("title", "Doctor is not available for this slot");
                                }
                            }
                        }
                }
            }
        }
    }

Step 3:

Required function to calculate the time difference.

This function takes user availability start time (hour and minute) and end time (hour and minutes) and current slot time which function BlockingUnavailableSlots iterates

function getTimeDifference(shour, sminute, ehour, eminute, slothour, slotminute) {
        //Hard coded value needed here i.e 2000, 0 ,1.... intentionally added
        var start = new Date(2000, 0, 1, shour, sminute).getTime();
        var end = new Date(2000, 0, 1, ehour, eminute).getTime();
        var now = new Date(2000, 0, 1, slothour, slotminute).getTime();
        if ((start <= now) && (now <= end)) {
            return 1;
        }
        else {
            return 0;
        }
    }

Step 4:

Call above function mentioned in step 2 after rendering all calendar event

 eventAfterAllRender: function (date) {
                     disableUnavailableSlots();
                }

Step 5:

Handle default actions in day click event like this

dayClick: function (date, jsEvent, view) {
 if (jsEvent.target.className.indexOf("blocked") < 0) {
 //perform action
 }
 else{
 //no action
 }

Step 6:

Include this style to color the unavailable slots

 .blocked {
        background-color: lightgray;
    }


If you face any problem regarding full calendar please comment below. We can always find the work around :)