I have started using the fullcalendar plugin for a calendar display of mine.
The goal of the calendar is to allow the user to add events labled Accommodation or Canteen.
When my page loads, I use PHP to build an array that gets parsed to the JavaScript that displays the events.
What I would like to do is be able to display the Google Material Design icons with the matching event.
Accommodation will be the hotel icon.
Canteen will be the local dining icon.
Now in Google's documentation it shows that the icons can be applied using the following method:
<i class="material-icons">hotel</i>
However when passing events to the plugin, this does not seem to be possible.
The php where the array gets built:
$events = array();
while (!$result->eof()) {
if ($result->valueof('date_canteen_available') == 't') {
$events[] = array("title" => "Canteen", "start" => $result->valueof('date_date'));
}
if ($result->valueof('date_accommodation_available') == 't') {
$events[] = array("title" => "Accommodation", "start" => $result->valueof('date_date'));
}
Part of my javascript:
<script>
$('#calendarAccomo').fullCalendar({
header: {
},
defaultView: 'month',
editable: true,
selectable: true,
allDaySlot: false,
events: <?php echo json_encode($events) ?>,
</script>
My question is, how can I display the correct icon with each event entry?
You can do this:
$('#calendar').fullCalendar({
events: [{
title: 'Accommodation',
start: '2017-02-01',
description: 'This is a cool event'
}, {
title: 'Canteen',
start: '2017-02-02',
description: 'This is a cool event'
}],
eventRender: function(event, element, view) {
if (event.title == 'Accommodation') {
element.append('<i class="material-icons">hotel</i>');
} else {
element.append('<i class="material-icons">local_dining</i>');
}
}
});
Try the fiddle.
Related
I'm working with Full Calendar I want to create a button that take all the events from the calendar and send them to my database. But when trying to call the getEvents method referenced here from the calendar object, I cannot get it to work. The method doesn't seem to exist. I get undefined method.
Below is a snippet of the initialization of the calendar.
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
initialDate: '2020-09-12',
navLinks: true, // can click day/week names to navigate views
selectable: true,
selectMirror: true,
select: function(arg) {
var title = prompt('Event Title:');
if (title) {
calendar.addEvent({
title: title,
start: arg.start,
end: arg.end,
allDay: arg.allDay
})
}
calendar.unselect()
},
eventClick: function(arg) {
if (confirm('Are you sure you want to delete this event?')) {
arg.event.remove()
}
},
editable: true,
dayMaxEvents: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2020-09-01'
},
{
title: 'Long Event',
start: '2020-09-07',
end: '2020-09-10'
},
{
groupId: 999,
title: 'Repeating Event',
start: '2020-09-09T16:00:00'
},
{
groupId: 999,
title: 'Repeating Event',
start: '2020-09-16T16:00:00'
},
{
title: 'Conference',
start: '2020-09-11',
end: '2020-09-13'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2020-09-28'
}
]
});
calendar.render();
I use the last version of Full Calendar (v5)
When I try to create a button that will get the calendar then retrieve all the events and send it to my database I get error saying that the function doesn't exist.
Here is how I do that :
var calendar = document.getElementById("calendar");
/* I can do that since I have my calendar with the id "calendar"
And then I try use the getEvents function
*/
var events = calendar.getEvents();
/* Show undefined */
<div id="calendar"></div>
Super Important Note: I realized that the function doesn't exist since I try to apply it to the HTML element and not the FullCalendar JS object. So my question is how can I get a FullCalendar JS Object from the HTML element in order to retrieve the events that the user has saved ??
Your problem is because var calendar = document.getElementById("calendar"); fetches the HTML element into which the rest of the calendar's HTML was added by fullCalendar. It does not fetch the fullCalendar instance which was generated by new FullCalendar.Calendar when you intialised the calendar. It's the latter which exposes the functions to manipulate the calendar or get data from it.
Notice how you already use that object in your code to call fullCalendar's render function, e.g. calendar.render();.
(The HTML element object just contains standard functions found on any HTML element, not anything specific to fullCalendar.)
So in summary you need to use the calendar variable you created from the new FullCalendar... instantiation. If you need access to that outside the scope it was originally declared in (which is the callback of the DOMContentLoaded event handler), then one way round that is to make it a global variable, e.g.
var calendar; //global variable
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
calendar = new FullCalendar.Calendar(calendarEl, {
....
});
calendar.render();
});
Then somewhere else in your code, wherever you need it, you can write
var events = calendar.getEvents();
I am having some problems retrieving these from my string
here is my script, taken from the website..
events: {
url: '/CalendarManager/Findall',
method: 'GET',
extraParams: {
custom_param1: 'customerName',
custom_param2: 'description'
},
failure: function () {
alert('there was an error while fetching events!');
},
eventRender: function (event, element) {
element.qtip({
content: event.custom_param1,
content: event.custom_param2
});
}
},
UPDATE: 12/24/2020
To answer questions below.. I am using 5.3.2 version. I can use this as well and it will bring back everything but the custom parameters.
events: '/CalendarManager/Findall',
I am using Json pulling from DB - Below is the code..
public ActionResult FindAll()
{
return Json(db.GetEvents.AsEnumerable().Select(e => new
{
id = e.CompanyId,
companyName = e.CompanyName,
title = e.Title,
description = e.Description,
allDay = e.AllDay,
start = e.StartDate.ToString("yyyy-MM-ddTHH:mm:ss"),
end = e.EndDate.ToString("yyyy-MM-ddTHH:mm:ss"),
color = e.Color
}).ToList(), JsonRequestBehavior.AllowGet);
}
I changed the version I was using and that is when the extras did not show up. So I added what I thought the documentation said to use.
Adding the extra Params after the url did not work..
UPDATE:
I read through the suggested. I guess I am still not understanding or maybe not getting "Where I am supposed to put the code".
I believe I need to use eventContent. I also did use the console.log(info.event.extendedProps.companyName); Which is great, it does show up in the console window, However i need it on the calendar not in the console window. FullCalendar's examples could be a little better!
Here is what I did but still does not show on the calendar.
eventDidMount: function (info) {
var tooltip = new Tooltip(info.el, {
title: info.event.extendedProps.description,
placement: 'top',
trigger: 'hover',
container: 'body'
});
console.log(info.event.extendedProps.companyName);
},
eventSources: [{
url: '/CalendarManager/Findall',
failure: function () {
alert('there was an error while fetching events!');
},
}],
eventContent: function (arg) {
html: arg.event.extendedProps.companyName
}
I did add some stuff in there to produce just a bubble when hovered over with this info but it does not work either.
Thank You!
UPDATE: 12/27/2020 Working Code
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prevYear,prev,next,nextYear today',
center: 'title',
right: 'dayGridMonth,dayGridWeek,dayGridDay,listWeek'
},
initialView: 'dayGridMonth',
navLinks: true, // can click day/week names to navigate views
editable: true,
dayMaxEvents: true, // allow "more" link when too many events
themeSystem: 'bootstrap',
selectable: true,
selectMirror: true,
//Random default events
//events: '/CalendarManager/Findall',
eventDidMount: function (info) {
var tooltip = new Tooltip(info.el, {
title: info.event.extendedProps.description,
placement: 'top',
trigger: 'hover',
container: 'body'
});
console.log(info.event.extendedProps.companyName);
},
events: {
url: '/CalendarManager/Findall',
failure: function () {
alert('there was an error while fetching events!');
},
},
eventContent: function (arg) {
return { html: arg.event.title + '<br>' + arg.event.extendedProps.companyName + '<br>' + arg.event.extendedProps.description };
}
});
calendar.render();
Thank you for all your help!
First, let me know what kind of version of fullcalendar you are using.
fullcalendar v5.5 doesn't provide eventRender.
And extraParams is not what you want to show. It is the query params which attach after the request url, like http://example.com/CalendarManager/Findall?custom_param1=customerName&....
If you want to use extend event props then you should parse them as extendProps.
And you should use Event Render Hooks rather than eventRender if you are using the latest version.
How to fix:
Anyway, you should use function, not an object.
You can use events (as a function)
function( fetchInfo, successCallback, failureCallback ) { }
You can also use events (as a json feed)
var calendar = new Calendar(calendarEl, {
events: '/myfeed.php'
});
If you are going to use object rather than function, then you can use eventSources
And if you want to handle the success response, then use eventSourceSuccess function
Here is an example (using fullcalendar v5.5):
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'listWeek',
loading: function(bool) {
if (bool) {
$("#dashboard-calendar-column .pre-loader").show();
} else {
$("#dashboard-calendar-column .pre-loader").hide();
}
},
// get all events from the source
eventSources: [{
url: '/CalendarManager/Findall',
method: 'GET',
failure: function() {
document.getElementById('script-warning').style.display = 'block'
}
}],
// convert the response to the fullcalendar events
eventSourceSuccess: function(content, xhr) {
var events = [];
content.events.value.map(event => {
events.push({
id: event.id,
allDay: event.isAllDay,
title: event.subject,
start:event.start.dateTime,
end: event.end.dateTime,
// The followings are what you want to add as extended
custom_param1: 'customerName',
custom_param2: 'description',
// Or you could add them to the extendedProps object
extendedProps: {
custom_param1: 'customerName',
custom_param2: 'description',
description: event.bodyPreview,
...
},
// You can check fullcalendar event parsing
...
})
})
return events;
},
eventDidMount: function (arg) {
// remove dot between the event titles
$(arg.el).find('.fc-list-event-graphic').remove();
// You can select the extended props like arg.event.custom_param1 or arg.event.extendProps.custom_param1
...
},
});
calendar.render();
})
Hope this would help you.
You can use extraParams using eventSources if you are using fullcalendar v5.
eventSources: [{
url: '/CalendarManager/Findall',
method: 'POST',
extraParams: {
custom_param1: 'customerName',
custom_param2: 'description'
}
...
}]
You should use POST rather use GET, then it will work.
I am implementing FullCalendar onto my MVC web application and have the basic calendar working. I am now attempting to add adding external events which i have working apart from when the first event is first dragged on, it isnt added into the database. if the event is moved or edited it however is entered.
Is there a way to make the event entered directly into the database when initially dragged in?
This is my current code for adding external events.
addExternalEvent: true,
eventDrop: function (event) {
var data = {
EventID: event.eventID,
Subject: event.title,
Start: event.start.format('DD/MM/YYYY HH:mm A'),
End: event.end != null ? event.end.format('DD/MM/YYYY HH:mm A') : null,
Description: event.description,
ThemeColor: event.color,
IsFullDay: event.allDay,
};
SaveEvent(data);
}
$('#external-events .fc-event').each(function () {
$(this).data('event', {
title: $.trim($(this).text()),
stick: true
});
$(this).draggable({
zIndex: 999,
revert: true,
revertDuration: 0
});
});
Thanks in advance.
I'm using fullcalendar v2.3.1 and I have eventLimits set to 1, so more then 1 event will show up as a link. I click on the link and a popover shows displaying the events in it. Can I style this popover? or do I have to create my own popover and style it myself? I would like to change it's position from center of day to bottom and maybe change a few other things.
$('#fullcalendar').fullCalendar({
header: {
left: 'prev,next', //today',
center: 'title',
//right: 'month,agendaWeek,agendaDay'
right: ''
},
defaultView: 'month',
editable: true,
allDaySlot: false,
selectable: true,
slotMinutes: 15,
eventLimit: 1,
//eventLimit: true, // for all non-agenda views
//views: {
// agenda: {
// eventLimit: 2 // adjust to 6 only for agendaWeek/agendaDay
// }
//},
events: '/ManageSpaces/GetDiaryEvents/',
//eventLimitClick: function (cellInfo, jsEvent) {
// var s = cellInfo.segs;
//},
eventClick: function (calEvent, jsEvent, view) { //function (data, event, view) {
//var s = cellInfo.segs;
$("#eventDetails.collapse").collapse('toggle');
},
dayClick: function (data, event, view) {
$(this).popover({
html: true,
placement: 'bottom',
container: 'body',
title: function () {
return $("#day-popover-head").html();
},
content: function () {
return $("#day-popover-content").html();
}
});
$(this).popover('toggle');
if ($calPopOver)
$calPopOver.popover('destroy');
$calPopOver = $(this).popover('show');
}
});
Usually and that doesn't sound like it would be difficult. Unfortunately the js above doesn't tell us much as they obviously hook into the fullcalendar plugin which takes care of the html generation. You'll need to see what html it creates.
To figure this stuff out I usually use ie or firefoxe's dev tools or firebug (hit f12 when viewing the results on the site). They have element inspectors which will let you click on the generated html elements and see what css hooks are created and the styles that apply to the element from which style sheets or inline styles. Some basic familiarity with these get me through most of these kind of issues.
If you are able to extract the generated html at least for the section you're interested in or provide a link then that would help heaps.
I am trying to add a new events to the ui calendar using ui bootstrap modal box. However, its not showing on the calendar. Below I have created the function for the day click event which contains the code for the modal box:
$scope.dayClickEvent = function(date,jsEvent,view){
//open model view for adding a event title
var creatEventModalInstance = $modal.open({
templateUrl: '/js/schedule/event_modal.html',
controller: function($scope, $modalInstance){
$scope.add = function(event){
$modalInstance.close(event);
};
$scope.close = function(){
$modalInstance.dismiss('cancel');
};
}
});
Here is the code for the ui configuration for the calendar:
$scope.uiConfig = {
calendar:{
height: 450,
editable: true,
header:{
left: 'month basicWeek basicDay agendaWeek agendaDay',
center: 'title',
right: 'today prev,next'
},
dayClick: $scope.dayClickEvent
}
};
Also the code for the event source to provide ui calendar with data about the events:
$scope.eventSources = {
events: [
{
title: 'Event1',
start: '2015-01-18'
},
{
title: 'dsadas',
start: '2015-01-18'
}
// etc...
],
color: 'yellow', // an option!
textColor: 'black' // an option!
};
So, what I am doing wrong and thanks in advance.
$scope.eventSources is an array that includes one or more event source objects.
It's an extended form meant to allow you to add multiple event sources.
an Event Source Object includes the events array as well as any Event Source Options related to the events - such as text or background colours.
Therefore you must to add an object for each event source
- then you include your events array within the object - along with any options.
...in your example you put the events array directly within an $scope.eventSources object...
To correct:
- make $scope.eventSources an array ie use [square brackets]
- put the events:[] array inside an object ie within {curly brackets}
try something like this:
$scope.eventSources = [
//this is event source object #1
{
events: [ // put the array in the `events` property
{
title: 'Event1',
start: '2015-01-24'
},
{
title: 'Event2',
start: '2015-01-28'
}
],
color: 'black', // an Event Source Option!
textColor: 'yellow' // an Event Source Option!
}
];
as outlined in this answer, you can add multiple sources by referencing objects, like:
$scope.eventSources = [$scope.eventSourceObject1, $scope.eventSourceObject2, etc...],
(you can call your Event Source Objects whatever you want, as long as they're correctly constructed)
Again each event source will have to be an object that includes the events array inside.