bootstrap3 pretty-fullcalendar meteor not reactive in blaze - meteor

I'm using a bootstrap3 pretty-fullcalendar in a project and pre blaze, when I changed some properties of an event (such as color) it was immediately reflected in the display on the calendar. Now, when I change the attribute, I have to reload the calendar manually to have the change show up.
I'm instantiating the calendar in the template render function as
Template.packLayout.rendered = function(){
$('#calendar').fullCalendar({
//dayClick:function( date, allDay, jsEvent, view ) {
// Requests.insert({title:'Request',start:date,end:date,color:'red',className:'todo'});
// Session.set('lastMod',new Date());
//},
eventClick:function(reqEvent,jsEvent,view){
Session.set('editingReqEvent',reqEvent.id);
Session.set('showEditEvent',true);
},
eventDrop:function(reqEvent){
Requests.update(reqEvent.id, {$set: {start:reqEvent.start,end:reqEvent.end}});
Session.set('lastMod',new Date());
},
events: function(start, end, callback) {
var events = [];
reqEvents = Requests.find();
reqEvents.forEach(function(evt){
event = {id:evt._id,title:evt.title,start:evt.start,end:evt.end,color:evt.color};
events.push(event);
})
callback(events);
},
editable:true,
weekMode: 'liquid'
});
}
Has something changed that would make this happen?

Here is how i managed to get it working:
1) keep your calendar code as per "rendered"
Template.calendar.rendered = function () {
console.log('Calendar - running redered');
Session.set('calendarTemplateRendered', true);
var entries = Calendar.find().fetch(),
$calendar = $('#calendar');
$calendar.html('').fullCalendar({
header: {
left: '',
center: '',
right: ''
},
contentHeight: 1100,
defaultDate: '2014-01-12',
defaultView: 'agendaWeek',
editable: true,
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');
},
events: entries
});
Add a autorun:
Deps.autorun(function () {
if (Session.equals('calendarTemplateRendered', false) ||
!calendarSubs.ready() ||
typeof Calendar === 'undefined') {
console.log('exiting because there is no objects to process');
return;
}
console.log('trying to autorun');
var entries = Calendar.find().fetch(),
$calendar = $('#calendar');
$calendar.fullCalendar('removeEvents');
$calendar.fullCalendar('addEventSource', entries);
$calendar.fullCalendar('rerenderEvents');
}
Blaze will do the rest for you - (redraw the UI properly). Now you can just modify your Calendar subscription as you like and it will work perfectly.

Related

fullcalendar v5 after edit event render() don't refresh

when i edit a event list, it correctly reload but calendar don't refresh.
if i click in other tab and then return in calendar tab it refresh: problem with bootstrap? This is my function to init calendar
function getCalendar(mydate) {
//Date for the calendar events (dummy data)
var date = new Date()
var d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear()
var calendar = FullCalendar.Calendar;
var calendarEl = document.getElementById('calendar');
var calEv=bindEvents(mydate);
//var calRi=bindResource(mydate);
dCal = new calendar(calendarEl, {
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
timeZone: 'UTC',
height: '100%',
contentHeight: 'auto',
initialView: 'dayGridMonth',
themeSystem: 'bootstrap',
locale: 'it',
//Random default events
//events: 'https://fullcalendar.io/demo-events.json',
//events: bindEvents(mydate),
//events: calEv,
//events: evUrl,
events: function(info, successCallback, failureCallback) {
var evUrl = window.apiurl+'/api/anagrafiche/tourfascecalevents/'+id_entita;
$.ajax(evUrl, {
type: 'GET',
cache: false,
}).done(function(dati) {
dbgConsole("render init ev");
dbgConsole(dati);
ev=bindEvents(dati);
dbgConsole(ev);
successCallback(ev);
}).fail(function(x,s,t) {
alert_error(x);
});
},
//resources: bindResource(mydate),
initialDate: dataIni,
editable : true,
selectable: true,
droppable : false, // this allows things to be dropped onto the calendar !!!
dateClick: function(info) {
dbgConsole(info);//event.setProp( name, value )
var cls=[];
var data_fine = moment(info.dateStr, "YYYY-MM-DD").add(gg_viaggio, 'days').format('YYYY-MM-DD');
if ('undefined' == typeof grpSelected || ''==grpSelected) {
// alert('Cancellazione data: ' + info.dateStr + ' !');
var reqUrl = window.apiurl+'/api/anagrafiche/tourfasce/'+id_entita;
$.ajax(reqUrl, {
type: 'DELETE',
cache: false,
data: {
id_gruppo: id_gruppo,
id_entita: id_entita,
MM_delete: 'form_fascedel',
data_inizio: info.dateStr
}
}).done(function(dati) {
window.tables['FasceTable'].setData();
dbgConsole("render");
//$('#h-tab').trigger('click');
//$('#dati-fasce-tab').trigger('click');
dCal.render();
//dCal.updateSize();
}).fail(function(x,s,t) {
alert_error(x);
});
} else {
// alert('Imposta data: ' + info.dateStr + ' in gruppo "'+grpSelected+'" !');
var reqUrl = window.apiurl+'/api/anagrafiche/tourfasce/'+id_entita;
$.ajax(reqUrl, {
type: 'PUT',
cache: false,
data: {
id_gruppo: id_gruppo,
id_entita: id_entita,
MM_update: 'form_fasceupd',
data_inizio: info.dateStr,
nome_periodo: grpSelected,
data_fine: data_fine
}
}).done(function(dati) {
window.tables['FasceTable'].setData();
dbgConsole("render");
//$('#h-tab').trigger('click');
//$('#dati-fasce-tab').trigger('click');
dCal.render();
//dCal.updateSize();
}).fail(function(x,s,t) {
alert_error(x);
});
}
// alert('Gruppo: ' + id_gruppo + ' - Entita: "'+id_entita+ ' - Giorni: "'+gg_viaggio+'" !');
//dCal.setOption('initialDate', '2021-06-01');
//dCal.render();
},
/*
eventClick: function(calEvent, jsEvent, view) {
var testo='';
testo=testo+'Servizio: ' + calEvent.title_serv+'\n';
testo=testo+'Inizio: ' + calEvent.start.format()+'\n';
testo=testo+'Fine: ' + calEvent.end.format()+'\n';
testo=testo+'Descrizione: ' + calEvent.title+'\n';
alert(testo);
}
*/
});
//dCal.render();
dbgConsole("Cal:")
dbgConsole(dCal);//event.setProp( name, value )
}
and this is activation
$('#dati-fasce-tab').on('shown.bs.tab', function (event) {
dCal.render();
})
after 'dateClick' events are modified and reloaded but calendar not update view
P.S.: all events are type 'background'
Already exists any different method to refresh?
We are a problem to refresh on load calendar in hidden area, any idea?
First of all, you need to render the fullcalendar element inside the initialize function.
function getCalendar(mydate) {
...
dCal = new calendar(calendarEl, {
});
dCal.render();
}
After that, you need to use refetchEvents function while an event like changing tab or save an event is firing.
https://fullcalendar.io/docs/Calendar-refetchEvents
dCal.refetchEvents();
You could face into an issue like dCal is undefined, then you need to add some handling like
if (typeof dCal !== 'undefined') {
dCal.refetchEvents();
}

onDragStop tells me jsEvent is undefined

I'm trying to make it possible to drag events to an external div and back into the calendar again. However, whenever I drop an event I get TypeError: jsEvent is undefined.
I'm not entirely sure why it is doing this, this should be a valid parameter that is passed to the function of eventDragStop.
I'm using the latest FullCalendar 4.
Here is my code
// Load the CSS stuff
import {Tooltip} from "bootstrap";
require('#fortawesome/fontawesome-free/css/fontawesome.min.css');
require('#fortawesome/fontawesome-free/css/brands.min.css');
require('#fortawesome/fontawesome-free/css/solid.min.css');
require('../css/app.scss');
// Load the JS stuff
let $ = require('jquery');
require('bootstrap');
require('./libs/navbar.js');
require('jquery-ui/ui/widgets/draggable');
import apiclient from "./libs/apiclient";
import { Calendar } from '#fullcalendar/core';
import dayGridPlugin from '#fullcalendar/daygrid';
import timeGridPlugin from '#fullcalendar/timegrid';
import interactionPlugin from '#fullcalendar/interaction';
import bootstrapPlugin from '#fullcalendar/bootstrap';
// $(document).ready(function () {
//
// });
document.addEventListener('DOMContentLoaded', () => {
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events .fc-event').each(function() {
// store data so the calendar knows to render an event upon drop
$(this).data('event', {
title: $.trim($(this).text()), // use the element's text as the event title
stick: true // maintain when user navigates (see docs on the renderEvent method)
});
// 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
});
});
let calendarEl = document.getElementById('calendar-holder');
let calendar = new Calendar(calendarEl, {
views: {
jira: {
type: 'dayGridWeek',
duration: {months: 3},
buttonText: 'Jira'
}
},
defaultView: 'jira',
themeSystem: 'bootstrap',
editable: true,
droppable: true,
firstDay: 1,
contentHeight: 'auto',
weekNumbersWithinDays: true,
weekNumbers: true,
eventSources: [
{
url: "/fc-load-events",
method: "POST",
extraParams: {
filters: JSON.stringify({})
},
failure: () => {
// alert("There was an error while fetching FullCalendar!");
},
},
],
header: {
left: 'prev,next today',
center: 'title',
right: 'jira,dayGridMonth,timeGridWeek',
},
plugins: [ bootstrapPlugin, interactionPlugin, dayGridPlugin, timeGridPlugin ], // https://fullcalendar.io/docs/plugin-index
timeZone: 'UTC',
eventRender: function(info) {
var tooltip = new Tooltip(info.el, {
title: info.event.title+'<br>'+info.event.extendedProps.assignee,
placement: 'top',
trigger: 'hover',
container: 'body',
html: true
});
},
dragRevertDuration: 0,
drop: function() {
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
},
eventDragStop: function( event, jsEvent, view ) {
if(isEventOverDiv(jsEvent.clientX, jsEvent.clientY)) {
$('#calendar-holder').calendar('removeEvents', event._id);
var el = $( "<div class='fc-event'>" ).appendTo( '#external-events-listing' ).text( event.title );
el.draggable({
zIndex: 999,
revert: true,
revertDuration: 0
});
el.data('event', { title: event.title, id :event.id, stick: true });
}
}
});
calendar.render();
let isEventOverDiv = function(x, y) {
var external_events = $( '#external-events' );
var offset = external_events.offset();
offset.right = external_events.width() + offset.left;
offset.bottom = external_events.height() + offset.top;
// Compare
if (x >= offset.left
&& y >= offset.top
&& x <= offset.right
&& y <= offset .bottom) { return true; }
return false;
}
});
I figured out that the jsEvent is now located in event.jsEvent. This is where I can get the position from now.

Jquery full calendar (style changes after page refresh)

This is my calendar initially after the event creation:
and this is after page refresh:
Can anyone help me understand how to keep the same style even after page refresh, specifically the vertical line in the middle? Sometimes the line increases as well.
The fullCalendar JS is as follows:
$('#calendar').fullCalendar({
locale: 'nl',
weekends: true, // false will hide Saturdays and Sundays
defaultView: 'agendaWeek',
allDaySlot: false,
slotLabelFormat: "HH:mm",
axisFormat: 'HH:mm',
timeFormat: 'HH:mm',
aspectRatio: 1,
editable: true,
eventStartEditable: true,
selectable: true,
selectHelper: true,
unselectAuto: false,
eventLimit: true,
dragScroll: true,
eventOverlap: false,
slotEventOverlap: false,
header: {
left: 'title',
center: '',
right: 'prev,next,today,agendaWeek,agendaDay'
},
views: {},
eventDrop: function (event, dayDelta, minuteDelta, allDay, revertFunc) {
var title = "Available";
var eventInfo;
eventInfo = {
title: title,
start: event.start,
end: event.end,
id: event.id
};
updateEvent(eventInfo);
},
eventResize: function (event, dayDelta, minuteDelta, revertFunc) {
var title = "Available";
var eventInfo;
eventInfo = {
title: title,
start: event.start,
end: event.end,
id: event.id
};
updateEvent(eventInfo);
},
select: function (start, end) {
var title = "Available";
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
createEvent(eventData);
}
$('#calendar').fullCalendar('unselect');
},
eventSources: [{
events: function (start, end, timezone, callback) {
var employeeId = $("#employee-Id").val();
$.ajax({
url: '../' + employeeId + '/events',
dataType: 'json',
success: function (response) {
var events = $.parseJSON(response.data);
$('#calendar').fullCalendar('addEventSource', events);
callback(events);
}
});
}
}],
eventRender: function (event, element) {
//delete event on double click..Tanvir
element.one().bind('dblclick', function (e) {
/* e.preventDefault();
$(this).prop('disabled', true);
setTimeout(function () { $(this).prop('disabled', false); }, 500);*/
$("#startTime").html(moment(event.start).format('MMM Do YYYY, h:mm A'));
$("#endTime").html(moment(event.end).format('MMM Do YYYY,h:mm A'));
$("#eventContent").dialog({modal: true, title: event.title, width: 100});
$('.delete-event').bind('click', function (e) {
$('#calendar').fullCalendar('removeEvents', event._id);
deleteEvent(event.id);
$("#eventContent").hide();
});
$('.discard-delete').bind('click', function () {
$("#eventContent").hide();
});
});
},
});
});
No duplicate event is created in the database. What is happening a the event HTML is rendering twice after refresh. Specifically fc-time-grid-event under the event container class is rendering twice after refresh.
The cause of the duplication is here, in your events function:
$('#calendar').fullCalendar('addEventSource', events);
callback(events);
You are adding the event objects as an event source, AND sending them back to the calendar as a list of events, in the documented way. So while the events may not be duplicated in your database, your code is sending two sets of identical event data to the calendar, and consequently they are displayed twice.
You can simply remove this line:
$('#calendar').fullCalendar('addEventSource', events);
as it is totally unnecessary in this context.

Fetching all GoogleCalendar Events before FullCalendar has loaded

I currently am using Adam Shaw's jQuery Calendar 'FullCalendar' and am experiencing significant delays in the calendar rendering. In short, the page appears, 1 second passes, the Calendar pops in, another second passes, and then the events populate the page, here. Is there a way to only fetch a certain number of events behind and before today's date? Or even loading the calendar immediately would be an improvement. I am also using Craig Thompson's qTip2.
Javascript
<script type=text/javascript>
// Setup FullCalendar
jQuery(document).ready
(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var tooltip = $('<div/>').qtip({
id: 'fullcalendar',
prerender: true,
content: {
text: ' ',
title: {
},
},
events: {
render: function(event, api) {
var elem = api.elements.bgiframe;
}
},
position: {
my: 'bottom center',
at: 'top center',
target: 'event',
viewport: $(window),
adjust: {
mouse: false,
scroll: true,
method: 'shift',
resize: true
}
},
show: {
modal: {
on: false,
blur: true,
stealfocus: false
}
},
hide: false,
style: 'qtip-bootstrap'
}).qtip('api');
$('#fullcalendar').fullCalendar({
eventSources: ["https://www.google.com/calendar/feeds/emailaddresshere/public/basic",
"http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic"],
header: {
left: 'title',
center: '',
right: 'today prev,next'
},
selectable: true,
eventClick: function(data, event, view) {
var content = '<h3>'+data.title+'</h3>' +
'<p><b>Start:</b> '+data.start+'<br />' +
(data.end && '<p><b>End:</b> '+data.end+'</p>' || '');
tooltip.set({
'content.text': content
})
.reposition(event).show(event);
},
dayClick: function() { tooltip.hide() },
eventResizeStart: true,
eventDragStart: false,
viewDisplay: function() { tooltip.hide() }
});
}());
</script>

dayClick and eventClick function not working

I have inserted some new functions in my js but dayClick and eventClick don't work. The calendar is able to load properly though.
Any idea why the dayclick and eventclick in the following code is not working?
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: '',
right: 'agendaWeek,agendaDay'
},
selectable: true,
selectHelper: true,
allDayDefault: false,
allDaySlot: false,
firstHour: 9,
defaultView: 'agendaWeek',
dayClick: function(date, allDay, jsEvent, view) {
calendar.fullCalendar('gotoDate', date);
},
eventClick: function(calEvent, jsEvent, view) {
window.location = "http://www.domain.com?start=" + calEvent.start;
},
select: function(start, end) {
var title = prompt('Event Title:');
if (title) {
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end
},
false // make the event "stick"
);
var startDateString = $.fullCalendar.formatDate(start, 'yyyy-MM-dd hh:mm');
var endDateString = $.fullCalendar.formatDate(end, 'yyyy-MM-dd hh:mm');
$.ajax({
type: 'POST',
url: '{url}ajaxpost/add',
data: {
startDate: startDateString,
endDate: endDateString,
eventTitle: title
},
dateType: 'json',
success: function (resp) {
calendar.fullCalendar('refetchEvents');
}
});
}
calendar.fullCalendar('unselect');
},
editable: true,
events: "{url}ajaxget/data",
});
});
You cannot use the "select" callback and the "dayClick" callback together as there is a conflict between the two. You can use datepicker to accomplish the gotoDate function to accomplish the same thing.
http://weblogs.asp.net/gunnarpeipman/archive/2010/02/02/linking-jqueryui-datepicker-and-fullcalendar.aspx
As for the eventClick Im not sure why it is not working, but it is easier to place the url in the database the call it in the events and just set it as the property "url: www.somesite.com/sdfjkiwe"
As a side note, It would probably wor better if you didn't use renderEvent to display your event. Try using the event function found here to use your ajax call within it.
http://arshaw.com/fullcalendar/docs/event_data/events_function/

Resources