我使用Fullcalendar.io v2
在我的agendaWeek
mod中,我有事件,所有事件都显示在日期广场的一行上。所以,我有更多的事件,然后是更多的事件块。
如何每行显示一个事件?就像month
mod一样。我有更多的事件,然后更高的日期块我(高度)。也许,很难使用像eventRender
这样的函数,因为如果你检查.fs-event
元素(网页开发者工具),你会看到事件块使用position:absolute;top:300px;left:33%
...所以我不会&#39不知道该怎么做。
答案 0 :(得分:3)
我也遇到了这个问题,这是非常困难的,因为插件以奇怪的方式组成日历,使用一些表并使用位置绝对动态定位事件并改变css 顶部属性。
然而,我找到了一个非常好的通用解决方案。首先,我将向您展示代码,我将解释代码究竟是什么。
我使用fullCalendar的选项eventAfterAllRender。这是example working。
我使用moment来管理时间,我假设fullCalendar html元素的ID为“日历”。
eventAfterAllRender: function() {
// define static values, use this values to vary the event item height
var defaultItemHeight = 25;
var defaultEventItemHeight = 18;
// ...
// find all rows and define a function to select one row with an specific time
var rows = [];
$('div.fc-slats > table > tbody > tr[data-time]').each(function() {
rows.push($(this));
});
var rowIndex = 0;
var getRowElement = function(time) {
while (rowIndex < rows.length && moment(rows[rowIndex].attr('data-time'), ['HH:mm:ss']) <= time) {
rowIndex++;
}
var selectedIndex = rowIndex - 1;
return selectedIndex >= 0 ? rows[selectedIndex] : null;
};
// reorder events items position and increment row height when is necessary
$('div.fc-content-col > div.fc-event-container').each(function() { // for-each week column
var accumulator = 0;
var previousRowElement = null;
$(this).find('> a.fc-time-grid-event.fc-v-event.fc-event.fc-start.fc-end').each(function() { // for-each event on week column
// select the current event time and its row
var currentEventTime = moment($(this).find('> div.fc-content > div.fc-time').attr('data-full'), ['h:mm A']);
var currentEventRowElement = getRowElement(currentEventTime);
// the current row has to more than one item
if (currentEventRowElement === previousRowElement) {
accumulator++;
// move down the event (with margin-top prop. IT HAS TO BE THAT PROPERTY TO AVOID CONFLICTS WITH FullCalendar BEHAVIOR)
$(this).css('margin-top', '+=' + (accumulator * defaultItemHeight).toString() + 'px');
// increse the heigth of current row if it overcome its current max-items
var maxItemsOnRow = currentEventRowElement.attr('data-max-items') || 1;
if (accumulator >= maxItemsOnRow) {
currentEventRowElement.attr('data-max-items', accumulator + 1);
currentEventRowElement.css('height', '+=' + defaultItemHeight.toString() + 'px');
}
} else {
// reset count
rowIndex = 0;
accumulator = 0;
}
// set default styles for event item and update previosRow
$(this).css('left', '0');
$(this).css('right', '7px');
$(this).css('height', defaultEventItemHeight.toString() + 'px');
$(this).css('margin-right', '0');
previousRowElement = currentEventRowElement;
});
});
// this is used for re-paint the calendar
$('#calendar').fullCalendar('option', 'aspectRatio', $('#calendar').fullCalendar('option', 'aspectRatio'));
}
代码的工作原理:
首先,我发现所有 tr 元素都是我日历的行(请注意,它们包含一个属性及其拥有时间的行)。
稍后我会迭代每一列,并为每一列获取其事件项。每个事件项都是 anchor 元素,其中一个内部子项的日期为 data-full 。
从事件中我看到它应该是什么行,如果有多个项目,则在该行中,然后增加事件项目所在的位置。我使用 margin-top 属性,因为插件不使用或重新调整此属性(不要使用 top 属性)。
在行中,我设置了一个数据属性,以获取具有该行任何列的最大事件数量。有了它,我可以计算行是否必须增加高度。
嗯,这基本上就是代码的作用。如果你有一些问题请做 -
答案 1 :(得分:2)
您可以为活动添加一个类,并尝试使用CSS
自定义此事件作为示例,您可以使用样式
.test {
width: 100%;
height: auto;
position: relative !important;
left: 0% !important;
margin-right: 0% !important;
}
和这样的事件:
{
title: 'Lunch',
start: '2014-06-09T10:30:00',
className: 'test'
},
如果这是您想要实现的目标,请查看此Fiddle
另外,通过一些解决方法,您可以使用eventAfterRender
回调来调整特定行的高度。但这不是一个非常安全的解决方案,需要进行一些调整:
eventAfterRender: function( event, element, view ) {
var row = $(".fc-slats tr:contains('"+ moment(event.start).format('ha') + "')");
if (moment(event.start).format('mm') != '00')
{
row = row.next();
}
row.height(element.height()+row.height());
}
答案 2 :(得分:0)
我也遇到了同样的问题,虽然亚历山大的答案很棒,但我遇到了性能问题,因为它有很多DOM操作。我每周大约有2000-3000个事件,并且在Firefox,IE等浏览器中无法使用。因此,调整Alexander的答案并最大限度地减少DOM操作,提出了以下解决方案。
变量
var itemsOnSlot = {}; // counter to save number of events in same time slot
var maxItemsOnRow = {}; // counter to save max number of events in row
利用eventRender和eventAfterAllRender回调
eventRender: function(event, element, view){
// for each event, margin top and other css attributes are changed to stack events on top of each other
if(!(event.start in itemsOnSlot)){ // if itemsOnSlot has no index with current event's start time
itemsOnSlot[event.start] = 1; // create index and set count to 1
$(element).addClass('slot-attributes'); // add css to change the event style
}else{ // if itemsOnSlot already has a index with current event's start time
itemsOnSlot[event.start] += 1; // increase counter by 1
// change margin top to stack events on top of each other and add css to change the event style
$(element).css('cssText','margin-top:'+(itemsOnSlot[event.start]*18)+'px !important;').addClass('slot-attributes');
}
},
eventAfterAllRender: function(view) {
// this loop is run to get the max number of events per row
for(var start in itemsOnSlot){ // for all the timeslots with events in them
var time = start.substr(16,8); // extract required time format from index - eg. 14:00:00
if(!(time in maxItemsOnRow)){ // if maxItemsOnRow has no index with current time
maxItemsOnRow[time] = itemsOnSlot[start]; // create index and set count to current day's number of events in this time slot
}else{ // if maxItemsOnRow already has a index with current time
if(itemsOnSlot[start] > maxItemsOnRow[time]){ // if current day's number of events in this time slot are greater than existing number
maxItemsOnRow[time] = itemsOnSlot[start]; // replace current time's number of slots
}
}
}
// change height of each row using values from maxItemsOnRow
$('div.fc-slats > table> tbody > tr[data-time]').each(function() { // for all rows in calendar
var time = $(this).attr('data-time'); // get time of each row
if(time in maxItemsOnRow){ // if current row's time is in maxItemsOnRow
$(this).css('cssText','height:'+(maxItemsOnRow[time]*18)+'px !important;'); // change the height of the row to contain max items in row
}else{ // if current row's time is not in maxItemsOnRow (no events in current time slot)
$(this).css('cssText','display: none !important;'); // hide timeslot
}
});
// repaint the calendar with new dimensions
$('#calendar').fullCalendar('option', 'aspectRatio', $('#calendar').fullCalendar('option', 'aspectRatio'));
itemsOnSlot = {}; // reset variables
maxItemsOnRow = {}; // reset variables
},
CSS
.slot-attributes {
left: 4px !important;
right: 3px !important;
height: 15px !important;
margin-right: 0 !important;
}