Fullcalendar js eventClick on dynamically added events - javascript

I have the following js:
!function ($) {
$(function(){
// fullcalendar
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var addDragEvent = function($this){
// create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
// it doesn't need to have a start or end
var eventObject = {
title: $.trim($this.text()), // use the element's text as the event title
className: $this.attr('class').replace('label','')
};
// 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, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
};
$('.calendar').each(function() {
$(this).fullCalendar({
header: {
left: 'prev,next',
center: 'title',
right: 'today,month,agendaWeek,agendaDay'
},
editable: true,
droppable: true, // this allows things to be dropped onto the calendar !!!
drop: function(date, allDay) { // this function is called when something is dropped
// 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;
copiedEventObject.allDay = allDay;
// render the event on the calendar
// the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
$('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
}
,
events: [
],
eventClick: function(event) {
alert('win');
}
});
});
getEvents();
});
}(window.jQuery);
function getEvents()
{
$.ajax({
type: 'POST',
url: '/Calendar/findEvents',
dataType: 'json',
data: {
request: 'ajax'
},
success: function (data)
{
if(data.length > 0)
{
for (index = 0; index < data.length; ++index)
{
var d = new Date(data[index]['end']);
if(data[index]['is_online'] === 1)
{
var myevent = {title: 'Forløb: '+data[index]['academy_name'].toUpperCase()+' \n Modul: '+data[index]['module_name']+ '\n Type: E-learning',start: new Date(d.getFullYear(), d.getMonth(), d.getDate())};
}
else
{
var myevent = {title: 'Forløb: '+data[index]['academy_name'].toUpperCase()+' \n Modul: '+data[index]['module_name']+ '\n Type: Kursus'+ '\n Lokation: '+data[index]['location']+'\n Underviser: '+data[index]['mentor'],start: new Date(d.getFullYear(), d.getMonth(), d.getDate())};
}
$('.calendar').fullCalendar( 'renderEvent', myevent, true);
}
}
}
});
}
As you can see when the calendar is loaded i am starting to load events (through ajax) into the calendar.
Now what i want to do is simply add an eventListner on each of the elements.
In the documentation it sates the following:
eventClick: function(event) {
if (event.url) {
window.open(event.url);
return false;
}
}
Which i attempted with just a simple alert (as you can see in the code:
eventClick: function(event) {
alert('win');
}
However when i click my items nothing happens.
Can anyone tell me what i am missing?

I know you are loading events through AJAX, but have you tried returning an array of objects (the events) to the events array in your instantiation of the calender? Right now you are passing an empty array, so the plugin is not assigning any elements as 'events', and thus isn't assigning any click handlers.
events: [ getEvents()
],
eventClick: function(event) {
alert('win');
}
});
And then inside your getEvents() function call, rather than render the events, you should just return the event objects.

The suggested way to load events with an ajax call + some manipulation on the data you receive is to use your function as an event source (link to the doc) :
$(this).fullCalendar({ ...
events: function(start, end, tz, callback) {
$.ajax({
type: 'POST',
url: '/Calendar/findEvents',
dataType: 'json',
data: {
request: 'ajax'
},
success: function (data) {
// build an array of event objects with the data
var events = ...
// use the "callback" argument to load them in the grid :
callback(events);
}
});
},
...
});
note : the signature of the function depends on the version of fullcalendar you are using. Versions prior to version 2.0 do not have the tz argument (again, check the doc).

FullCalendar is processing your listeners with no events. Your ajax is loaded after the initialization of your calendar. You could keep your current code and add the listener on eventRender.
$('#calendar').fullCalendar({
eventRender: function(event, element, view){
element.click(function(){
alert('test');
})
}
});
I would probably suggest loading the events as suggested in the other answers though, but this should work.

$('#calendar').fullCalendar({
eventRender: function(event, element, view){
element.click(function(){
alert('test');
});
$("#calendar .fc-helper-container").find("a").remove();
}
});

Related

how to change the parameter names "title", "start" and "end" in the fullcalendar jquery

In jquery's fullcalendar script I'd like to change the keywords "title" "start" and "end" by the column names that are in my database table.
the fullcalendar work when i change in the database table the name of the colums :
i changed "name" by "title" , "date_start" by "start and "date_end" by "end", ok it's work ,but I would like to do the opposite.
$(document).ready(function() {
var calendar = $('#calendar').fullCalendar({
editable: false,
events: "{{ route('products') }}",
displayEventTime: false,
eventRender: function(event, element, view) {
if (event.allDay === 'true') {
event.allDay = true;
} else {
event.allDay = false;
}
},
eventClick: function(event) {
$.getJSON("{{ route('products') }}", function(user) {
var convertToTableau = Array.from(Object.values(user));
console.log(convertToTableau);
var us = $.grep(convertToTableau, function(v) {
return v.id == event.id;
console.log(event.id);
});
$("#firstname").text(us[0].title);
$("#idpilote").text(" Id : " + us[0].id);
$("#firstname").text(" Name : " + us[0].title);
$("#metier").text(" Job : " + us[0].profession);
});
}
});
});
</script> ```
You can't change what fullCalendar expects as the default property names for the important fields in your events (well, you could, if you modified the fullCalendar source code, but you don't want to do that).
However, if for some reason you don't want to change your server/database code to match (but why not, exactly??) you can create a simple mapping between the two via the eventDataTransform callback in fullCalendar. This function runs once for every event which is loaded into fullCalendar, and allows you to update the properties of the event object before fullCalendar starts processing it. In here you can copy data from the server-generated property names to the ones which fullCalendar recognises.
Here's an example:
eventDataTransform: function(event) {
event.title = event.name;
event.start = event.date_start;
event.end = event.date_end;
return event;
}

eventRender callback renders all events, how to render only a single event

So I am simply adding an event (created a json for it with id, start, etc.)
I tried the following:
$('#calendar').fullCalendar('renderEvent', my_event);
$('#calendar').fullCalendar('updateEvent', my_event);
These make a callback as following:
eventRender: function(event, element) {
console.log('in event Render callback');
console.log(event);
}
eventRender renders all the events in the calendar when adding a single event. So I can see my added event on the calendar immediately, and the 2 console log statements are printed for all events including the new one.
How can I add only this new event (with a new id) on the calendar such that only this new event is rendered (eventRender callback for only new event) and not all the events?
I'm afraid it is not possible by default. You can try to do something like this:
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#button_id').click(function() {
var newEvent = {
title: 'NEW EVENT',
start: new Date(y, m, d),
render: true
};
$('#calendar').fullCalendar('renderEvent', newEvent, 'stick');
});
$('#calendar').fullCalendar({
editable: true,
eventRender: function(event, element) {
if (event.render) {
element.addClass('test');
}
event.render = false;
}
});
});
Code above will add "test" css class to the last added event only. Maybe this will help you somehow.
Fiddle

Full calendar Drop edit description with the external events from database

In the Full calendar external-dragging events i want to change the description by adding the id of the event inserted in the database with the description while copying the event.
droppable: true, // this allows things to be dropped onto the calendar !!!
drop: function(date, allDay){ // this function is called when something is dropped
// 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;
copiedEventObject.description = 'custom_event';
copiedEventObject.allDay = allDay;
copiedEventObject.className = $(this).attr("data-class");
var new_date = copiedEventObject.start.format();
var new_event = copiedEventObject.title;
$.post('calendar_action.php',{'action':'create_event','date':new_date,'event':new_event},function(data){
$(copiedEventObject).attr("description",data);
});
// render the event on the calendar the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
$('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
$(this).remove();
},
The $.post method in ajax is not passing the global variable so i used the $.ajax method and its working fine
$.ajax({
type: 'POST',
async: false,
url: "calendar_action.php",
data: {'action':'create_event','date':new_date,'event':new_event},
success: function(data) {
desc = data;
}
});
copiedEventObject.description = desc+'_custom_event';

fullcalendar add events dynamically

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

FullCalendar- Drop not triggered when changing month

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.

Categories