Fullcalendar.io: how to display one event in a line on the agenda and then mix all in one?

I am using Fullcalendar.io v2

In my agendaWeek module, I have events, and they all appear on the same line in the square of the day. So, more events I have, and then more subtle blocks of events.

How can I show one event per line? Like in the month model. And I have more events, then a higher day block will be me (height). It may be difficult to use functions like eventRender , because if you check the .fs-event element (web developer tool), you will see that the event block uses position:absolute;top:300px;left:33% ... therefore I do not know what to do.

enter image description here

I want something like this: enter image description here

+5
source share
3 answers

You can add a class to your events and try customizing these events with CSS.

As an example, you can use the style

 .test { width: 100%; height: auto; position: relative !important; left: 0% !important; margin-right: 0% !important; } 

and an event like this:

 { title: 'Lunch', start: '2014-06-09T10:30:00', className: 'test' }, 

Look at Fiddle if this is what you want to achieve.

Also with a small workaround, you can use the eventAfterRender to adjust the height of a specific row. But this is not a very safe solution and requires some configuration:

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

https://jsfiddle.net/m5uupf9x/3/

+2
source

I am also stuck with this problem, it is very difficult, because the plugin presents the calendar in an odd way, using some tables and dynamically determining events with an absolute position and changing the css top property.

However, I found a general solution that works very well. First I will show you the code and they will explain what exactly the code does.

I use the eventAfterAllRender option of the full calendar. This is an example of work . enter image description here

I am using moment to control the time, and I am assuming that the identifier of the fullCalendar html element is 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')); } 

How the code works:

First I found all the tr elements that are the rows of my calendar (note that they contain an attribute with their time).

Later, I repeat for each column and get event elements for each column. Each event element is a binding element with some internal child element with a date as a filled attribute.

From the event I look at what its line should be, and in this line, if there is more than one element, then increase the position in which the event element should be. I use the margin-top property for this, because this property is not used or is not adjusted by the plugin (do not use the top property).

In the row, I set the data attribute to accept the maximum number of events that have any column in this row. In doing so, I can calculate whether the row should increase its height or not.

Well, that’s basically what codes do. If you have a question, please do so.

+2
source

I also ran into the same problem, and while Alexander's answer is wonderful, I had performance issues as he manipulated the DOM a lot. I have about 2000-3000 events per week and become unusable in browsers such as Firefox, IE, etc. Therefore, adaptation of Alexander's answer and minimization of manipulations with the DOM arose with the help of the following solution.

variables

 var itemsOnSlot = {}; // counter to save number of events in same time slot var maxItemsOnRow = {}; // counter to save max number of events in row 

use eventRender and eventAfterAllRender callbacks

 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 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 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 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 number of events in this time slot are greater than existing number maxItemsOnRow[time] = itemsOnSlot[start]; // replace current time 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 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 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; } 
0
source

All Articles