Disable timeslot ranges in jQuery fullcalendar plugin

后端 未结 7 570
南方客
南方客 2020-12-05 03:14

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 event

相关标签:
7条回答
  • 2020-12-05 03:42

    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
        }
    }
    
    0 讨论(0)
  • 2020-12-05 03:43

    I found a solution by using another calendar: jquery-week-calendar ( https://github.com/themouette/jquery-week-calendar ).

    This calendar has a feature called Freebusy. It's ment to be used to have busy and free timeslot ranges, but by altering the source code a bit, I am able to add background colors to timeslot ranges. I changed the method freeBusyRender as follows:

    freeBusyRender: function(freeBusy, $freeBusy, calendar) {
        if(freeBusy.free == 't_red') {
            $freeBusy.css("backgroundColor", "red");
        } else if(freeBusy.free == 't_green') {
            $freeBusy.css("backgroundColor", "green");
        } else if(freeBusy.free == 't_blue') {
            $freeBusy.css("backgroundColor", "blue");
        } else if(freeBusy.free == 't_black') {
            $freeBusy.css("backgroundColor", "black");
        }
        $freeBusy.addClass('free-busy-free');
        return $freeBusy;
    }
    

    Then, I can initialize the calendar as follows:

    (function($) {
        d = new Date();
        d.setDate(d.getDate() - (d.getDay() - 3));
        year = d.getFullYear();
        month = d.getMonth();
        day = d.getDate();
        var eventData2 = {
            options: {
                timeslotsPerHour: 4,
                timeslotHeight: 12,
                defaultFreeBusy: { free: true }
            },
            events: [
                { 'id': 1, 'start': new Date(year, month, day, 12), 'end': new Date(year, month, day, 13, 00), 'title': 'Lunch with Sarah'},
                { 'id': 2, 'start': new Date(year, month, day, 14), 'end': new Date(year, month, day, 14, 40), 'title': 'Team Meeting'},
                { 'id': 3, 'start': new Date(year, month, day + 1, 18), 'end': new Date(year, month, day + 1, 18, 40), 'title': 'Meet with Joe'},
                { 'id': 4, 'start': new Date(year, month, day - 1, 8), 'end': new Date(year, month, day - 1, 9, 20), 'title': 'Coffee with Alison'},
                { 'id': 5, 'start': new Date(year, month, day + 1, 14), 'end': new Date(year, month, day + 1, 15, 00), 'title': 'Product showcase'}
            ],
            freebusys: [
                { 'start': new Date(year, month, day - 1, 8), 'end': new Date(year, month, day - 1, 18), 'free': 't_red'},
                { 'start': new Date(year, month, day, 8), 'end': new Date(year, month, day + 0, 18), 'free': 't_green' },
                { 'start': new Date(year, month, day + 1, 8), 'end': new Date(year, month, day + 1, 18), 'free': 't_blue' },
                { 'start': new Date(year, month, day + 2, 14), 'end': new Date(year, month, day + 2, 18), 'free': 't_black'},
                { 'start': new Date(year, month, day + 3, 8), 'end': new Date(year, month, day + 3, 18), 'free': 't_red' }
            ]
        };
        $(document).ready(function() {
            var $calendar = $('#calendar').weekCalendar({
    
            allowCalEventOverlap: true,
            overlapEventsSeparate: true,
            totalEventsWidthPercentInOneColumn: 95,
    
            timeslotsPerHour: 4,
            scrollToHourMillis: 0,
            height: function($calendar) {
                return $(window).height() - $('h1').outerHeight(true);
            },
            eventRender: function(calEvent, $event) {
                if (calEvent.end.getTime() < new Date().getTime()) {
                    $event.css('backgroundColor', '#aaa');
                    $event.find('.wc-time').css({
                        backgroundColor: '#999',
                        border: '1px solid #888'
                    });
                }
            },
            eventNew: function(calEvent, $event, FreeBusyManager, calendar) {
                        calEvent.id = calEvent.userId + '_' + calEvent.start.getTime();
            },
            data: function(start, end, callback) {
                        callback(eventData2);
            },
            displayFreeBusys: true,
            daysToShow: 7,
            switchDisplay: { '1 day': 1, '3 next days': 3, 'work week': 5, 'full week': 7 },
            headerSeparator: ' ',
            useShortDayNames: true
            });
        });
    })(jQuery);
    

    which gives me following result:

    calendar

    I bet this can be improved; I think I broke the freeBusy feature doing this, but I don't need it.

    0 讨论(0)
  • 2020-12-05 03:50

    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.

    0 讨论(0)
  • 2020-12-05 03:56

    There is another much more developed and supported calendar type plugin from dhtmlx called the scheduler here: http://dhtmlx.com/docs/products/dhtmlxScheduler/

    It supports disabling of timeslots, background colours, and much more. I've used it before and found it offers everything I needed.

    enter image description here

    0 讨论(0)
  • 2020-12-05 03:57

    This thread in google code allows to follow the evolution of this kind of issue. Actually it's about busyness hours colors, but it is directly linked

    Also this guy has implemented a very handy way to manage this purpose still using fullcalendar with this kind of code

    $('#calendar').fullCalendar({
        ....
        events: [
            {
                title: 'All Day Event',
                start: new Date(y, m, 1)
            }
        ],
        annotations: [{
            start: new Date(y, m, d, 13, 0),
            end: new Date(y, m, d, 15, 30),
            title: 'My 1st annotation', // optional
            cls: 'open', // optional
            color: '#777777', // optional
            background: '#eeeeff' // optional
        }]      
    });
    

    Check the screenshot

    0 讨论(0)
  • 2020-12-05 04:00

    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;
    
    }
    
    0 讨论(0)
提交回复
热议问题