Javascript Fullcalendar.io:如何在agendaWeek中每行显示一个事件,然后将所有事件混合在一起?

Javascript Fullcalendar.io:如何在agendaWeek中每行显示一个事件,然后将所有事件混合在一起?,javascript,jquery,css,fullcalendar,Javascript,Jquery,Css,Fullcalendar,我使用Fullcalendar.io v2 在myagendaWeekmod中,我有一些事件,它们都显示在day square的一行上。所以,我拥有的事件越多,事件块就越薄 如何在每行中显示一个事件?就像在月份mod中一样。我参加的活动越多,我的日挡就越高(身高)。可能很难使用像eventRender这样的函数,因为如果您检查.fs event元素(web开发人员工具),您将看到事件块使用位置:绝对;顶部:300px;左:33%。。。所以我不知道该怎么办 我想要这样的东西: 您可以将类添加到事

我使用Fullcalendar.io v2

在my
agendaWeek
mod中,我有一些事件,它们都显示在day square的一行上。所以,我拥有的事件越多,事件块就越薄

如何在每行中显示一个事件?就像在
月份
mod中一样。我参加的活动越多,我的日挡就越高(身高)。可能很难使用像
eventRender
这样的函数,因为如果您检查
.fs event
元素(web开发人员工具),您将看到事件块使用
位置:绝对;顶部:300px;左:33%
。。。所以我不知道该怎么办

我想要这样的东西:

您可以将类添加到事件中,并尝试使用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'
},
如果这是你想要实现的,看看这个

另外,通过一些变通方法,您可以使用
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());
}

我也遇到了这个问题,这是非常困难的,因为插件以一种奇怪的方式组成日历,使用一些表,使用绝对位置动态定位事件,并改变css top属性

不过,我找到了一个通用的解决方案,效果非常好。首先,我将向您展示代码,并向他们解释代码的具体功能

我使用完整日历的选项。这是一个很好的例子

我用于管理时间,我假设fullCalendar html元素的id为“Calendar

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'));
  }
eventAfterAllRender:function(){
//定义静态值,使用此值更改事件项高度
var defaultItemHeight=25;
var defaultEventItemHeight=18;
// ...
//查找所有行并定义一个函数以选择具有特定时间的一行
var行=[];
$('div.fc-slats>table>tbody>tr[数据时间])。每个(函数(){
rows.push($(this));
});
var-rowIndex=0;
var getRowElement=函数(时间){
而(rowIndexdiv.fc-event-container')。每个(function(){//for each week列
var累加器=0;
var-previousRowElement=null;
$(this).find('>a.fc-time-grid-event.fc-v-event.fc event.fc start.fc end').each(函数(){//for week列上的每个事件
//选择当前事件时间及其行
var currentEventTime=矩($(this).find('>div.fc-content>div.fc-time').attr('data-full'),['h:mm A']);
var currentEventRowElement=getRowElement(currentEventTime);
//当前行必须包含多个项目
if(currentEventRowElement==previousRowElement){
累加器++;
//向下移动事件(使用边距顶部道具。它必须是该属性以避免与FullCalendar行为冲突)
$(this.css('margin-top','+='+(累加器*defaultItemHeight).toString()+'px');
//如果当前行超过其当前最大项,则增加当前行的高度
var maxItemsOnRow=currentEventRowElement.attr('data-max-items')|| 1;
如果(累加器>=maxItemsOnRow){
currentEventRowElement.attr('data-max-items',累加器+1);
currentEventRowElement.css('height','+='+defaultItemHeight.toString()+'px');
}
}否则{
//重置计数
rowIndex=0;
累加器=0;
}
//设置事件项的默认样式并更新previosRow
$(this.css('left','0');
$(this.css('right','7px');
$(this.css('height',defaultEventItemHeight.toString()+'px');
$(this.css('margin-right','0');
previousRowElement=currentEventRowElement;
});
});
//这用于重新绘制日历
$('日历').fullCalendar('选项','aspectRatio',$('日历').fullCalendar('选项','aspectRatio'));
}
代码的工作原理:

首先,我找到了日历行中的所有tr元素(请注意,它们包含一个带有时间的属性)

稍后,我对每一列进行迭代,并为每一列获取其事件项。每个事件项都是一个锚元素,具有一些内部子元素,日期作为属性data full

从事件中我可以看到它的行应该是什么,如果有多个项目,那么在该行中增加事件项目应该位于的位置。我使用margin top属性,因为插件没有使用或重新调整该属性(不要使用top属性)

在该行中,我设置了一个数据属性,以获取该行任何列的最大事件量。通过该属性,我可以计算该行是否必须增加其高度


好的,这就是代码的基本功能。如果你有什么问题,请回答。

我也面临同样的问题,虽然Alexander的回答很好,但我对它的性能有问题,因为它需要大量的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


好吧,这是不可能的。嗨!这几乎就是我需要的。我试着玩css代码,但没有结果。问题是如何在表中设置更高的
td
?正如你在小提琴中看到的,一次有两个事件从那里出来
td
区域,因为
td
具有固定的高度。因此,如何自动调整高度取决于有多少个事件是否有(在一个td中)?我也尝试调整行高,请检查我的编辑
.slot-attributes {
    left: 4px !important;
    right: 3px !important;
    height: 15px !important;
    margin-right: 0 !important;
}