In FullCalendar v3, there has an option to catch after loading all events.
eventAfterAllRender
It seems removed in v4. As saying here:
https://fullcalendar.io/docs/v4/upgrading-from-v3
Here has a code snippet to prepare a demo calendar in v5.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='https://cdn.jsdelivr.net/npm/fullcalendar#5.5.1/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar#5.5.1/main.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
initialDate: '2020-09-12',
navLinks: true, // can click day/week names to navigate views
businessHours: true, // display business hours
editable: true,
selectable: true,
events: [
{
title: 'Business Lunch',
start: '2020-09-03T13:00:00',
constraint: 'businessHours'
},
{
title: 'Meeting',
start: '2020-09-13T11:00:00',
constraint: 'availableForMeeting', // defined below
color: '#257e4a'
},
{
title: 'Conference',
start: '2020-09-18',
end: '2020-09-20'
},
{
title: 'Party',
start: '2020-09-29T20:00:00'
},
// areas where "Meeting" must be dropped
{
groupId: 'availableForMeeting',
start: '2020-09-11T10:00:00',
end: '2020-09-11T16:00:00',
display: 'background'
},
{
groupId: 'availableForMeeting',
start: '2020-09-13T10:00:00',
end: '2020-09-13T16:00:00',
display: 'background'
},
// red areas where no events can be dropped
{
start: '2020-09-24',
end: '2020-09-28',
overlap: false,
display: 'background',
color: '#ff9f89'
},
{
start: '2020-09-06',
end: '2020-09-08',
overlap: false,
display: 'background',
color: '#ff9f89'
}
]
});
calendar.render();
});
</script>
<style>
body {
margin: 40px 10px;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 0 auto;
}
</style>
</head>
<body>
<div id='calendar'></div>
</body>
</html>
Codepen: https://codepen.io/wetruck/pen/poEXEve
Is there any option to perform an action after loading all events in v5?
I'm actually using a html loader. It's showing with the page load. But after loading all events, it should be removed.
For this situation where you have a loader you want to show and hide, please see the loading callback option for something which will do the job - you can use that callback to make a loader show/hide when the AJAX part of the task starts and stops.
e.g.
loading: function( isLoading ) {
if (isLoading == true) {
//show your loader
} else {
//hide your loader
}
}
Unlike the old eventAfterAllRender it starts and stops on the start/end of the AJAX request and doesn't cover the rendering of the events by fullCalendar, but that's normally very fast unless you have an absurd number of events being downloaded for a single time period.
Related
I am trying to make a fullcalendar component which can divide a day in equal parts.
This is working for certain amounts (10, 20, ...)
But when working with a uneven amount (like 15). This does not work.
I made a code pen of a simplified version of the problem:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
timeZone: 'UTC',
headerToolbar: {
left: 'today prev,next',
center: 'title',
right: 'resourceTimelineDay,resourceTimelineTenDay,resourceTimelineMonth,resourceTimelineYear'
},
initialView: 'resourceTimelineDay',
scrollTime: '08:00',
aspectRatio: 1.5,
views: {
resourceTimelineDay: {
duration: { days: 21 }, // Or whatever value you want.
slotDuration: "3:00:00",
slotLabelInterval: "21:00:00",
slotMaxTime: "24:00:00",
slotWidth: "8",
minTime: '00:00',
maxTime: "24:00:00",
},
resourceTimelineTenDay: {
type: 'resourceTimeline',
duration: { days: 10 },
buttonText: '10 days'
}
},
editable: true,
resourceAreaHeaderContent: 'Rooms',
resources: 'https://fullcalendar.io/demo-resources.json?with-nesting&with-colors',
events: 'https://fullcalendar.io/demo-events.json?single-day&for-resource-timeline'
});
calendar.render();
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link href="https://cdn.jsdelivr.net/npm/fullcalendar-scheduler#5.5.1/main.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar-scheduler#5.5.1/main.min.js"></script>
<div id='calendar'></div>
codepen
The problem with the uneven amounts we cannot reach exactly 24:00:00, this gives a problem in the visualation.
Does anyone know a solution to this problem?
###EDIT### extra info:
When running my code I get following results:
divided in 30 parts (which mean 48 minutes) (and 48 minutes * 30 = 24:00:00)
divided in 21 parts (which means 1 hour and 8 minutes) (1:08 * 21 = 23:48:00)
I tried using MaxTime to limit to 23:48:00, but this does not work as expected.
Thanks in advance
I am facing an issue while implementing fullcalendar. I used fullcalendar plugin for allowing the user to add task and events and with the respective option, all day, recurring every week, every day, every month and every year.
For the above-mentioned functionality, I referred two SO post
Recurring Events in Full Calendar (For repeating weekly)
Repeat full calendar events daily, monthly and yearly.
While creating an all-day event with recurring every week I am facing an issue which was addressed in Issue #4173 for which I have created a demo here
I also checked v4 and I found it will work for me a demo in v4 here, but I have some other concern here, I am working on a live website and there I can't revamp and opt to implement v4 it is a complex system need to look into all aspect before opting to revamp so is there any hack to implement the same in v3 is there anything which I can manually edit in the locally stored file or patch it for fixing this?
$(function() {
let defaultEvents = [{
id: 230,
title: 'all day with every week (range)',
start: '00:00:00',
end: '23:59:59',
dow: [2],
allDay: true,
ranges: [{
start: "2018-12-10",
end: "2018-12-26"
}]
}, ];
$('#calendar').fullCalendar({
defaultView: 'month',
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaWeek,agendaDay'
},
eventSources: [defaultEvents],
eventRender: function(event, element, view) {
if (event.ranges) {
console.log(event.ranges)
return (event.ranges.filter(function(range) {
return (event.start.isBefore(range.end) &&
event.end.isAfter(range.start));
}).length) > 0;
}
}
});
});
html,
body {
margin: 0;
padding: 0;
font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 900px;
margin: 40px auto;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.0/fullcalendar.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.0/fullcalendar.min.js"></script>
<div id='calendar'></div>
Thank you
This issue was highlighted twice in v3 with tickets #4173 and #4399 and now it is fixed in v4 using a separate plugin for recurrence RRule. In v4 you can replicate the following event like this
{
title: 'event with every week (all day)',
allDay: true,
rrule: {
freq: 'weekly',
dtstart: '2019-04-05',
until: '2021-04-05'
},
}
here is the fiddle
I need to be able to let users move some events around on my fullcalendar. And I want to go to server and fetch counterparties' busy times and display them as background events on the calendar when the dragging is going on. However, when I call .fullcalendar('renderEvents', [...]) while the dragging is happening, the dragging mechanism within fullcalendar breaks and stops.
Is there a way to either add events without breaking dragging or some other way highlight busy times that have to be retrieved with ajax call?
The example is here: https://jsbin.com/qikiganelu/1/edit?js,output. Try dragging 'Meeting with Bob'.
$(function() { // document ready
$('#calendar').fullCalendar({
header: {
left: '',
center: '',
right: ''
},
defaultView: 'agenda',
duration: {days: 2},
allDaySlot: false,
defaultDate: '2017-04-27',
minTime: '9:00',
maxTime: '17:00',
events: [
{
title: 'Keynote',
start: '2017-04-27T09:00',
end: '2017-04-27T11:00',
editable: false,
color: "gray",
},
{
title: 'Meeting with Bob',
start: '2017-04-27T12:30',
end: '2017-04-27T13:00',
editable: true,
},
],
eventDragStart: function(event, jsEvent, ui, view){
// fetch Bob's busy times and add them as background events
var busyTimes = [
{
start: '2017-04-27T14:00',
end: '2017-04-27T16:00',
rendering: 'background',
},
{
start: '2017-04-28T9:00',
end: '2017-04-28T12:00',
rendering: 'background',
}
];
$('#calendar').fullCalendar('renderEvents', busyTimes);
},
});
});
body {
margin: 40px 10px;
padding: 0;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
font-size: 14px;
}
#calendar {
max-width: 900px;
margin: 0 auto;
}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='https://fullcalendar.io/js/fullcalendar-3.4.0/fullcalendar.css' rel='stylesheet' />
<link href='https://fullcalendar.io/js/fullcalendar-3.4.0/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='//cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js'></script>
<script src='//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://fullcalendar.io/js/fullcalendar-3.4.0/fullcalendar.js'></script>
<!-- the code from the JavaScript tab will go here -->
<!-- the code from the CSS tab will go here -->
</head>
<body>
<div id='calendar'></div>
</body>
</html>
As a workaround, try preloading all the background events, but hiding them via CSS until the drag operation happens. For instance:
// hide all background events by default
.fc-bgevent {
display: none;
}
// redisplay once "show-background-events" class toggled on
.fc-bgevent.show-background-events {
display: block;
}
Show / hide the background events by toggling the .show-background-events class like so:
eventDragStart: function(event, jsEvent, ui, view){
$(".fc-bgevent").addClass("show-background-events");
},
eventDragStop: function(event, jsEvent, ui, view){
$(".fc-bgevent").removeClass("show-background-events");
}
Example at: https://jsbin.com/vuvacisibu/1/edit?css,js,output
My bad, I now see the problem. And your mistake is the place you put your $('#calendar').fullCalendar('renderEvents', busyTimes); and also the way you write the array, I also changed the ISO8601 time string a bit to be sure.
You can remove the seconds from the time string and write 2017-04-27T12:35Z instead of 2017-04-27T12:35:02Z for example
<script>
$(function() { // document ready
$('#calendar').fullCalendar({
header: {
left: '',
center: '',
right: ''
},
defaultView: 'agenda',
duration: {days: 2},
allDaySlot: false,
defaultDate: '2017-04-27',
minTime: '9:00',
maxTime: '17:00',
events: [
{
title: 'Keynote',
start: '2017-04-27T09:00',
end: '2017-04-27T10:00',
editable: false,
color: "gray",
},
{
title: 'Meeting with Bob',
start: '2017-04-27T10:35:02Z',
end: '2017-04-27T11:35:02Z',
editable: true,
},
],
eventDragStart: function(event, jsEvent, ui, view){
}
});
//this is the new place for the fetching and calling renderEvents
// fetch Bob's busy times and add them as background
var busyTimes = [
{title: 'Event One', start: '2017-04-27T12:35:02Z', end: '2017-04-27T13:35:02Z'},
{title: 'Event Two', start: '2017-04-27T14:35:02Z', end: '2017-04-27T15:35:02Z'}
];
$('#calendar').fullCalendar('renderEvents', busyTimes);
});
</script>
Issue
I am struggling to get my events to populate the Full Calendar on load. The events work fine when I change the month, but when the application first loads they don't seem to appear.
Code
Here is my code for for the UIConfig of the Calendar:
//THIS CALLS MY GET METHOD.
var holidaysnew = getUserEventsById.getUserEventsById();
$scope.uiConfig = {
calendar: {
viewRender: function (view, element) {
holidaysnew.forEach(function (hol) {
$scope.eventSources[0].events.push({
end: $filter('dateFilter')(hol.HOLIDAY_END),
start: $filter('dateFilter')(hol.HOLIDAY_START),
title: hol.HOLIDAY_TITLE,
color: $filter('colorEventFilter')(hol.HOLIDAY_EVENT_STATE_ID)
});
});
},
height: 850,
editable: true,
header: {
left: '',
center: '',
right: ''
},
}
};
Now the viewRender gets hit on load aswell as when I change the month. The weird thing is it only works when you click a new month.
#Ben problem is that you are making http call in service. But here calendar will not wait for http response. So calendar loads first then after you will receive http response that's why you are not getting response first time. You need to change the way to load events like below.
$scope.uiConfig = {
calendar: {
events: function(start, end, timezone, callback) {
$http({
method : "GET",
url : 'your_url_to_fatch_events',
data : {start: startDate, end: endDate, id: userId}
}).then(
function (olidaysnew) {
var events = [];
// or make your events
olidaysnew.forEach(function (hol) {
events.push({
end: $filter('dateFilter')(hol.HOLIDAY_END),
start: $filter('dateFilter')(hol.HOLIDAY_START),
title: hol.HOLIDAY_TITLE,
color: $filter('colorEventFilter')(hol.HOLIDAY_EVENT_STATE_ID)
});
)}
callback(events);
}
)
},
height: 850,
editable: true,
header: {
left: '',
center: '',
right: ''
},
}
}
I'm working with the Twitter search widget and currently I have the javascript embedded in the within the body tags of the HTML, something like this:
<body>
<script charset="utf-8" src="https://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({
version: 2,
type: 'faves',
rpp: 1,
interval: 7200000,
title: '',
subject: '',
width: 500,
height: 65,
theme: {
shell: {
background: '#a4c9b9',
color: '#ffffff'
},
tweets: {
background: '#a4c9b9',
color: '#ffffff',
links: '#444444'
}
},
features: {
scrollbar: true,
loop: false,
live: false,
behavior: 'all'
}
}).render().setUser('exampleuser').start();
</script>
</body>
Instead though, I'd rather move all that javascript to the header (or maybe the footer?) tag, then simply have it rendered in the body without the tags. Is there a simple way to do this?
You can use one of either native JS...
window.onload = function() {
// your code here
};
or jQuery...
$(document).ready(function() {
// your code here
});
...to ensure the code will not run until the document has finished loading.
This explains the slight difference between window.onload and $(document).ready().
Another option would be to wrap your code in a named function and call it in the body somewhere but you would still have to put it in <script> tags.
EDIT: Using window.onload...
<html>
<head>
<script>
window.onload = function() {
new TWTR.Widget({
version: 2,
type: 'faves',
rpp: 1,
interval: 7200000,
title: '',
subject: '',
width: 500,
height: 65,
theme: {
shell: {
background: '#a4c9b9',
color: '#ffffff'
},
tweets: {
background: '#a4c9b9',
color: '#ffffff',
links: '#444444'
}
},
features: {
scrollbar: true,
loop: false,
live: false,
behavior: 'all'
}
}).render().setUser('exampleuser').start();
};
</script>
</head>
<body></body></html>