Javascript 在 jQuery fullcalendar 插件中禁用时间段范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10008113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:28:05  来源:igfitidea点击:

Disable timeslot ranges in jQuery fullcalendar plugin

javascriptjqueryfullcalendar

提问by Tom

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

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

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.

尽管如此,我还有一个更紧迫的问题。我需要能够在某些时间范围内更改插槽的背景颜色。理想情况下,我会以与 eventSources 相同的方式使用它;只需指向一个 url 并使用 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.

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

采纳答案by Tom

I found a solution by using another calendar: jquery-week-calendar ( https://github.com/themouette/jquery-week-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:

这个日历有一个叫做 Freebusy 的功能。可以使用繁忙和空闲时隙范围,但是通过稍微更改源代码,我可以为时隙范围添加背景颜色。我改变了 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;
}

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.

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

回答by Adil Malik

BTW, Why don't you check it in Selectcallback?

顺便说一句,你为什么不在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
    }
}

回答by koosvdkolk

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

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

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

上面的代码是我制作的插件的一部分的编译,所以它可能无法直接工作。随时联系我。

回答by rat

I finally got this available slots to work per days.

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

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

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

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:

并且不要忘记 css 类:

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

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

}

回答by Pierre de LESPINAY

This threadin 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 guyhas implemented a very handy way to manage this purpose still using fullcalendar with this kind of code

此外,这个人已经实现了一种非常方便的方法来管理这个目的,仍然使用带有这种代码的 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
    }]      
});

Check the screenshot

检查屏幕截图

回答by Lingasamy Sakthivel

Fullcalendar has a builtin function businessHourswhich emphasizes certain time slots on the calendar.

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

回答by Martin

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

来自 dhtmlx 的另一个更加开发和支持的日历类型插件称为调度程序: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

在此处输入图片说明