2012-04-04 21 views
20

我正在开发一个webapp并使用jQuery fullcalendar plugin在jQuery fullcalendar插件中禁用时隙范围

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

我正在使用的当前方法是为要禁用并禁止事件重叠的时间段添加事件。

有没有更好的方法来做到这一点?我宁愿不禁止事件重叠。

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


不过,我有一个更紧迫的问题。我需要能够在特定时间范围内更改插槽的背景颜色。理想情况下,我将以与eventSources相同的方式使用它;只需指向一个url,然后用ajax/json发送彩色范围。

我要添加的赏金就是为了这个最后一个问题(着色插槽范围,以及在日和周视图中)。如果有人可以建议我到另一个解决方案,那么可以做到这一点的完整日历,这也很好。

+0

没有比这更好的主意了;我只是添加了黑色时隙,并计划在有人制作或扩展时隙并禁止它们与黑色(禁用)插槽重叠时捕捉事件。如果我找到更好的方法,我一定会在这里发布。 – Tom 2012-06-07 17:27:26

+0

关于你目前的解决方案。在禁用时段的周视图中,整个星期都会被禁用。您只能在2012年6月8日禁用6 am-7am。对 ? – 2012-06-08 09:32:03

+0

是的,你可以;我只是创建一个特定时间段的时间段(如果我没有错误,最小值是15分钟)。更进一步说,如果有人试图创建一个与它重叠的时隙,我将在事件处理程序中禁止它。我打算检查服务器端,并为此使用ajax。你可能注意到了;这个项目还没有完成,但它有一些拖延我的手,但很快我会实施我在这里告诉你的;我已经做了一些认真的测试来证明概念。 – Tom 2012-06-08 11:13:54

回答

-1

我通过其他日历找到了解决办法。

此日历有一个名为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; 
} 

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

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

这给了我下面的结果:

calendar

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

7

顺便说一句,你为什么不检查Select回调? jQuery的周历(https://github.com/themouette/jquery-week-calendar):

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 
    } 
} 
+2

Adil,谢谢你的建议。我已经计划做类似的事情。我正在寻找的是一种让用户在视觉上清楚某些时隙被禁用的方式,以便他们在点击它之前就能看到它。迄今为止的解决方案是创建黑色事件。 – Tom 2012-06-30 06:19:18

+0

虽然答案尚未找到**,但您收到赏金是因为您在赏金期间参与了此活动。这笔赞助金的目的现在已经完成,这是为了引起注意,可能会导致可行的答案。干杯! – arttronics 2012-07-06 09:14:57

+0

@arttronics谢谢:) – 2012-07-06 09:51:41

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

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

+0

这使得有可能在某些时段有开放和封闭的插槽,对吧? – Tom 2012-07-16 15:19:39

+0

嗯,不是真的:它增加了一个班到'封闭'的插槽,所以他们可以例如被赋予灰色背景色。但是这是你想要的,还是不是? – koosvdkolk 2012-07-17 06:48:42

+0

检查http://nl.picturepush.com/public/8749184截图(怪异的,我不能把它添加到我原来的帖子...) – koosvdkolk 2012-07-17 07:05:29

3

This thread在谷歌代码允许跟随这种问题的演变。其实它是关于繁忙小时的颜色,但它有直接联系

而且this guy已经实施了非常方便的方式来管理这个目的仍然使用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 
    }]  
}); 

检查screenshot

+0

嗨,截图看起来很神奇,我试图实现你的代码,但我不管理。我做了一个jsFiddle。我究竟做错了什么? http://jsfiddle.net/sebababi/g5gtG/2/ – Sebastian 2014-01-07 13:18:01

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; 

} 
+0

嗨,我试图实现你的代码,但我没有设法使它的工作,我做了一个jsFiddle,你能帮我吗? http://jsfiddle.net/sebababi/w64Hd/ – Sebastian 2014-01-07 13:02:26

+0

他的代码有点过时了,此时不完整。如果你还需要帮助,也许我可以帮你塞巴斯蒂安。然而,这只是可用时段的视觉指标。 – 2014-01-28 22:57:18

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