22

我正在开发一个 webapp 并且正在使用jQuery fullcalendar 插件

我需要以某种方式禁用某些时间段。

我正在使用的当前方法是为我想要禁用和禁止事件重叠的时隙添加事件。

有一个更好的方法吗?我宁愿不允许事件重叠。

我可以接受上述问题的解决方案:添加黑色时隙并禁止在这些区域添加时隙。


尽管如此,我还有一个更紧迫的问题。我需要能够在某些时间范围内更改插槽的背景颜色。理想情况下,我会以与 eventSources 相同的方式使用它;只需指向一个 url 并使用 ajax/json 将要着色的范围发送回来。

我即将添加的赏金是针对最后一个问题(彩色插槽范围,以及日视图和周视图)。如果有人可以向我建议另一种解决方案,那么完整的日历可以做到这一点,那也很好。

4

7 回答 7

6

顺便说一句,你为什么不在Select回调中检查它?

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
    }
}
于 2012-06-29T16:17:53.803 回答
5

使用 Fullcalender,在我的代码中我有这样的东西:

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

上面的代码是我做的一个插件的一部分的汇编,所以它可能不能直接工作。随时联系我。

于 2012-07-16T14:36:19.480 回答
4

我终于让这个可用的插槽每天工作。

调整 koosvdkolk 的答案以每天有不同的可用插槽:

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

现在只需调用:

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

并且不要忘记 css 类:

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

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

}
于 2012-12-13T11:40:28.720 回答
3

谷歌代码中的这个线程允​​许跟踪此类问题的演变。实际上是关于忙碌时间的颜色,但它是直接相关的

此外,这个人已经实现了一种非常方便的方法来管理这个目的,仍然使用带有这种代码的 fullcalendar

$('#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
    }]      
});

检查屏幕截图

于 2012-08-30T07:30:08.293 回答
0

Fullcalendar 有一个内置功能businessHours,它强调日历上的某些时间段。

businessHours: [ // specify an array instead
{
    dow: [ 1, 2, 3 ], // Monday, Tuesday, Wednesday
    start: '08:00', // 8am
    end: '18:00' // 6pm
},
{
    dow: [ 4, 5 ], // Thursday, Friday
    start: '10:00', // 10am
    end: '16:00' // 4pm
}
]
于 2017-11-22T11:48:26.640 回答
-1

我通过使用另一个日历找到了解决方案:jquery-week-calendar ( https://github.com/themouette/jquery-week-calendar )。

这个日历有一个叫做闲忙的功能。它习惯于有繁忙和空闲的时间段范围,但是通过稍微改变源代码,我可以为时间段范围添加背景颜色。我将方法 freeBusyRender 更改如下:

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

然后,我可以按如下方式初始化日历:

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

这给了我以下结果:

日历

我敢打赌这可以改进;我想我这样做破坏了 freeBusy 功能,但我不需要它。

于 2012-07-12T08:25:17.187 回答
-7

来自 dhtmlx 的另一个更加开发和支持的日历类型插件称为调度程序:http: //dhtmlx.com/docs/products/dhtmlxScheduler/

它支持禁用时隙、背景颜色等等。我以前用过它,发现它提供了我需要的一切。

在此处输入图像描述

于 2014-11-12T09:52:09.453 回答