Looking for an example of how to implement the loading callback.
Here is my code that I am using so far. Just not sure how to use the loading callback.
Do I need to use events as a function or can I add something to the code I am using here?
Thanks
$('#calendar').fullCalendar({
theme: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
events: {
url: 'calendar/ajax.php',
data: {
uid: '<?=$_SESSION[$pageID]['owner_uid']?>',
fbpageid: '<?=$pageID?>'
},
error: function() {
alert('there was an error while fetching events!');
}
},
eventMouseover: function(calEvent,jsEvent) {
xOffset = 10;
yOffset = 10;
var left = (jsEvent.clientX + yOffset);
if ( (jsEvent.clientX + 200 + yOffset) > $(window).width() ){
left = (jsEvent.clientX - 200);
}
$("body").append(calEvent.tooltip);
$("#p_"+calEvent.id)
.css("top",(jsEvent.clientY - xOffset) + "px")
.css("left",left + "px")
.fadeIn("fast");
},
eventMouseout: function(calEvent,jsEvent) {
$("#p_"+calEvent.id).fadeOut("fast");
$("#p_"+calEvent.id).remove();
}
});
Here is an example of how to use the loading callback:
loading: function(bool) {
if (bool)
$('#loading').show();
else
$('#loading').hide();
},
Related
what I'm possibly doing wrong!?
I do NOT see my events when 'defaultView: agendaWeek' (or agendaDay).
PS: basicWeek (or basicDay) works just fine.
BUT: when clicking the 'month' view: ALL events are showing correctly in 'month' view! Then, when again clicking 'week' (or Day) I see them ALL correctly as agendaWeek (or agendaDay) view!
I'm running fullcalendar: 3.6.2
PS: sorry, posted same issue in non-related forum
must miss a stupid thing - thanks for your time and hints, ed
<script type="text/javascript">
(function ($) {
#if (Model.tagColorsEnabled && Model.tagColors != null) {
<text>
var tagSet = [
#foreach (var tc in Model.tagColors)
{
#Display(tc)
}
];
var tagIndex = [];
for (var tag in tagSet) {
tagIndex[tagSet[tag].slug] = tag;
}
</text>
}
$('#calendar').fullCalendar({
locale: '#culture',
timeFormat: 'HH:mm', //eddie timeFormat: 'HH:mm{-HH:mm}',
slotLabelFormat: 'HH:mm', //eddie timeFormat: 'HH:mm{-HH:mm}',
// height: 500, //added by eddie
// allDay: false, // eddie
header: {
left: 'prev,next today',
center: 'title',
right: 'month, agendaWeek, agendaDay',
// right: 'month, agendaWeek, agendaDay' // eddie
},
eventRender: function (event, element) {
var colors = { bg : event.defaultBackgroundColor, br: event.defaultBorderColor, fg: event.defaultTextColor };
#if (Model.tagColorsEnabled)
{
<text>
var min = 100;
for (var klassNdx in event.className) {
var klass = event.className[klassNdx];
if (klass.substring(0, 4) === "tag-") {
var entry = tagIndex[klass.substring(4)];
if (entry !== undefined) {
if (entry < min) {
colors = tagSet[entry];
min = entry;
}
}
}
}
</text>
}
$(element)
.css("background-color", colors.bg)
.css("color", colors.fg)
.css("border-color", colors.br);
},
editable: false,
events: {
url: '#Url.Content("~/_Calendar/" + Model.queryId)',
},
// defaultView: '#Model.defaultView',
// defaultView: 'basicWeek',
defaultView: 'agendaWeek',
weekends: #Model.showWeekends
//viewRender: function (v, e) { alert("Rendering view"); }
});
})(jQuery);
</script>
solved - sort of!
When using 'defaultView: basicWeek / agendaWeek'; fact is that I get different DateTime info like:
basicWeek: '2017-1-06' --> which in turn works correctly!
agendaWeek: '2017-1-06T00:00:00' --> which results in an error!
When stripping off 'T00:.....' --> problem solved
I know that this is probably not the 'clean' solution BUT for the time being ..... will further check if time is available!
For now I like to thank ADyson for his advise and time spent.
I've a calendar that I want to list various types of event on and enable a checkbox filter to show/hide those kind of events.
Is there a way to say on this action, ONLY load from 1 data-source AND remember that URL on month next/prev links?
I've started using eventSources, but it loads them all, rather than the one(s) I want.. Here's what I have.
var fcSources = {
all: {
url: tournament_url + '/getCalendar/?typefilter=[1,2]'
},
type1: {
url: tournament_url + '/getCalendar/?typefilter=[1]'
},
type2: {
url: tournament_url + '/getCalendar/?typefilter=[2]'
}
};
These URLS all provide a json string of events, based on the types prrovided.
Here's my calendar:
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek'
},
firstDay: 1, // Monday = 1
defaultDate: new Date(), // Now
editable: true,
eventSources: [ fcSources.all ],
events: fcSources.all,
nextDayThreshold: '00:00:00',
... etc etc
Above my calendar I have this:
input type="checkbox" name="event_filter[]" value="type1" /> Type 1
input type="checkbox" name="event_filter[]" value="type2" /> Type 2
And finally , two Jquery fucntions.. one to get all the filters:
function getFilters(getName) {
var filters = [];
var checked = [];
$("input[name='"+getName+"[]']").each(function () {
filters.push( $(this).val() );
});
$("input[name='"+getName+"[]']:checked").each(function () {
checked.push( $(this).val() );
});
return [filters, checked];
}
and the last to load them:
$(".event_filter").on('click', function() {
var doFilters = getFilters('event_filter');
$('#calendar').fullCalendar( 'removeEvents' );
if (doFilters[0] === doFilters[1]) {
$('#calendar').fullCalendar( 'addEventSource', fcSources.all );
} else {
$.each(doFilters[1], function(myFilter, myVal) {
console.log(myVal);
$('#calendar').fullCalendar( 'addEventSource', fcSources.myVal );
});
}
// $('#calendar').fullCalendar( 'refetchEvents' );
});
Since the sources are all the same place and just different data on the URL, this approach could meet your needs. In the demo it just alerts the URL that is being tried but doesn't actually supply any data...
https://jsfiddle.net/gzbrc2h6/1/
var tournament_url = 'https://www.example.com/'
$('#calendar').fullCalendar({
events: {
url: tournament_url + '/getCalendar/',
data: function() {
var vals = [];
// Are the [ and ] needed in the url? If not, remove them here
// This could (should!) also be set to all input[name='event_filter[]'] val's instead of hard-coded...
var filterVal = '[1,2]';
$('input[name="event_filter[]"]:checked').each(function() {
vals.push($(this).val());
});
if (vals.length) {
filterVal = '[' + vals.join(',') + ']' // Are the [ and ] needed in the url? If not, remove here too
}
return {
typefilter: filterVal
};
},
beforeSend: function(jqXHR, settings) {
alert(unescape(settings.url));
}
}
});
// when they change the checkboxes, refresh calendar
$('input[name="event_filter[]"]').on('change', function() {
$('#calendar').fullCalendar('refetchEvents');
});
Try this!
$('#calendar').fullCalendar({
events: function( start, end, timezone, callback ) {
var checked = [];
$("input[name='event_filter[]']:checked").each(function () {
checked.push( $(this).val() );
});
var tournament_url = 'https://www.example.com';
$.ajax({
url: tournament_url + '/getCalendar/',
data: {typefilter: '['+checked.join(',')+']'},
success: function(events) {
callback(events);
}
});
}
});
$('input[name="event_filter[]"]').on('change', function() {
$('#calendar').fullCalendar('refetchEvents');
});
This works for me.
How can I consume a JSON feed? The webmethod gets hit, but it throwns the error, "error while fetching events." I think its related to ASP.NET wrapping everything with "d." but I don't know how to proceed.
[WebMethod]
public string GetEvents(string webMethodParam)
{
return #"[{""title"": ""All Day Event"",""start"": ""2014-09-01""}]";
}
function createCal() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
eventSources: [{
url: "<%= AdminPath %>WebMethods/WebService1.asmx/GetEvents",
type: 'POST',
data: {
webMethodParam: 'something'
},
error: function () {
alert('there was an error while fetching events!');
}
}],
defaultDate: '2014-09-12',
editable: false,
eventLimit: true
});
}
It was related to this weird "d." wrapper. To fix it I did the following.
[WebMethod]
public void GetEvents(string webMethodParam)
{
string ret = #"[{""title"": ""All Day Event"",""start"": ""2014-09-01""}]";
this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(ret);
}
To create the calendar to async call the webmethod with the current date, I did this.
function getCalendarDisplayDate() {
try {
var now = moment().format("dddd, MMMM Do, YYYY, h:MM:ss A");
var m = moment();
var moment2 = $('#calendar').fullCalendar('getDate');
return moment2.format();
}
catch (err) {
}
return "init";
}
function createCal() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
eventSources: [{
url: "<%= AdminPath %>WebMethods/WebService1.asmx/GetEvents",
type: 'POST',
data: {
webMethodParam: getCalendarDisplayDate
},
error: function (v) {
alert('there was an error while fetching events!');
}
}],
defaultDate: '2014-09-12',
editable: false,
eventLimit: true
});
}
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>
I am integrating fullCalendar in my meteor application. fullCalendar expects a specific data format. I can create that data from my Collection. However the data is no longer reactive.
What is a way I can make the data I translated from my Collection to an Array "reactive"?
Thanks.
Client html:
<template name="carpool_calendar">
<div id="calendar"></div>
</template>
Client JS:
Template.carpool_calendar.rendered = function () {
//initialize the calendar in this template
$('#calendar').fullCalendar({
events: function(start, end, callback) {
var events = [];
var calendarEvents = Carpool_Events.find();
calendarEvents.forEach(function (carpool_event) {
events.push({
title: carpool_event.owner,
start: carpool_event.eventDate
});
console.log("Event owner " + ": " + carpool_event.owner);
});
callback(events);
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
weekends: false, // will hide Saturdays and Sundays
editable: true
});
};
Updated Client JS (This is not quite right yet. Its recreating the calendar on every data change...the page gets longer and longer with new calendar instances):
Template.carpool_calendar.rendered = function () {
Meteor.autorun(function() {
//initialize the calendar in this template
$('#calendar').fullCalendar({
events: function(start, end, callback) {
var events = [];
var calendarEvents = Carpool_Events.find();
calendarEvents.forEach(function (carpool_event) {
events.push({
title: carpool_event.owner,
start: carpool_event.eventDate
});
console.log("Event owner " + ": " + carpool_event.owner);
});
callback(events);
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
weekends: false, // will hide Saturdays and Sundays
editable: true
});
})};
Client JS Fully working "reactive" fullcalendar:
Template.carpool_calendar.rendered = function () {
//initialize the calendar in this template
$('#calendar').fullCalendar({
events: function(start, end, callback) {
var events = [];
var calendarEvents = Carpool_Events.find();
calendarEvents.forEach(function (carpool_event) {
events.push({
title: carpool_event.owner,
start: carpool_event.eventDate
});
console.log("Event owner " + ": " + carpool_event.owner);
});
callback(events);
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
weekends: false, // will hide Saturdays and Sundays
editable: true
});
Meteor.autorun(function() {
var calendarEvents = Carpool_Events.find();
$('#calendar').fullCalendar('refetchEvents');
});
};
Like TimDog said, you can't give the UI element a reactive array, and let it take care of the rest. But another option is you could use Meteor.autorun so when your collection changes, it can trigger a JS function to make an updated array, thereby making it somewhat reactive.
I'm not sure how to use this calendar exactly, but adding this into your client side code might help.
Meteor.autorun(function() {
calendarEvents = Carpool_Events.find();
$('#calendar').fullCalendar({
events: function(start, end, callback) {
var events = [];
calendarEvents.forEach(function (carpool_event) {
events.push({
title: carpool_event.owner,
start: carpool_event.eventDate
});
});
callback(events);
}
});
});
This is part of a bigger question regarding how to properly create UI components for Meteor that ensure reactive data contexts. It's a very good question and one that's been asked before.
The short answer is that there is no standardized framework yet -- like a Meteor.UI smart package. In the interim, however, your best bet is to hack the fullCalendar widget using the {{#each}} helper source as your guide. You'll want to pay attention to how data elements are labeled with Spark:
'each': function (data, options) {
var parentData = this;
if (data && data.length > 0)
return _.map(data, function(x, i) {
// infer a branch key from the data
var branch = (x._id || (typeof x === 'string' ? x : null) ||
Spark.UNIQUE_LABEL);
return Spark.labelBranch(branch, function() {
return options.fn(x);
});
}).join('');
else
return Spark.labelBranch(
'else',
function () {
return options.inverse(parentData);
});
},