add event to fullcalendar by dropping from external source - fullcalendar

I would like to add an event to the fullcalendar jquery plugin from an external source. I need the event title; start and end dates. I read that the drop callback function is called when you drop an external source on the calendar. This reports the start date in the alert. The eventReceive option shows the title of the event. This alert is displayed after the drop callback. This is the code:
$('#edit_calendar').fullCalendar({
...
droppable: true,
drop: function(date) {
alert("Dropped on " + date );
},
eventReceive: function (event) {
alert('event, ' + event.title + ', was added, (need date here)');
},
How do I get the start date value from the drop callback to the eventRecieve function?

You can get the start and end dates within the drop event. This is the code I added to the drop event:
drop: function (date, jsEvent, ui, resourceId) {
var memberName = $(this).data('event').title;
var memberID = $(this).attr('id').toString();
//Create Event - add to array
var newEvent = new Object();
newEvent = {
title: memberName,
id: memberID,
start: date.format(),
end: date.format(),
objectID: 0
};
eventsAdded.push(newEvent);
},

Related

FullCalendar - Get Background event on dayClick

I'm currently trying to get an event (type of background) when the DayClick is trigger.
I can't use the EventClick trigger because of the background type (I don't know why but nothing happen in my case, something wrong from FullCalendar ?).
This is my code for the init :
$('#calendarRoomUnavailable').fullCalendar({
height: 'auto',
header: {
left : '',
center: 'title',
right: ''
},
defaultView: 'year',
defaultDate: getDateFilterRoomAvailable(),
lang: 'fr',
firstDay: 1,
columnFormat: 'ddd D/M',
selectable : false,
weekends: false,
navLinks : false,
events: basePath + '/agenda/datalist/room_available',
viewRender: function (view, element) {
},
eventRender: function(event,element){
if(event.rendering === "background"){
element.data(event); //store the event data inside the element
}
},
dayClick: function (date, jsEvent, view) {
console.log(jsEvent)
},
editable:false,
});
Quick look
What I want:
When I click on a day, I want the get the event(background) related to the day (I've got only one event per day in my calendar).
Currently I'm working with the eventRender + dayClick :
eventRender: function(event,element){
if(event.rendering === "background"){
element.data(event); //store the event data inside the element
}
},
dayClick: function (date, jsEvent, view) {
console.log(jsEvent)
[...]
}
With the console.log JSEvent on the DayClick, I know it get me the wrong <td> :
Img
Because, when I try to get the target <td> with the class fc-bgevent, nothing happens :
dayClick: function (date, jsEvent, view) {
console.log(jsEvent)
if (jsEvent.target.classList.contains('fc-bgevent')) {
console.log($(jsEvent.target).data());
}
If I try to go to the HTML element target getted by the jsEvent, it shows me the wrong <td> and I can't do anything with that ...
HTML Debug
Does someone know how to bypass that ?
Thanks !
Code to get one event from a date :
function getEventFromDate(date) {
var allEvents = [];
allEvents = $('#calendarRoomUnavailable').fullCalendar('clientEvents');
var event = $.grep(allEvents, function (v) {
return +v.start === +date;
});
if (event.length > 0) {
return event[0];
} else {
return null;
}
}
After the #ADyson comments, my final function look like this :
function getEventFromDate(date) {
var eventToReturn = null;
$('#calendarRoomUnavailable').fullCalendar('clientEvents', function(event) {
var event_start = formatDateYmd(new Date(date),'-');
var date_formated = formatDateYmd(new Date(event.start),'-');
if(event_start === date_formated) {
eventToReturn = event;
}
});
return eventToReturn;
}
with a small function to get a formated date without library like Moment.js or Date.js:
function formatDateYmd(value,$delimiter)
{
var year = value.getFullYear();
var month = (value.getMonth()+1) < 10 ? '0'+(value.getMonth()+1) : (value.getMonth()+1);
var day = value.getDate() < 10 ? '0'+value.getDate() : value.getDate();
return year + $delimiter +
month + $delimiter +
day;
}
I hope to find something more performant, but this one divide the execution time by two.
Keep an eye on it
Thanks again.

apply functions for contextMenu on each event in FullCalendar.js

I'm working with Fullcalendar.js and I set for each event a Simple Contextmenu that makes a specified function (change status when confirming a medical appointment). Next code sample works fine only when i have an Event in a day (eventRender):
eventRender: function(event, element) {
var originalClass = element[0].className;
element[0].className = originalClass + ' hasmenu';
$('#calendar2').contextmenu({
delegate: '.hasmenu',
menu: [{
title: 'Cambiar Estado',
cmd: 'cestado',
action: function(ui){ui.cmd = "cestado";confirmarCambioEstado(event);}
}, {
title: 'Atender Cita',
cmd: 'acita',
action: function(ui){ui.cmd = "acita";if(event.color=="#0088cc"){
actualizarEstado(3,event.id);
event.color = "yellowgreen";
calendarJ.fullCalendar('rerenderEvents');
hrefHCE.href = "HCE?idCita="+event.id;
hrefHCE.click();
}else{
advertenciaEstado();
}}
},{
title: 'Cancelar Cita',
cmd: 'ccita',
action: function(ui){ui.cmd = "ccita";event.color = "green";
confirmarCambioEstado(event);}
}, {
title: 'Eliminar Cita',
cmd: 'ecita',
action: function(ui){ui.cmd = "ecita";confirmarEliminar(event);}
}],
beforeOpen: function (event,ui) {
ui.menu.zIndex($(event.target).zIndex() + 1);
}
});
},
eventDrop: function(event, delta, revertFunc){
confirmarCambioFecha(event,revertFunc);
},
eventAfterAllRender: cambiarFuncion
});
But,only works like i want for a day. When i have two or more eventes on a same day, when in apply the functions in the contextMenu, it only makes the function with the last event of the day (if i have 3 events, the functions apply for the last event, not for the specified event i want to apply the functions)
How do i apply the same tratment for each event witouth having that issue i'm showing? i've tried to put a forEach sentence, but i don't know what i do

Order Events in Fullcalendar by Start date and End Date

How can I order events in fullCalendar first by start date?
Example:
An event which starts first will show on top and then one which starts later will be later
If two events have same the start date then, order them by end date
i.e
an event which ends earlier will be shown first, followed by an event which ends later.
Calendar Display
Events Order
var args = jQuery.parseJSON(emCalendarArgs);
var Jobj = args.events;
// Setup FullCalendar
(function() {
//var language = jQuery('#pg_lang').val();
//alert(language+ 'dsfsd');
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var language = langg;
var mn_text, week_text, day_text, list_text;
//alert(mn_text);
var args = jQuery.parseJSON(emCalendarArgs);
var Jobj = args.events;
console.log(Jobj);
jQuery('#events-full-calendar').fullCalendar({
allDaySlot: false,
editable: true,
lang: 'he',
handleWindowResize: true,
eventOrder: 'start,end',
header: {
left: 'today prev,next',
center: 'title',
right: 'month,basicWeek,basicDay'
},
buttonText: {
month: mn_text,
week: week_text,
day: day_text
},
eventLimit: {
'month': 3, // adjust to 4 only for months
'default': false // display all events for other views
},
axisFormat: 'HH:mm',
timeFormat: {
agenda: 'H:mm{ - h:mm}'
},
slotEventOverlap: false,
events: Jobj,
timeFormat: 'H:mm',
});
}());
I found a Solution to it. For any one else looking for the solution to this, I changed a function in fullcalendar.js:
compareSegs: function(seg1, seg2) { return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1) compareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs); }
to :
compareSegs: function(seg1, seg2) {
if(this.view.name=="basicWeek" || this.view.name=="month" || this.view.name=="basicDay"){ // ordering events by color in ListView
return seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
compareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);
}
else{
return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first
seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first
seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
compareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);
}
}
and used below code in fullcalendar function
eventOrder: 'start, end'
in my fullcalendar call

prevent an external event to be dropped on full calendar if earlier than today's date

I am using the fullcalendar jquery plugin to create a schedule of events. I want to prevent the user from dropping an external event on the calendar if it is earlier than current date.
This is my current code:
$('#edit_calendar').fullCalendar({
header:
{
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
titleFormat: { month: 'MMMM' },
defaultView: 'month',
droppable: true,
drop: function (date, jsEvent, ui, resourceId) {
//compare today's date with drop date - if in the past, don't allow
var today = moment().startOf('day');
var dropDate = moment(date).startOf('day');
if (dropDate < today)
{
//The alert is shown
alert("An event in the past cannot be added, updated, or deleted.");
return false;
}
else
{
var memberName = $(this).data('event').title;
var memberID = $(this).attr('id').toString();
//Create Event - add to array
var newEvent = new Object();
newEvent = {
title: memberName,
id: memberID,
start: date.format(),
end: date.format(),
objectID: 0
};
eventsAdded.push(newEvent);
}
},
...rest of code
If the event is dropped before the current day display the alert and do not create the event. If shown after the current day, create the event.
In the code above, the alert is shown, but the event is still created. If the event is dropped after the current day, the event is created.
I thought by adding return false after the alert is displayed it will prevent the event from being created. However, the alert is shown AND the event is created.
Do I have to remove the event or is there a way to prevent the event from being created?
I was able to restrict events when they are added or changed using the selectConstraint and eventConstraint respectively. However, I would like to add an alert when the user tries to update or add an event outside the start and end dates so they know why it is not working.
This is what I have:
$('#edit_calendar').fullCalendar({
header:
{
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
titleFormat: { month: 'MMMM' },
defaultView: 'month',
droppable: true,
drop: function (date, jsEvent, ui, resourceId) {
var memberName = $(this).data('event').title;
var memberID = $(this).attr('id').toString();
//Create Event - add to array
var newEvent = new Object();
newEvent = {
title: memberName,
id: memberID,
start: date.format(),
end: date.format(),
objectID: 0
};
eventsAdded.push(newEvent);
},
editable: true,
//The following constraints prevents the user from adding/updating/deleting events that are before the current date
//The end date is required. So, you can't add events over a year away from the current date
eventConstraint: {
start: moment().startOf('day'),
end: moment(moment().startOf('day'), 'MM-DD-YYY').add('days', 365)
},
selectConstraint: {
start: moment().startOf('day'),
end: moment(moment().startOf('day'), 'MM-DD-YYY').add('days', 365)
},
...rest of code...
Is there any way I can add an alert when the user tries to add or update an event ou
From the documentation:
eventDrop does not get called when an external event lands on the calendar. eventReceive is called instead
Having said that, in order to prevent the drop you need to go more back in the chain. You need to use "dropAccept". You can read about it in the documentation.
You can use 'removeEvents' to remove added event.
https://fullcalendar.io/docs1/event_data/removeEvents/
drop: function(date, jsEvent, ui, resourceId) {
var add = true;
... // Here decide whether to add or not
if(add){
;
}
else{
//use 'removeEvents' to remove added event
}
}

drag and drop images to event in fullcalendar

I really hope to get some help with this. I'm doing a calendar for kids using fullcalendar. It should be possible to drag and drop som image icon into the events of the calendar. It looks someting like this: http://boerne.migraeniker.dk/kalender_filer/default.html
But how can I display the image that I drop inside the event.
The code that should drop the image is here:
drop:function(start,end, allDay) {
var originalEventObject = $(this).data('event');
var copiedEventObject = $.extend({}, originalEventObject);
if (copiedEventObject.title) {
start = $.fullCalendar.formatDate(start, "yyyy-MM-dd HH:mm:ss");
$.ajax({
url: 'http://boerne.migraeniker.dk/kalender_filer/add_events.php',
data: 'title='+copiedEventObject.title+'&start='+ start +'&end='+ end,
type: "POST",
success: function(json) {
}
});
calendar.fullCalendar('renderEvent',
{
title: copiedEventObject.title,
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
}
calendar.fullCalendar('unselect');
},
I really hope this makes sense otherwise I can post more of the code.
Take a look at External dragging demo
You need to declare droppable and drop in $('#mycalendar')
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();
}
}
JSFiddle

Resources