Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable timeslot ranges in jQuery fullcalendar plugin

I am developing a webapp and am using jQuery fullcalendar plugin.

I need to somehow disable certain time-slots.

The current method I am using is to add events for the time-slots I want to disable and disallow event overlapping.

Is there a better way to do this? I rather not disallow event overlapping.

I can live with the solution for the above problem: adding black timeslots and disallow the adding of timeslots in those areas.


Nevertheless I have a more pressing problem. I need to be able to change the background color of slots for certain time ranges. Ideally I would be using this in the same way as the eventSources; just point to an url and send the to be colored ranges back with ajax/json.

The bounty I am about to add is for this last problem (colourized slot ranges, as well in day and week view). If someone can suggest me to another solution then full calendar that can do this, that's also fine.

like image 811
Tom Avatar asked Apr 04 '12 09:04

Tom


3 Answers

BTW, Why don't you check it in Select callback?

select: function( start, end, allDay, jsEvent, view ) {
    if( /*start is the disabled time*/ )
        return false;
    else{
        // Proceed with the normal flow of your application
        // You might show a popup to get info from user to create
        // a new event here
    }
}
like image 132
Adil Malik Avatar answered Nov 19 '22 21:11

Adil Malik


Using Fullcalender, in my code I have something like this:

var availablePeriods = [["8:00", "12:00"], ["13:00", "17:00"]]; //these are the time intervals when the slots are OPEN

if (availablePeriods !== undefined) {
  slots = $element.find('.fc-agenda-slots tr');

  /* first add 'closed' class to all slots, and then remove class from 'open' slotts */
  slots.addClass('experdscheduler_closedSlot');
  if (jQuery.isArray(availablePeriods)) {
    /* only in weekview and dayview */
    currentView = plugin.getView();

    if (currentView === 'agendaWeek' || currentView === 'agendaDay') {
      numberOfAvailablePeriods =  availablePeriods.length;

      scheduleStartTime = timeToFloat($element.fullCalendar( 'option', 'minTime'));            
      scheduleSlotSize = $element.fullCalendar( 'option', 'slotMinutes') /60;

      /* function to calculate slotindex for a certain time (e.g. '8:00') */    
      getSlotIndex = function(time) {
        time = timeToFloat(time);            
        return Math.round((time-scheduleStartTime)/scheduleSlotSize);
      }


      /* remove 'closed' class of open slots */                 
      for (i=0; i<numberOfAvailablePeriods; i++) {            
        startOfPeriodSlot = getSlotIndex(timeToFloat(availablePeriods[i][0]));
        endOfPeriodSlot = getSlotIndex(timeToFloat(availablePeriods[i][1]));

        for (j=startOfPeriodSlot; j<endOfPeriodSlot; j++) {
          slots.eq(j).removeClass('experdscheduler_closedSlot');
        }
      }          
    }
  }         
}

/**
 * Helper function: Converts a given time to a float, e.g. '8:15' becomes 8.25
 * @param mixed time A integer, float or a string. Valid strings: '8:15', '20:15', '8:15am', '8:15pm', '8.15', etc.
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @author Koos van der Kolk <koosvdkolk at gmail dot com>
 * @return float
 **/
function timeToFloat(time) {      
  var returnValue, timeAsArray, separator, i, timeSeparators = [':', '.'], numberOfSeparators;

  /* is time an integer or a float? */
  if (parseInt(time, 10) === time || parseFloat(time) === time) {
    returnValue = time;
  } else {
    /* time will be considered a string, parse it */
    time = time.toString();

    numberOfSeparators = timeSeparators.length;

    for (i = 0; i < numberOfSeparators; i = i + 1) {
      separator = timeSeparators[i];

      if (time.indexOf(separator) > 0) {
        timeAsArray = time.split(separator);

        returnValue = parseInt(timeAsArray[0], 10) + parseInt(timeAsArray[1], 10) / 60;

        /* does string contain 'p' or 'pm'? */
        if (time.indexOf('p') > 0 && returnValue <= 12) {
          returnValue = returnValue + 12;
        }
      }
    }
  }
  return returnValue;
}

The above code is a compilation of parts of a plugin I made, so it might not work directly. Feel free to contact me.

like image 5
koosvdkolk Avatar answered Nov 19 '22 21:11

koosvdkolk


I finally got this available slots to work per days.

adjustment of koosvdkolk's answer to have different available slots per days:

   function adjustWorkHourSlotSize(day_num) {
      $(".day"+day_num+"slot").width($(".fc-col"+day_num).width()-2);

   }

   function addWorkHours2(availablePeriods, calendar_element) {
       if (availablePeriods !== undefined) {
          numberOfAvailablePeriods =  availablePeriods.length;

          //slots.addClass('nySchedule_unavailable_slots'); 
          //iterate trough days and get avail periods for each day of week
          currentView = calendar_element.fullCalendar('getView');
          currentView =  currentView.name;
          if (currentView === 'agendaWeek' || currentView === 'agendaDay') {



            scheduleStartTime = timeToFloat(calendar_element.fullCalendar( 'option', 'minTime'));            
            scheduleSlotSize = calendar_element.fullCalendar( 'option', 'slotMinutes') /60;
            /* function to calculate slotindex for a certain time (e.g. '8:00') */    
            getSlotIndex = function(time) {
              time = timeToFloat(time);            
              return Math.round((time-scheduleStartTime)/scheduleSlotSize);
            }

            slots_content = calendar_element.find('.fc-agenda-slots tr .ui-widget-content div');
            for (var i=0; i!=numberOfAvailablePeriods; i++) {
              if (currentView === 'agendaWeek') {

                slots_content.append("<div class='day"+i+"slot dayslot'></div>");
                $(".day"+i+"slot").addClass('unavailable');
                adjustWorkHourSlotSize(i);
              }


              dayPeriodsLength=availablePeriods[i].length;
              for (var j=0; j!=dayPeriodsLength; j++) {
                start=availablePeriods[i][j][0];
                end=availablePeriods[i][j][1];

                startOfPeriodSlot = getSlotIndex(timeToFloat(start));
                endOfPeriodSlot = getSlotIndex(timeToFloat(end));
                for (k=startOfPeriodSlot; k<endOfPeriodSlot; k++) {
                  $(".day"+i+"slot").eq(k).removeClass("unavailable");
                }
              }                
            }
          }
       }
   }

now just call:

var availablePeriods = [ [["8:00", "16:00"],["3:00", "5:00"]], [["9:00", "14:00"]] ];
addWorkHours2(availablePeriods, $("#calendar"));

and dont forget css classes:

.dayslot {
  float: left;
  margin-left: 2px;
}

.fc-agenda-slots .unavailable{
  background-color: #e6e6e6;

}
like image 4
rat Avatar answered Nov 19 '22 21:11

rat