Fullcalendar event url - add class if url contains - fullcalendar

Some of my Fullcalendar events have links. The links point to either public webpages, pdf documents or webpages which are restricted access.
I would like to add a class to format the links to add an icon, based on url string.
If the url contains:
"pdf" addclass "fc-pdf"
"restricted" addclass "fc-lock"
I assume it should be with and eventRender... but I'm having trouble find the right syntax. Can someone help me with this?
http://jsfiddle.net/lbriquet/oez9Ltym/
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'listDay,listWeek,month'
},
views: {
listDay: {
buttonText: 'list day'
},
listWeek: {
buttonText: 'list week'
}
},
defaultView: 'listDay',
defaultDate: '2016-09-12',
navLinks: true, // can click day/week names to navigate views
events: [{
title: 'Conference (website)',
start: '2016-09-11',
end: '2016-09-13',
url: "https://www.ted.com/talks"
}, {
title: 'Meeting (download document)',
start: '2016-09-12T10:30:00',
end: '2016-09-12T12:30:00',
url: "http://storage.ted.com/tedx/manuals/tedx_speaker_guide.pdf"
}, {
title: 'Lunch',
start: '2016-09-12T12:00:00'
}, {
title: 'Meeting (members only)',
start: '2016-09-12T14:30:00',
url: "http://www.dictionary.com/browse/restricted"
}, {
title: 'Happy Hour',
start: '2016-09-12T17:30:00'
}, {
title: 'Dinner',
start: '2016-09-12T20:00:00'
}],
eventRender: function eventRender(event, element, view) {
}
});

The way I got this to work was by adding a type to the events simply because I think it would be easier than dealing with regex that might not always work. So events don't need a type but they can have a type pdf, restricted or whatever else you need. In eventRender I added the following:
eventRender: function eventRender(event, element, view) {
if(typeof event.type !== 'undefined') {
if(event.type === 'pdf') {
element.addClass('fc-pdf');
} else if(event.type === 'restricted') {
element.addClass('fc-lock');
}
}
}
A check to see if the type is provided or not and then if statements for adding the class based on the type. I also had to make a small change to the css selector, changing a.fc-lock to .fc-lock a to allow it to display properly. Here is the JS Fiddle showing this.

Related

Fullcalendar V4: How to parse json received from ajax into event list

I'm trying to retrieve a list of events from an ajax call. I use the following code.
document.addEventListener("DOMContentLoaded", function()
{ var calendarEl = document.getElementById("id_d_agenda_1");
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: '2019-08-12',
editable: true,
navLinks: true, // can click day/week names to navigate views
eventLimit: true, // allow "more" link when too many events
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()
},
events: function(arg) {
$.ajax({
url: 'd.php',
dataType: 'json',
data: {
cmd:'getdata',
start:arg.startStr,
end:arg.endStr,
tz:arg.timeZone,
component:'d_agenda_1',
},
success: function(doc) {
$(doc).each(function() {
calendar.addEvent( this );
})
}
})
}
})
calendar.render();
});
While debugging my javascript I can see the rows of events appear in 'doc'. First I tried to bulk add them to the agenda, but that didn't seem to work. Now I'm adding them one-by-one, buth they still don't appear. I have checked the this variable in the debugger and it shows a single event:
title:"value", start:"2019-08-01". In fact I'm using the sample list that comes with the package. Can someone point me to the right direction in what I'm doing wrong?
other options I tried (with no luck ;-):
I tried to leave the jquery out, but with similar effect:
success: function(doc) {
doc.forEach(function(value) {
calendar.addEvent( value );
})
}
success: function(doc) {
$(doc).each(function() {
calendar.addEvent({
title:this.title,
start:this.start
});
})
Not sure if it's helpful, but I added the selectable option and tested the select option. The calendar.addevent on the select: doesn't add the event either. Since this is copied from the sample i'm quite confused now. Fun part is that if you replace the ajax part with a regular [] expression that all works well. Even the selectable options, so there's definitely something wrong with my ajax implementation, in regards to this component.
According to the DOCS you need to have a successCallback that will return the events to the calendar.
Here is the docs https://fullcalendar.io/docs/events-function
Here is a simple Demo https://codepen.io/nasser-ali-karimi/pen/gOOJrWV?editors=0010
And in short, I can say that you need to set the events like this.
events: function(info, successCallback, failureCallback) {
successCallback([
{"resourceId":"a","title":"event 1","start":"2019-11-23","end":"2019-11-25"},
{"resourceId":"b","title":"event 3","start":"2019-11-24T12:00","end":"2019-11-25T06:00"},
{"resourceId":"b","title":"event 4","start":"2019-11-24T07:30","end":"2019-11-24T09:30"},
{"resourceId":"b","title":"event 5","start":"2019-11-24T10:00","end":"2019-11-24T15:00"},
{"resourceId":"a","title":"event 2","start":"2019-11-24T09:00","end":"2019-11-24T14:00"}
])
}
you didn't mention the events data that comes from Ajax request, so I can say you need to provide the data like what said on docs.
Addition
Note: Event's date are on 11/28 and 11,29 so navigate to those dates to see the events.
Demo https://codepen.io/nasser-ali-karimi/pen/qBBGVbG?editors=0010
events: function(info, successCallback, failureCallback) {
var arrevents = [];
jQuery.get( "https://api.myjson.com/bins/16ubhe", function( data ) {
// var response = JSON.parse(data);
// $.each(response, function(k, v) {
// arrevents.push(v);
// });
arrevents = data;
successCallback(arrevents);
});
},

FullCalendar, modify calendar on eventMouseover/eventMouseout

https://fullcalendar.io
I have a need to render a background event when mousing over calendar events. Each calendar event has a datetime range associated with it that I would like to display on the calendar when the user hovers the mouse over it (and subsequently remove the background event from the calendar on eventMouseout). However, I've ran into an issue where the eventMouseover and eventMouseout events are triggered multiple times over and over when attempting to modify the fullCalendar on mouse enter/leave. I imagine this has something to do with the calendar being re-rendered when any of its events are touched adding/removing events to the calendar.
If you take a look at this codepen, open up DevTools and watch the console as you move your mouse over/out of any of the calendar events. If you move your mouse back and forth within an event you'll see the over/out events firing back to back, over and over.
What I'd like to have happen is a backgroundEvent (such as the following) to be updated with the datetime range on any given event. Then on mouseout, remove the backgroundEvent from the calendar.
// I'm only here because StackOverflow requires code to be present when a codepen link is shared.
var bgEvent = {
id: -1,
start: null,
end: null,
rendering: 'background',
backgroundColor: 'orange'
};
Instead what happens is the eventMouseover fires, renders the event, followed by the eventMouseout, which immediately removes the event.
EDIT 1:
I'm in the middle of creating a scheduling app, and the calendar events essentially represent individual tasks belonging to a greater "appointment" object. Thus, when hovering over an individual "task" I desire to display its associated "appointment" range on the calendar to assist the user in deciding whether that task can be moved to a different date/time or not.
EDIT 2:
Submitted an issue on FullCalendar's github repo. Will update with any developments from there.
CODE FROM THE ABOVE CODEPEN
HTML
<div id="calendar"></div>
CSS
body {
margin: 40px 10px;
padding: 0;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
font-size: 14px;
}
#calendar {
max-width: 900px;
margin: 0 auto;
}
JAVASCRIPT
$(function() {
var calendar = $('#calendar');
var bgEvent = {
id: -1,
start: null,
end: null,
rendering: 'background',
backgroundColor: 'orange'
};
calendar.fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listWeek'
},
eventMouseover: function (event, jsEvent, view) {
console.log('in');
bgEvent.start = event.start;
bgEvent.end = event.end;
var events = calendar.fullCalendar('clientEvents', bgEvent.id);
if (events.length) {
var e = events[0];
calendar.fullCalendar('updateEvent', e);
}
else
calendar.fullCalendar('renderEvent', bgEvent);
},
eventMouseout: function (event, jsEvent, view) {
console.log('out');
calendar.fullCalendar('removeEvents', bgEvent.id);
},
defaultDate: '2017-11-06',
editable: true,
eventLimit: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2017-11-01'
},
{
title: 'Long Event',
start: '2017-11-07',
end: '2017-11-10'
},
{
id: 999,
title: 'Repeating Event',
start: '2017-11-09T16:00:00'
},
{
id: 999,
title: 'Repeating Event',
start: '2017-11-16T16:00:00'
},
{
title: 'Conference',
start: '2017-11-05',
end: '2017-11-07'
},
{
title: 'Meeting',
start: '2017-11-06T10:30:00',
end: '2017-11-06T12:30:00'
},
{
title: 'Lunch',
start: '2017-11-06T12:00:00'
},
{
title: 'Meeting',
start: '2017-11-06T14:30:00'
},
{
title: 'Happy Hour',
start: '2017-11-06T17:30:00'
},
{
title: 'Dinner',
start: '2017-11-06T20:00:00'
},
{
title: 'Movie',
start: '2017-11-07T07:00:00'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2017-11-28'
}
]
});
});
Adam Shaw from the FullCalendar project comments that "whenever any events are rendered or rerendered, ALL events are rerendered. What you are seeing is a flash rerender of the foreground event causing a real mouseout. When #3003's optimization is made, this will be fixed."

FullCalendar - Images as events

Looking to use Full Calendar and to include images as events and draggable. In short, would love to see how this example https://fullcalendar.io/js/fullcalendar-3.0.1/demos/external-dragging.html would work with small thumbnails instead of the text "My Event 1, My Event 2" etc. And have that image show up on the calendar.
Thanks in advance.
You can add any image url to your eventObject by adding the attribute "imageurl" inside of the events definition (if you just want the image, don't specify a title):
events: [
{
title : 'event',
start : '2016-10-12',
end : '2016-10-14',
imageurl:'img/edit.png', //you can pass the image url with a variable if you wish different images for each event
.
.
.
}
After that, you add the following code in the eventRender, which will add the image icon to the event (16 width and height is a good size for a thumbnail):
eventRender: function(event, eventElement) {
if (event.imageurl) {
eventElement.find("div.fc-content").prepend("<img src='" + event.imageurl +"' width='16' height='16'>");
}
},
For further details refer to this question: Add Icon(s) in first line of an event (fullCalendar)
In version Fullcalendar 5 or newer eventRender is no longer used, instead used eventContent
Full code:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
events: [
{
title: '',
start: '2020-09-02',
image_url: 'images/demo/event-calendar-1.png',
},
{
title: '',
start: '2020-09-02',
image_url: 'images/demo/event-calendar-2.png',
},
{
title: 'Event',
start: '2020-09-17',
image_url: 'images/demo/event-calendar-1.png',
},
{
title: '',
start: '2020-09-19',
image_url: 'images/demo/event-calendar-3.png',
},
{
title: 'Hello',
start: '2020-09-28'
},
],
eventContent: function(arg) {
let arrayOfDomNodes = []
// title event
let titleEvent = document.createElement('div')
if(arg.event._def.title) {
titleEvent.innerHTML = arg.event._def.title
titleEvent.classList = "fc-event-title fc-sticky"
}
// image event
let imgEventWrap = document.createElement('div')
if(arg.event.extendedProps.image_url) {
let imgEvent = '<img src="'+arg.event.extendedProps.image_url+'" >'
imgEventWrap.classList = "fc-event-img"
imgEventWrap.innerHTML = imgEvent;
}
arrayOfDomNodes = [ titleEvent,imgEventWrap ]
return { domNodes: arrayOfDomNodes }
},
});
calendar.render();
});

Processing clicking only when show window

i am click button, when click "ENTER" on keyboard, but i am want processing clicking only when show window ('MyDesktop.Books').But when i am show window, and then close it, when i am click "ENTER", window ('MyDesktop.Books') showing again.
How to do: processing click "ENTER" on keyboard only when show window
Code:
Ext.define('MyDesktop.Books', {
extend: 'MyDesktop.BaseWindow',
id: 'books-win',
title: 'Book',
width: 700,
height: 400,
iconCls: 'small',
layout: 'fit',
items: [
{
xtype: 'bookwrap',
listeners: {
afterrender: function() {
var mapEnterNew = new Ext.KeyMap(document, {
key: 13,
fn: function(e) {
Ext.ComponentQuery.query('bookwrap button[name=createbook]')[0].getEl().dom.click();
}
});
}
}
}
],
});
I think you should either only initialize the window when it's needed for display and remove afterwards, or attach the event in field/form focus and remove it on blur.
I could give a better answer / example if I knew what xtype: "bookwrap" was.
You shouldn't really need to be using getEl().dom.click(), ExtJs can handle all your form submission needs with it's built in components, you can use use refs in your controller to get references to your buttons alot easier.
This code attaches the key event handling on render and removes it again when the window is closed/hidden:
There is also a Fiddle.
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('Books', {
extend: 'Ext.window.Window',
id: 'books-win',
title: 'Book',
width: 700,
height: 400,
iconCls: 'small',
layout: 'fit',
items: [{
xtype: 'panel',
html: 'test'
}],
listeners: {
beforehide: function() {
this.mapEnterNew.destroy();
},
afterrender: function() {
this.mapEnterNew = new Ext.KeyMap(document, {
key: 13,
fn: function(e) {
console.log(e);
Ext.ComponentQuery.query('bookwrap button[name=createbook]')[0].getEl().dom.click();
}
});
}
}
});
Ext.create('Books').show();
}
});

How to get the date when calendar rendering date cells

I've a situation where I need to get the date to attach in each event url (For event url's I'm adding the href attr using jquery) query string but after checking the docs I found both eventClick and eventRender do not returns the date of cell upon which event is showing.
I tried google for it and found tricky solutions using the eventClick callback and use page X and Y and then get the nearest element which holds the data attribute with date for the particular cell date but
eventClick:function(event,jsEvent,view){
var clickedDate = $.nearest({x: jsEvent.pageX, y: jsEvent.pageY}, '.fc-day').attr('data-date');
alert(clickedDate);
}
But this solutions fails when I've multiple event on the same date cell and more events will be shown in a popup.
Note : $.nearest is the jquery plugin to find the nearest element from given X,Y postions
Note : I'm using v2
Does this work sufficiently well for you?
http://jsfiddle.net/3E8nk/531/
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2014-06-12',
editable: true,
eventRender: function(event, element, view) {
var start = event.start.clone().startOf('day');
var end = event.end ? event.end.clone().endOf('day') : start.clone().endOf('day');
//Known bug: We get all "touching" events and not just necessarily events on the day we clicked
var events = $('#calendar').fullCalendar('clientEvents');
var touchingEvents = events.filter(function(event) {
var
eventStartWithin = event.start.isWithin(start, end),
eventEndWithin = event.end ? event.end.isWithin(start, end) : false;
return eventStartWithin || eventEndWithin;
});
console.log(touchingEvents);
},
events: [
{
title: 'All Day Event',
start: '2014-06-01'
},
{
title: 'Long Event',
start: '2014-06-07',
end: '2014-06-10'
},
{
id: 999,
title: 'Repeating Event',
start: '2014-06-09T16:00:00'
},
{
id: 999,
title: 'Repeating Event',
start: '2014-06-16T16:00:00'
},
{
title: 'Meeting',
start: '2014-06-12T10:30:00',
end: '2014-06-12T12:30:00'
},
{
title: 'Lunch',
start: '2014-06-12T12:00:00'
},
{
title: 'Birthday Party',
start: '2014-06-13T07:00:00'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2014-06-28'
}
]
});

Resources