I am using the FullCalendar plugin for my calendar.
I am trying to loop through some ajax data I have acquired and populate my calendar with the relevant fields I want to use.
This is what i'm doing:
for (var i = 0; i < $requests.length; i++)
{
var currEvent = {
title: $requests[i].staff_name,
start: new Date($requests[i].start_date),
end: new Date($requests[i].end_date),
backgroundColor: $requests[i].color,
borderColor: $requests[i].color,
textColor: "white",
}
$module.fullCalendar(
'renderEvent',
currEvent,
true
);
}
This will populate my calendar but i've been trying to add the eventClick callback so i can alert out the event's title or something. But everything I do results in either not outputting to the calendar or outputting with the click function doing nothing. How can I render my events and then assign a click function to each one?
This code will do it, I was also accidentally calling the plugin twice which screwed it up completely.
$module.fullCalendar({
weekends: false,
eventLimit: 3,
editable: false,
disableResizing: false,
events: allEvents,
eventClick: function(event, element) {
alert(event.title);
}
});
Related
I would like to add and render event by selection of dates range. select() is correctly fired, but there is error calendar.fullCalendar is not a function on the last line. I googled a lot but did not find any working solution.
I use FullCalendar v4 in timeline-view.
var calendar = null;
document.addEventListener('DOMContentLoaded', function() {
calendar = new FullCalendar.Calendar(document.getElementById('preview'), {
editable: true,
eventResizableFromStart: true,
eventResourceEditable: true,
selectable: true,
...
select: function(selectionInfo) {
var event = new Object();
event.title = 'title';
event.start = selectionInfo.start;
event.end = selectionInfo.end;
event.resourceId = selectionInfo.resource.id;
calendar.fullCalendar('renderEvent', event); // console says 'calendar.fullCalendar is not a function'
//$('#preview').fullCalendar('renderEvent', event); // I also tried this, but the same error as above
}
});
});
calendar.fullCalendar('renderEvent', event);
...I guess you copied this from somewhere? Because this is fullCalendar version 3 syntax. for version 4 you would write
calendar.addEvent(event);
See https://fullcalendar.io/docs/Calendar-addEvent for documentation. Always check that the examples you find apply to the correct version of the software.
I've been working with FullCalendar lately for a reservation system.
The problem is that whenever I select a time range it all adds to the eventData object. What I am trying to do is select one time range only.
When I click the $('#btn-reserve') button it should render the event on the calendar.
What's happening is that even my previous selections are getting rendered on the calendar. I only want to render the last selection I made.
here is my code
$('.calendar').fullCalendar({
selectable: true,
select: function(start, end) {
$('#end_time').val(end);
$('#start_time').val(start);
$('#newScheduleModal').modal({
show : true,
backdrop: 'static',
keyboard: false
});
$('#btn-reserve').click(function(){
eventData = {
title: 'Lesson Schedule',
start: start,
end: end
};
$('.calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
$('#newScheduleModal').modal('hide');
});
$('#btn-cancel-reserve').click(function(){
$('.calendar').fullCalendar('unselect');
eventData = {};
})
},
})
You are adding a new click event every time the calendar is selected. You need to unbind the click before adding it like so:
$('#btn-reserve').off('click').click(function
You might want to do the same for your "#btn-cancel-reserve" element.
I'm trying to create events in my full calendar dynamically.
I have:
$('#calendar').fullCalendar({
viewRender: function (view) {
var h;
if (view.name == "month") {
h = NaN;
}
else {
h = 2500; // high enough to avoid scrollbars
}
$('#calendar').fullCalendar('option', 'contentHeight', h);
},
lang: 'fr',
events: [
{
title: '8 présents',
start: data[0]
},
{
title: '8 excusés',
start: data[1]
},
{
title: '8 excusés',
start: '2015-01-08'
},
{
title: '8 présents',
start: '2015-01-08'
},
],
dayClick: function (date, jsEvent, view) {
window.location.replace(Routing.generate('dateChoisie', {date: date.format()}));
}
})
I have a var data, which is an array that contains all the dates of the events. I want to insert this in the events in the same way I inserted data[0], data[1], etc, but dynamically for all the dates.
I have tried to do a for:
events: [
for (var i = 0, max = data.Lenght; i < max; i++) {
{
title: '8 présents',
start: data[i]
},
}
{
title: '8 excusés',
start: data[1]
},
{
title: '8 excusés',
start: '2015-01-08'
},
{
title: '8 présents',
start: '2015-01-08'
},
],
But it doesn't work inside the list.
Anybody know how I can do this?
after rendering the full calendar you can add events dynamically.
var event={id:1 , title: 'New event', start: new Date()};
$('#calendar').fullCalendar( 'renderEvent', event, true);
I was searching for a while and I have found an possibility.
It was very easy at the end...
I let this here, maybe anybody is interested in.
for (var i in data)
var monthSource = new Object();
monthSource.title = data[i]+' présents';
monthSource.start = i; // this should be date object
monthSource.end = new Date(y, m, d); //to now
month[a] = monthSource;
a++;
}
$('#calendar').fullCalendar({
viewRender: function (view) {
$('#calendar').fullCalendar( 'removeEvents');
$('#calendar').fullCalendar('addEventSource', month);
}
Source: http://fullcalendar.io/docs/event_data/addEventSource/
You can dynamically add an event source. An Event Source is an url which can for example return json data.
Maybe it might be sufficient for you to fire the refetch event after you changed the event data.
.fullCalendar( 'refetchEvents' )
Source: http://fullcalendar.io/docs/event_data/refetchEvents/
(The accepted solution will lose the event if you do anything complicated; the event added is ephemeral and will spontaneously disappear if you blink too hard. This solution is robust and will work if you do more complicated things.)
Support for persistent events is a bit inelegant. You may have to dump, reload, AND render the entire calendar state...:
var CAL, EVENTS;
$(document).ready(function() {
// set up calendar with an EventSource (in this case an array)
EVENTS = [...];
$('#calendar').fullCalendar({...});
// calendar object
CAL = $('#calendar').fullCalendar('getCalendar');
// extend object (could be its own function, etc.)
CAL.refresh = function() {
CAL.removeEvents();
CAL.addEventSource(EVENTS);
}
// finish setting up calendar
CAL.refresh();
});
Demo:
EVENTS.pop(); // remove last event
refresh(); // refresh calendar; last event no longer there
see https://stackoverflow.com/a/18498338
How about doing as it says on the website example:
https://fullcalendar.io/docs/renderEvent-demo
So add the event, and then use whatever you want to add that to the backend.
Or you can add the event to backend, then return the database's new id and then add it to the timeline, so you'll have the ids right.
Or update the id with return message, whatever rocks your boat.
although it is not specified on the fullcalender site, it is necessary to assign a value to the "allday" parameter to be able to add new events dynamically. If you set this value to "false", it will not add the event to the AllDay row. If you do "true" it will add to the AllDay row.
var event = {
title: 'New Event',
start: Date(Date.now()),
backgroundColor: App.getLayoutColorCode('purple'),
allDay: false
}
jQuery('#calendar').fullCalendar('renderEvent',event,true);
or
var originalEventObject = jQuery(this).data('eventObject');
var copiedEventObject = jQuery.extend({}, originalEventObject);
copiedEventObject.title = "New Event";
copiedEventObject.start = date;
copiedEventObject.className = jQuery(this).attr("data-class");
copiedEventObject.backgroundColor = App.getLayoutColorCode('purple');
copiedEventObject.allDay = false;
jQuery('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
Simple examples of adding events can be found in the example-projects repo. There's currently examples for angular, vue, react, and bootstrap.
Wanted to mention this for anyone not using jquery who stumbles upon this
I'm having trouble getting custom controls to work when clicking the 'today' button that is part of Fullcalendar.
All the documentation I can find tells me that Fullcalendar's built-in controls can be affected using two methods:
So, this one works for me when it's applied to previous, next, month, agendaWeek and agendaDay, but not for 'today' (button.fc-today-button):
$('body').on('click', 'button.fc-next-button', function() {
console.log('I Clicked Next');
});
Some documentation also say that this works, although I can't make it do so on any button:
$('.fc-next-button span').click(function(){
console.log('I Clicked Next');
});
Does anyone know why this is and what I'm doing wrong?
Well, you want to affect the "today" button, yet you are adding code for the "next" button. You want to do something like:
$(".fc-today-button").click(function() {
alert('Clicked Today!');
});
This applies a click event to anything with the class "fc-today-button" (that is the class that the Today button will have).
Working example:
$('#fullCal').fullCalendar({
events: [{
title: 'Event 1',
start: moment().add(1, 'h'),
end: moment().add(2, 'h'),
allDay: false
}],
header: {
left: '',
center: 'prev title next today',
right: ''
},
timezone:'local',
defaultDate: '2014-11-15',
editable: false,
eventLimit: false,
firstDay: 6,
defaultView: 'agendaWeek',
});
$(".fc-today-button").click(function() {
alert('Clicked Today!');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.1.1/fullcalendar.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.1.1/fullcalendar.min.js"></script>
<div id="fullCal"></div>
After investigation and the help of MikeSmithDev (thanks Mike - your help was invaluable), it appears as though the 'today' event only gets triggered if it physically positioned below/after the calendar, the rest of the header controls (button.fc-next-button etc) don't seem to mind where they are physically positioned.
Likely the first function executes before the calendar is finished loading... so it works, there is just no button to bind it to.
I was able to more or less achieve this with a native workaround of sorts. You may utilize the "customButtons" and "headerToolbar" in combination to effectively remove the original today button and replace it with your own which can trigger custom function code upon being clicked.
I'm actually using this with VueJS, but should be equally feasible with Vanilla JS.
// these are the options you can pass when initializing a fullcalendar
customButtons: {
focusButton: {
text: "focus",
click: this.scrollToCurrentDay // this is a vue component function, but you could just as well pass a vanilla JS function
}
},
headerToolbar: { // this effectively removes the original today button and adds our custom button to the header of the calendar
left: '',
center: 'title',
right: 'prev focusButton next'
}
I wanted to do this because I wanted to not only focus the month when today was clicked, but also to scroll the calendar to the day (useful when using small screens like phones).
My custom today button click handler:
scrollToCurrentDay: function(arg) {
let CalendarAPI = this.$refs.calendar.getApi();
CalendarAPI.today();
var todayElement = document.getElementsByClassName('fc-day-today')[0];
var calendarElement = document.getElementsByClassName('fc')[0];
if (todayElement) {
todayElement.scrollIntoView();
} else {
calendarElement.scrollIntoView();
}
},
I can't believe nobody asked this. This is driving me insane. Im using FullCalendar to let the user drop external events to the calendar. I´m folliwing the well known approach:
$('#external-events div.external-event').each(function () {
var eventObject = {
type: 2,
id: $(this).attr("data-id"),
title: $(this).attr("data-name"),
duration: $(this).attr("data-duration"),
guid: $(this).attr("data-guid"),
color: $(this).attr("data-color")
};
// store the Event Object in the DOM element so we can get to it later
$(this).data('eventObject', eventObject);
// make the event draggable using jQuery UI
$(this).draggable({ zIndex: 999, revert: true, revertDuration: 0 });
});
My calendar is configured like this (drop event):
drop: function(date) {
// retrieve the dropped element's stored Event Object
var originalEventObject = $(this).data('eventObject');
// we need to copy it, so that multiple events don't have a reference to the same object
var copiedEventObject = $.extend({}, originalEventObject);
// assign it the date that was reported
copiedEventObject.start = date.format();
// render the event on the calendar
//$('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
$.ajax({
async: false,
url: '#Url.Action("AddWorkoutToPlan", "Planning")',
data: { 'planId': planId, 'workoutId': copiedEventObject.id, 'date': date.format() },
success: function(data) {
$('#calendar').fullCalendar('refetchEvents');
}
});
},
As you can see, I don't render the event, I just make an ajax call and on success I refetch the events so I can get the DB id, in case the user wants to remove it.
This is how I get my events:
events: {
url: '#Url.Action("GetPlannedActivities", "Planning")',
data: function() { return { planId: '#Model.Id' } },
beforeSend: function(xhr, opts) {
if (!$("#selectedPlan").val()) {
xhr.abort();
unblockContainer($("#calendar"));
}
},
success: function(data) {}
},
This is working nice, but if the user moves from the current month, then the external events wont drag nor the drop callback is triggered... I don't know what is going wrong...
Any ideas?
Finally I rolled back the FullCalendar version from 2.1.0_BETA1 / BETA2 to v2.0.2 and now is working as expected.
So I guess this is a bug in the new version that uses DIVS instead of TABLES.