Fullcalendar: Unable to resize repeating events that use ranges[] - javascript

I am currently creating a calendar that will display repeating classes for a student for a university project. I am able to display the repeating events on the calendar, but whenever I attempt to resize or drag and drop an event I am getting the following errors in the browser web console:
TypeError: this.eventInstances[0] is undefined [Learn More] fullcalendar.min.js:6:26715
TypeError: t is undefined [Learn More] fullcalendar.min.js:8:6813
This is the JSON being passed into the calendar:
[{"id":22,"title":"Class: CSC3047\n Location: DKB","start":"12:00","end":"14:00",
"allDay":false,"description":"Mr Jack Dell","dow":[1],"ranges":[{"start":"2018-03-12",
"end":"2018-10-15"}]},{"id":23,"title":"Class: CSC3056\n Location: Ashby","start":"09:00",
"end":"11:00","allDay":false,"description":"Narelle Allen","dow":[3],
"ranges":[{"start":"2018-03-12","end":"2018-10-15"}]}]
This is the javascript I am using to display/edit/update the calendar events:
var currentUpdateEvent;
var addStartDate;
var addEndDate;
var globalAllDay;
function updateEvent(event, element) {
//alert(event.description);
if ($(this).data("qtip")) $(this).qtip("destroy");
currentUpdateEvent = event;
$('#updatedialog').dialog('open');
$("#eventName").val(event.title);
$("#eventDesc").val(event.description);
$("#eventId").val(event.id);
$("#eventStart").text("" + event.start.toLocaleString());
if (event.end === null) {
$("#eventEnd").text("");
}
else {
$("#eventEnd").text("" + event.end.toLocaleString());
}
}
function updateSuccess(updateResult) {
//alert(updateResult);
}
function deleteSuccess(deleteResult) {
//alert(deleteResult);
}
function addSuccess(addResult) {
// if addresult is -1, means event was not added
// alert("added key: " + addResult);
if (addResult != -1) {
$('#calendar').fullCalendar('renderEvent',
{
title: $("#addEventName").val(),
start: addStartDate,
end: addEndDate,
id: addResult,
description: $("#addEventDesc").val(),
allDay: globalAllDay
},
true // make the event "stick"
);
$('#calendar').fullCalendar('unselect');
}
}
function UpdateTimeSuccess(updateResult) {
//alert(updateResult);
}
function selectDate(start, end, allDay) {
$('#addDialog').dialog('open');
$("#addEventStartDate").text("" + start.toLocaleString());
$("#addEventEndDate").text("" + end.toLocaleString());
addStartDate = start;
addEndDate = end;
globalAllDay = allDay;
//alert(allDay);
}
function updateEventOnDropResize(event, allDay) {
//alert("allday: " + allDay);
var eventToUpdate = {
id: event.id,
start: event.start
};
if (allDay) {
eventToUpdate.start.setHours(0, 0, 0);
}
if (event.end === null) {
eventToUpdate.end = eventToUpdate.start;
}
else {
eventToUpdate.end = event.end;
if (allDay) {
eventToUpdate.end.setHours(0, 0, 0);
}
}
eventToUpdate.start = eventToUpdate.start.format("DD-MM-YYYY hh:mm A");
eventToUpdate.end = eventToUpdate.end.format("DD-MM-YYYY hh:mm A");
PageMethods.UpdateEventTime(eventToUpdate, UpdateTimeSuccess);
$('#calendar').fullCalendar('refetchEvents');
}
function eventDropped(event, dayDelta, minuteDelta, revertFunc) {
updateEventOnDropResize(event);
}
function eventResized(event, dayDelta, minuteDelta, revertFuncc) {
updateEventOnDropResize(event);
}
function checkForSpecialChars(stringToCheck) {
var pattern = /[^A-Za-z0-9 ]/;
return pattern.test(stringToCheck);
}
$(document).ready(function () {
// update Dialog
$('#updatedialog').dialog({
autoOpen: false,
modal: true,
width: 470,
buttons: {
"update": function () {
//alert(currentUpdateEvent.title);
var eventToUpdate = {
id: currentUpdateEvent.id,
title: $("#eventName").val(),
description: $("#eventDesc").val()
};
if (checkForSpecialChars(eventToUpdate.title) || checkForSpecialChars(eventToUpdate.description)) {
alert("please enter characters: A to Z, a to z, 0 to 9, spaces");
}
else {
PageMethods.UpdateEvent(eventToUpdate, updateSuccess);
$(this).dialog("close");
currentUpdateEvent.title = $("#eventName").val();
currentUpdateEvent.description = $("#eventDesc").val();
$('#calendar').fullCalendar('updateEvent', currentUpdateEvent);
}
},
"delete": function () {
if (confirm("do you really want to delete this event?")) {
PageMethods.deleteEvent($("#eventId").val(), deleteSuccess);
$(this).dialog("close");
$('#calendar').fullCalendar('removeEvents', $("#eventId").val());
}
}
}
});
//add dialog
$('#addDialog').dialog({
autoOpen: false,
width: 470,
buttons: {
"Add": function () {
//alert("sent:" + addStartDate.format("dd-MM-yyyy hh:mm:ss tt") + "==" + addStartDate.toLocaleString());
var eventToAdd = {
title: $("#addEventName").val(),
description: $("#addEventDesc").val(),
start: addStartDate.format("DD-MM-YYYY hh:mm A"),
end: addEndDate.format("DD-MM-YYYY hh:mm A")
};
if (checkForSpecialChars(eventToAdd.title) || checkForSpecialChars(eventToAdd.description)) {
alert("please enter characters: A to Z, a to z, 0 to 9, spaces");
}
else {
//alert("sending " + eventToAdd.title);
PageMethods.addEvent(eventToAdd, addSuccess);
$(this).dialog("close");
}
}
}
});
// page is now ready, initialize the calendar...
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
// put your options and callbacks here
header:
{
left: 'title',
center: '',
right: 'month,agendaDay,agendaWeek, prev,next'
},
height: 490,
//contentHeight: auto,
titleFormat: 'MMMM D YYYY',
columnFormat: 'ddd D/M',
defaultView: 'agendaWeek',
handleWindowResize: true,
allDaySlot: true,
minTime: '09:00:00',
maxTime: '18:00:00',
slotLabelFormat: 'h(:mm)a',
slotLabelInterval: '01:00:00',
firstDay: 1,
weekends: false,
hiddenDays: [6, 7],
eventClick: updateEvent,
selectable: true,
selectHelper: true,
select: selectDate,
editable: true,
eventDrop: eventDropped,
eventResize: eventResized,
events: {
url: 'JsonResponse.ashx',
color: 'blue',
error: function () {
alert('Error while Getting events!');
}
},
eventRender: function (event, element) {
//alert(event.title);
element.qtip({
content: event.description,
position: { corner: { tooltip: 'bottomLeft', target: 'topRight' } },
style: {
border: {
width: 1,
radius: 3,
color: '#0000ff'
},
padding: 10,
textAlign: 'center',
tip: true, // Give it a speech bubble tip with automatic corner detection
name: 'cream' // Style it according to the preset 'cream' style
}
});
return (event.ranges.filter(function (range) { // test event against all the ranges
return (event.start.isBefore(range.end) &&
event.end.isAfter(range.start));
}).length) > 0;
}
});
});
I may be wrong, but I have a feeling that the issue is that qtip is not able to tell which event is in focus due to the ranges value being passed in. Another thing to note is that if I attempt to resize the event twice it will update the database with the new values but will not actually resize the event on the calendar and the event will not update on the calendar until I refresh the page.
Stack trace from browser:
TypeError: this.eventInstances[0] is undefined
[Learn More]
fullcalendar.min.js:6:26715
s</t.prototype.getEventDef
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:26715
d</t.prototype.isEventInstanceGroupAllowed
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:9:10438
l</e.prototype.isEventInstanceGroupAllowed
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:7:13696
hitOver
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:10:24171
a</t.prototype.trigger
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:15714
l</e.prototype.handleHitOver
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:28967
l</e.prototype.handleDragStart
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:28573
a</t.prototype.startDrag
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:14363
a</t.prototype.handleDistanceSurpassed
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:15289
a</t.prototype.handleMove
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:14610
a</t.prototype.handleMouseMove
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:15474
d
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:2:3854
e
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:16679
dispatch
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:12392
add/r.handle
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:9156
trigger
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:11571
triggerHandler
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:19064
s</e.prototype.trigger
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:16925
u</t.prototype.handleMouseMove
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:20528
d
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:2:3854
dispatch
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:12392
add/r.handle
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:9156
TypeError: t is undefined
[Learn More]
fullcalendar.min.js:8:6813
o</t.prototype.buildNewDateProfile
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:6813
l</t.prototype.mutateSingle
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:7:6026
f</t.prototype.mutateEventsWithId/<
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:11:28483
forEach self-hosted:271:13 f</t.prototype.mutateEventsWithId
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:11:28434
p</e.prototype.reportEventResize
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:7:22052
interactionEnd
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:10:24614
a</t.prototype.trigger
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:15714
a</t.prototype.handleInteractionEnd
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:13682
l</e.prototype.handleInteractionEnd
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:29260
a</t.prototype.endInteraction
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:8:13574
d
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:2:3854
e
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:16679
dispatch
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:12392
add/r.handle
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:9156
trigger
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:11571
triggerHandler
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:19064
s</e.prototype.trigger
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:16925
u</t.prototype.handleMouseUp
http://kmartin41.public.cs.qub.ac.uk/QSIS/js/fullcalendar.min.js:6:20621
d
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:2:3854
dispatch
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:12392
add/r.handle
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js:3:9156
I have based my repeating events off the following answer: https://stackoverflow.com/a/29393128/5659955
Thanks in advance!

As mentioned in my comment there was a bug raised against fullcalendar for resizing events that only have a time for their start and end. github.com/fullcalendar/fullcalendar/issues/3824
To get around this I have taken the calendar start and end range and created a list of all the dates in-between. I then loop over the list and check if the date is a monday(1) and if it matches the dow value in the db (1). I then assign the date to that event and add it to a class object and make a list of the class objects.
Essentially each event has an individual date assigned with the same start and end time. Any time and event is resized it will update the base event in the database and therefore all events are updated.
My solution is in C#.
Table structure:
id event_id startTime endTime startDate endDate dow
2 22 12PM 01PM 3/12/2018 12:00:00 AM 10/15/2018 12:00:00 AM 1
while (reader.Read())
{
int dow;
DateTime startTime;
DateTime endTime;
DateTime newstartdate;
DateTime newenddate;
var datelist = new List<DateTime>();
DateTime tmpdate;
for (int i = 0; i < end.Subtract(start).Days; i++)
{
tmpdate = start.AddDays(i);
datelist.Add(tmpdate);
}
startTime = (DateTime)reader["startTime"];
endTime = (DateTime)reader["endTime"];
dow = (int)reader["dow"];
foreach (DateTime day in datelist.ToList())
{
if((int)day.DayOfWeek == dow)
{
CalendarEvent cevent = new CalendarEvent();
newstartdate = new DateTime(day.Year, day.Month, day.Day, startTime.Hour, startTime.Minute, 0);
newenddate = new DateTime(day.Year, day.Month, day.Day, endTime.Hour, endTime.Minute, 0);
cevent.id = (int)reader["event_id"];
cevent.title = (string)reader["ModuleName"];
cevent.description = (string)reader["Lecturer"];
cevent.start = newstartdate;
cevent.end = newenddate;
DateTime startDate = (DateTime)reader["startDate"];
ceventlist.start = startDate.ToString("yyyy-MM-dd");
DateTime endDate = (DateTime)reader["EndDate"];
ceventlist.end = endDate.ToString("yyyy-MM-dd");
datelist.Remove(day);
cevent.ranges = new List<CalendarEventList>();
cevent.ranges.Add(ceventlist);
events.Add(cevent);
}
}

Related

How can I set time limit in calendar?

I am using https://ui.toast.com/tui-calendar Toast Calender I just want show 09:00-17:00 in this calendar. It works on my PC but it shows me full time,
but It doesn't have options for limit.
this calendar can not set custom limit times?
Script
const week = {
hourStart: 9,
hourEnd: 17
};
var Calendar = tui.Calendar;
var calendar = new Calendar('#calendar', {
defaultView: 'week',
taskView: false,
useCreationPopup: false,
useDetailPopup: true,
allDaySlot: false,
droppable: false,
template: {
monthDayname: function(dayname) {
return '<span class="calendar-week-dayname-name">' + dayname.label + '</span>';
}
}
});
document.getElementById('my-today-button').addEventListener('click', function() {
calendar.today();
});
document.getElementById('my-next-button').addEventListener('click', function() {
calendar.next();
});
document.getElementById('my-prev-button').addEventListener('click', function() {
calendar.prev();
});
document.getElementById('weekView').addEventListener('click', function() {
calendar.changeView('week', true);
});
document.getElementById('monthView').addEventListener('click', function() {
calendar.changeView('month', true);
});

FullCalendar end date null whenever event is not changed even though allday false

Does anybody know why is the end date null on those "allday=false" events?
Fiddle Sample: https://jsfiddle.net/L1g0z3jd/
I instantiate it differently from the start date, it shows just fine in the calendar view, but for some reason I can't understand whenever i get clientEvents, even thought i have not changed it, I got a null in the event end date!
PS: Just for the sake of "conscience" I must add ... I'm using and old version of google chrome (v 57.0.2987.133 64-bit) and an old ubuntu version (Linux Mint 18.1 Serena)
Its getting me crazy! Thanks!
HTML Code:
<button onclick="javascript:getEvents()">Get Events</button>
<div id='calendar'></div>
Javascript Code:
$(function() {
$('#calendar').fullCalendar({
header: false,
allDaySlot: false,
visibleRange: {start: moment('2000-01-02'), end: moment('2000-01-09')},
editable: true,
selectable: true,
views: {
settimana: {
type: 'agenda',
columnFormat: 'ddd',
hiddenDays: []
}
},
defaultView: 'settimana',
defaultDate: $.fullCalendar.moment().startOf('week'),
slotMinutes: 30,
events: [
$.fn.getAgendaWorktime(1, "08:00:00", 60),
$.fn.getAgendaWorktime(2, "08:30:00", 120),
],
select: function(startDate, endDate) {
$('#calendar').fullCalendar('renderEvent', {
title: 'free time',
start: startDate.format(),
end: endDate.format(),
allDay: false
});
},
eventClick: function(calEvent, jsEvent, view) {
console.log(calEvent, jsEvent, view);
if(doubleClick==calEvent._id){
if (confirm('Delete it?')) {
$('#calendar').fullCalendar('removeEvents',calEvent._id);
}
doubleClick = null;
}else{
doubleClick=calEvent._id;
}
},
});
});
function getEvents() {
var e=0,err=false,$data = []
$('#calendar').fullCalendar('clientEvents').forEach(periodo => {
if (periodo.end==null || periodo.start.format().substr(0,10)!=periodo.end.format().substr(0,10)) {
if (e==0) {
err = true;
e++;
alert('Event startint at '+periodo.start.format()+' cant spread to multiple days');
}
} else {
$data.push({'ini': periodo.start.format(), 'fim': periodo.end.format()});
}
});
alert($data);
}
jQuery.fn.getAgendaWorktime = function ($dow, $start, $elapsed) {
var r = {
allDay: false,
title: 'free time',
start: new Date('2000-01-02 '+$start),
end: new Date('2000-01-02 '+$start)
};
r.start.setDate(r.start.getDate()+$dow);
r.end.setDate(r.end.getDate()+$dow);
r.end.setHours(r.end.setHours()+($elapsed*60));
return(r);
}
I figured out how to solve the question, I will reply to it here for I have not found any workaround or further analysis of the problem in the internet ....
I didn't review my problem to determine if it was specific related to the fact that I was setting the event's end time incorrectly and the calendar wasn't giving me any errors on the issue or anything else, but if you're gowing by the same road i went i can tell you:
Check to see if the end time is been created corretly (that seams to be my real mistaken, I was using setHours instead getHours in the getAgendaWorktime function, which turned the final value to be null. I corrected it in the sample below, but let it incorrectly in the fiddle to show the use of the forceEventDuration attribute);
Set "forceEventDuration" parameter to "true" (that forces the "end" attribute to always be filled easying me up in my code for I can always awaits for an string from ".format()" method of the attibute);
for meny reasons fullcalendar.io some times does not sets the event end date and this was getting me problems whenever avaluating the event end time (Ok, I could work around it but I was intrigged for why does it was getting me those results when it sould not, and the answare was a buged code). With "forceEventDuration: true" fullcalendar gave me the end time every time therefor i could find out that the input method i was using was seting the end date incorrectly and gave me the chance to correct it as well.
Links related:
Calendar parameter documentation https://fullcalendar.io/docs/forceEventDuration
Corrected Fiddle https://jsfiddle.net/gjrfox05/
I hope this answer could be of some help for newcomers at fullcalendar.io as me.
Fiddle Javascript part corrected sample:
$(function() {
$('#calendar').fullCalendar({
header: false,
allDaySlot: false,
forceEventDuration: true,
visibleRange: {start: moment('2000-01-02'), end: moment('2000-01-09')},
editable: true,
selectable: true,
views: {
settimana: {
type: 'agenda',
columnFormat: 'ddd',
hiddenDays: []
}
},
defaultView: 'settimana',
defaultDate: $.fullCalendar.moment().startOf('week'),
slotMinutes: 30,
events: [
$.fn.getAgendaWorktime(1, "08:00:00", 60),
$.fn.getAgendaWorktime(2, "08:30:00", 120),
],
select: function(startDate, endDate) {
$('#calendar').fullCalendar('renderEvent', {
title: 'free time',
start: startDate.format(),
end: endDate.format(),
allDay: false
});
},
eventClick: function(calEvent, jsEvent, view) {
console.log(calEvent, jsEvent, view);
if(doubleClick==calEvent._id){
if (confirm('Delete it?')) {
$('#calendar').fullCalendar('removeEvents',calEvent._id);
}
doubleClick = null;
}else{
doubleClick=calEvent._id;
}
},
});
});
function getEvents() {
var e=0,err=false,$data = []
$('#calendar').fullCalendar('clientEvents').forEach(periodo => {
if (periodo.end==null || periodo.start.format().substr(0,10)!=periodo.end.format().substr(0,10)) {
if (e==0) {
err = true;
e++;
alert('Event startint at '+periodo.start.format()+' cant spread to multiple days');
}
} else {
$data.push({'ini': periodo.start.format(), 'fim': periodo.end.format()});
}
});
alert($data[0].fim);
}
jQuery.fn.getAgendaWorktime = function ($dow, $start, $elapsed) {
var r = {
allDay: false,
title: 'free time',
start: new Date('2000-01-02 '+$start),
end: new Date('2000-01-02 '+$start)
};
r.start.setDate(r.start.getDate()+$dow);
r.end.setDate(r.end.getDate()+$dow);
r.end.setHours(r.end.getHours()+($elapsed*60));
return(r);
}
By default FullCalendar end date null when event end_date = start_date.
I Just pass another fiend with same date from database (Django View).
event_sub_arr['end'] = end_date
event_sub_arr['end_same_date'] = end_date
And check in javaScript
eventClick: function(info) {
var modal = document.getElementById('DeleteEventModal')
getEventDeleteUrl(info.event.id)
getEventUpdateUrl(info.event.id)
modal.style.display = 'block'
calendar.unselect()
var start = info.event.start
var end_same_date = info.event.end_same_date
var end = info.event.end || end_same_date
$("#event_id_name").text(info.event.title)
$("#event_id_start").text(moment(start).format('h:mm:ss a, MMMM Do YYYY'))
$("#event_id_end").text(moment(end).format('h:mm:ss a, MMMM Do YYYY'))
console.log(info.event.start)
console.log(info.event.end)
console.log({{ event_data|safe }})
},
ITS WORK FOR ME

FullCalendar showing Duplicates Events on Month change

I am working on adding events to fullcalendar with Javascript. I am using fullcalendar-2.7.2. The events are added when i click on the custom button but when I change the month it shows many duplicate events.
Here is the code that I have written :-
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
theme: true,
eventClick: function(event) {
// opens events in a popup window
window.open(event.url, 'gcalevent', 'width=700,height=600');
return false;
},
loading: function(bool) {
$('#processingDiv').toggle(bool);
},
selectable: true,
selectHelper: true,
select: function(start, end) {
var title = prompt('Event Title:');
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
}
$('#calendar').fullCalendar('unselect');
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
defaultDate: moment().utc().valueOf(),
editable: true,
eventLimit: true, // allow "more" link when too many events
fixedWeekCount: false
});
try {
//This data is showing Okay. This one is the Test Event in image Below on Date 1.
var jsonStart = JSON.parse('{!jsonStringSF}');
var myCalendar = $('#calendar');
for(var i=0; i < jsonStart.length; i++) {
var myEvent = {
id: jsonStart[i].id,
title: jsonStart[i].title,
allDay: jsonStart[i].allDay,
start: jsonStart[i].startDate,
end: jsonStart[i].endDate
};
myCalendar.fullCalendar('removeEvents', myEvent.id );
myCalendar.fullCalendar( 'renderEvent', myEvent, true );
}
} catch(err) {
alert(err.message);
}
});
</script>
<body>
<apex:form >
<apex:actionFunction name="getEventsFromGoogle" action="{!getEventsFromCalendar}" onComplete="showEventsOnCalendar('{!jsonString}');" />
<apex:actionFunction name="syncEventsToGoogle" action="{!startSyncToGoogle}" onComplete="hideProcessingDiv();" />
</apex:form>
<div id="processingDiv" style="display:none;">
<apex:outputPanel styleClass="popupBackground" layout="block"/>
<apex:outputPanel styleClass="custPopup" layout="block">
<img src="/img/loading24.gif" style="vertical-align:middle; horizontal-align:middle"/>
<span>Please wait...</span>
</apex:outputPanel>
</div>
<div id="allButtons">
<button class="ui-button ui-state-default" onClick="syncToGoogle();">Sync Salesforce to Google</button>
<button class="ui-button ui-state-default" onclick="connectToGoogle();">Sync Google to Salesforce</button>
</div>
<div id='calendar'></div>
<script>
function syncToGoogle() {
showProcessingDiv();
syncEventsToGoogle();
}
function connectToGoogle() {
showProcessingDiv();
getEventsFromGoogle();
}
function showEventsOnCalendar(jsonString) {
//jsonString is [{"title":"Assign Task","startDate":"2016-05-07T13:00:00+05:30","sequence":1,"recurrence":["RRULE:FREQ=WEEKLY;BYDAY=SU,SA"],"id":"mhpufelkfo1d7thn2naqm2s2ec","endDate":"2016-05-07T14:00:00+05:30","allDay":false}]
try {
var json = JSON.parse(jsonString); //This is String which has list of events.
var myCalendar = $('#calendar');
var myEvent = '';
for(var i=0; i < 1; i++) { //For testing I have itrated the loop just once.
myEvent = '';
var recurValue = JSON.stringify(json[i].recurrence);
//RRULE:FREQ=WEEKLY;UNTIL=20160520T110000Z;BYDAY=MO,TU,WE,TH,FR,SU,SA
//Recurrence returns this format.
if(recurValue != null && recurValue != 'null') {
var Frequency = recurValue.match("FREQ=(.*?);");
var Until = recurValue.match("UNTIL=(.*?);");
var ByDay = recurValue.match("BYDAY=(.*?)\"]");
if(ByDay[1] == null && ByDay[1] == 'null') {
ByDay[1] = '';
}
var repeatDays = [];
if(ByDay[1].indexOf('MO') > -1) {
repeatDays.push(1);
}
if(ByDay[1].indexOf('TU') > -1) {
repeatDays.push(2);
}
if(ByDay[1].indexOf('WE') > -1) {
repeatDays.push(3);
}
if(ByDay[1].indexOf('TH') > -1) {
repeatDays.push(4);
}
if(ByDay[1].indexOf('FR') > -1) {
repeatDays.push(5);
}
if(ByDay[1].indexOf('SA') > -1) {
repeatDays.push(6);
}
if(ByDay[1].indexOf('SU') > -1) {
repeatDays.push(0);
}
myEvent = {
id: json[i].id,
title: json[i].title,
allDay: json[i].allDay,
start: json[i].startDate,
end: json[i].endDate,
dow: repeatDays
};
} else {
myEvent = {
id: json[i].id,
title: json[i].title,
allDay: json[i].allDay,
start: json[i].startDate,
end: json[i].endDate
};
}
$('.fc-event').remove(); //Tried this is solve the problem but failed.
//myCalendar.fullCalendar('removeEvents', myEvent.id ); //also tried this but still no luck.
myCalendar.fullCalendar( 'renderEvent', myEvent, true );
}
hideProcessingDiv();
} catch(err) {
hideProcessingDiv();
alert(err.message);
}
}
This is how it looks at start :-
Here is the screenshot of the problem when click on the next month or come back: -
Can anyone suggest me the solution to stop the duplicates?

Fullcalendar, preventing user from selecting multiple day event

In my fullcalendar http://fullcalendar.io/
I want to prevent a user to be able to create an event on multiple days
$('#calendar').fullCalendar({
defaultView: 'agendaWeek',
lang: "fr",
header: false,
timezone: 'local',
minTime: "08:00:00",
columnFormat: 'dddd',
selectHelper: true,
selectable: true,
select: function(start, end, id, allDay) {
var eventData = {
start: start,
end: end,
id: 1,
block: true,
editable: true,
backgroundColor: "#469278"
};
// console.log(moment(eventData.start["_d"]).format("dddd"));
// console.log(moment(eventData.end["_d"]).format("dddd"));
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
// console.log(eventData);
if (moment(eventData.start["_d"]).format("dddd") != moment(eventData.end["_d"]).format("dddd")) {
$('#calendar').fullCalendar('unselect');
};
var day = moment(eventData.start["_d"]).format("dddd");
var start_time = moment(eventData.start["_d"]).format("HH:mm");
var end_time = moment(eventData.end["_d"]).format("HH:mm");
var id = moment(eventData.end["_id"]);
var slot = {
day: day,
start_time: start_time,
end_time: end_time
};
array_dispo.push(slot);
$("#dispo_array").val(JSON.stringify(array_dispo));
$('#calendar').fullCalendar('unselect');
},
});
});
When a user is selecting a start date that is different from the end date of his event I thus tried to use the unselect method from the doc http://fullcalendar.io/docs/selection/unselect_method/ like this :
if (moment(eventData.start["_d"]).format("dddd") != moment(eventData.end["_d"]).format("dddd")) {
$('#calendar').fullCalendar('unselect');
};
But unfortunately this code doesnt automatically deselects the current selection...
You can do a check in your select method and then decide whether you want to render the event or not.
I also use Moment.js to calculate dates and durations, this library is included with FullCalendar (http://fullcalendar.io/docs/utilities/Moment/)
So I played around and came up with this:
select: function (start, end) {
var mEnd = $.fullCalendar.moment(end);
var mStart = $.fullCalendar.moment(start);
if (mEnd.isAfter(mStart, 'day')) {
$('#calendar').fullCalendar('unselect');
} else {
$('#calendar').fullCalendar('renderEvent', {
start: mStart,
end: mEnd,
allDay: false
},
true // stick the event
);
$('#calendar').fullCalendar('unselect');
}
}
Here is the jsfiddle if you want to see it in action: here
You can do it using this way:
eventResize: function(eventResizeInfo) {
console.log('eventResize is called');
var event = eventResizeInfo.event;
if (event.start.getDay() !== event.end.getDay()) {
eventResizeInfo.revert();
}
},
To prevent users from selecting multiple days at a time
selectAllow: function(selectedEvent) {
let startDate = selectedEvent.start;
let endDate = selectedEvent.end;
endDate.setSeconds(endDate.getSeconds() - 1);
if (startDate.getDate() === endDate.getDate()) {
return true;
} else {
return false;
}
}
Simply add the following option to your calendar:
selectAllow: (selectInfo) => { return selectInfo.start.getDay() === selectInfo.end.getDay() },

on refresh full calendar adds duplicate events

On the first load of the page, it shows a single event per day, but on the second load (or refresh of the page) it adds a duplicate event on the same day in the full calendar.
Here is my code:
var CalendarView = Backbone.View.extend({
el : '#calendar-box',
initialize : function() {
// TODO for instance: more instances, Event Bus bindings... only once.
this.calendarModel = new CalendarModel();
$('#calendar-box').hide();
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
this.calendarModel.fetch({
success : function(model, response, options) {
$.unblockUI();
var count=0;
var eventsList=[];
model.attributes.result.forEach(function(){
eventsList.push({
id: model.attributes.result[count].eventId,
title:model.attributes.result[count].title,
start: new Date(model.attributes.result[count].startDate),
end: new Date(model.attributes.result[count].endDate),
attorneyName: model.attributes.result[count].attorneyName,
codeLitOrg: model.attributes.result[count].codeLitOrg,
balance: model.attributes.result[count].balance,
litCode: model.attributes.result[count].litCode
});
count++;
});
if (!_.isEmpty(eventsList)){
$('#calendar').fullCalendar({
editable: true,
events: eventsList,
eventMouseover: function(event, jsEvent, view) {
var info = event.title+'\nBK/LIT: '+event.codeLitOrg+'\nBalance: '+event.balance
+'\nAttorney: '+event.attorneyName+'\nLitCode: '+event.litCode;
$(jsEvent.target).attr('title', info);
},
theme: false,
height:575,
weekMode:'liquid',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
});
}
},
error : function(model, xhr, options) {
$.unblockUI();
}
});
$.eventBus.on('calendarModalLoaded',function(){
if (!($('.fc-border-separate').html())){
$('#calendar').fullCalendar('today');
}
});
},
render : function() {
// TODO for instance, bindings elements after ready in DOM.
$('#calendar').fullCalendar('today');
return this;
},
events : {
'click a.op-attorney-info' : 'onAttorneyInfo',
'click .go-back-link' : 'goBack'
},
goBack: function(){
$('#calendar-box, .content-box').toggle();
//$('.content-box').toggle();
//$('.go-back-link').hide();
},
onAttorneyInfo : function(ev) {
// TODO for instance, fetch attorney's model
}
});
return CalendarView;
});
I have tried $('#calendar').fullCalendar('removeEvents'), but it is also not working.
Please help me out.

Categories