apply functions for contextMenu on each event in FullCalendar.js - fullcalendar

I'm working with Fullcalendar.js and I set for each event a Simple Contextmenu that makes a specified function (change status when confirming a medical appointment). Next code sample works fine only when i have an Event in a day (eventRender):
eventRender: function(event, element) {
var originalClass = element[0].className;
element[0].className = originalClass + ' hasmenu';
$('#calendar2').contextmenu({
delegate: '.hasmenu',
menu: [{
title: 'Cambiar Estado',
cmd: 'cestado',
action: function(ui){ui.cmd = "cestado";confirmarCambioEstado(event);}
}, {
title: 'Atender Cita',
cmd: 'acita',
action: function(ui){ui.cmd = "acita";if(event.color=="#0088cc"){
actualizarEstado(3,event.id);
event.color = "yellowgreen";
calendarJ.fullCalendar('rerenderEvents');
hrefHCE.href = "HCE?idCita="+event.id;
hrefHCE.click();
}else{
advertenciaEstado();
}}
},{
title: 'Cancelar Cita',
cmd: 'ccita',
action: function(ui){ui.cmd = "ccita";event.color = "green";
confirmarCambioEstado(event);}
}, {
title: 'Eliminar Cita',
cmd: 'ecita',
action: function(ui){ui.cmd = "ecita";confirmarEliminar(event);}
}],
beforeOpen: function (event,ui) {
ui.menu.zIndex($(event.target).zIndex() + 1);
}
});
},
eventDrop: function(event, delta, revertFunc){
confirmarCambioFecha(event,revertFunc);
},
eventAfterAllRender: cambiarFuncion
});
But,only works like i want for a day. When i have two or more eventes on a same day, when in apply the functions in the contextMenu, it only makes the function with the last event of the day (if i have 3 events, the functions apply for the last event, not for the specified event i want to apply the functions)
How do i apply the same tratment for each event witouth having that issue i'm showing? i've tried to put a forEach sentence, but i don't know what i do

Related

Full Calendar v3 extending display beyond end of calendar year in List View

Good morning!
I have a list view set up in full calendar and have noticed that it will not display events beyond the end of the year. With it being now mid-December, this is a bit of a problem for me. We have several event that should be displaying in this list. When I change the view to month I have to click the next month button to get next years events, but at least with that I do sucessfully see the events in question.
Is there a way for my list view calendars to roll-over and include next year entries as I approach the end of the current year?
Here is an excerpt of what I have that effects the display of my calendar:
{url:'https://calendar.mydomain.com/services/id/38djsuw3hr-au8reh39dq/organization/1/department/13/',event_properties:{color:'#6a9b49'}},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: '',
center: '',
right: '' //view options on top-right (supported by v2.9.1 currently)
},
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
// opens events in a new window or tab
window.open(event.url,);
return false;
},
// eventDataTransform: function(rawEventData){
// return {title: rawEventData.Title
// };
// },
defaultView: $(window).width() < 765 ? 'listYear':'listYear', //carryover code from full sized calendar
nowIndicator: false, //show a marker for current time
eventLimit: 4, // allow "more" link when too many events
fixedWeekCount: false, // have blank rows on a 6 or 7 row month
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
allDayDefault: false,
noEventsMessage: "No Currently Scheduled Events"
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
All I see is my "NoEventsMessage" text when in list view. If I create a test event the occurs prior to the end of the year it shows up in list view.
Any ideas on spanning calendar end?
thanks
[Edit: I should say that the link at the top is a JSON feed, so I am not using a prefilled list of events from within my script or from within an external file]
Here is how I solved it.
I created a custom view entry for the specific default view called "list" and gave it a one year duration:
views: {
list: {
duration: { days:365 }
}
},
I reset my default view from the dynamic version I carried over from my full-sized calendar (since I am using this in a column anyway and the window width call is not needed):
From:
defaultView: $(window).width() < 765 ? 'listYear':'listYear',
To:
defaultView: 'list',
After doing those things my January entries for next year began to display in list view.
Here is what my display calls look like (If someone wants to edit this to make it look prettier and more efficient, I don't mind :).
ics_sources = [
{url:'https://calendar.mydomain.com/services/id/38djsuw3hr-au8reh39dq/organization/1/department/13/',event_properties:{color:'#6a9b49'}},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: false,
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
// opens events in a new window or tab
window.open(event.url,);
return false;
},
defaultView: 'list',
nowIndicator: false, //show a marker for current time
eventLimit: 4, // allow "more" link when too many events
fixedWeekCount: false, // have blank rows on a 6 or 7 row month
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
noEventsMessage: "No Currently Scheduled Events",
views: {
list: {
duration: { days: 365 },
}
}
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
Thanks.
[edit: removed extraneous backticks from answer.]

FullCalendar - Get Background event on dayClick

I'm currently trying to get an event (type of background) when the DayClick is trigger.
I can't use the EventClick trigger because of the background type (I don't know why but nothing happen in my case, something wrong from FullCalendar ?).
This is my code for the init :
$('#calendarRoomUnavailable').fullCalendar({
height: 'auto',
header: {
left : '',
center: 'title',
right: ''
},
defaultView: 'year',
defaultDate: getDateFilterRoomAvailable(),
lang: 'fr',
firstDay: 1,
columnFormat: 'ddd D/M',
selectable : false,
weekends: false,
navLinks : false,
events: basePath + '/agenda/datalist/room_available',
viewRender: function (view, element) {
},
eventRender: function(event,element){
if(event.rendering === "background"){
element.data(event); //store the event data inside the element
}
},
dayClick: function (date, jsEvent, view) {
console.log(jsEvent)
},
editable:false,
});
Quick look
What I want:
When I click on a day, I want the get the event(background) related to the day (I've got only one event per day in my calendar).
Currently I'm working with the eventRender + dayClick :
eventRender: function(event,element){
if(event.rendering === "background"){
element.data(event); //store the event data inside the element
}
},
dayClick: function (date, jsEvent, view) {
console.log(jsEvent)
[...]
}
With the console.log JSEvent on the DayClick, I know it get me the wrong <td> :
Img
Because, when I try to get the target <td> with the class fc-bgevent, nothing happens :
dayClick: function (date, jsEvent, view) {
console.log(jsEvent)
if (jsEvent.target.classList.contains('fc-bgevent')) {
console.log($(jsEvent.target).data());
}
If I try to go to the HTML element target getted by the jsEvent, it shows me the wrong <td> and I can't do anything with that ...
HTML Debug
Does someone know how to bypass that ?
Thanks !
Code to get one event from a date :
function getEventFromDate(date) {
var allEvents = [];
allEvents = $('#calendarRoomUnavailable').fullCalendar('clientEvents');
var event = $.grep(allEvents, function (v) {
return +v.start === +date;
});
if (event.length > 0) {
return event[0];
} else {
return null;
}
}
After the #ADyson comments, my final function look like this :
function getEventFromDate(date) {
var eventToReturn = null;
$('#calendarRoomUnavailable').fullCalendar('clientEvents', function(event) {
var event_start = formatDateYmd(new Date(date),'-');
var date_formated = formatDateYmd(new Date(event.start),'-');
if(event_start === date_formated) {
eventToReturn = event;
}
});
return eventToReturn;
}
with a small function to get a formated date without library like Moment.js or Date.js:
function formatDateYmd(value,$delimiter)
{
var year = value.getFullYear();
var month = (value.getMonth()+1) < 10 ? '0'+(value.getMonth()+1) : (value.getMonth()+1);
var day = value.getDate() < 10 ? '0'+value.getDate() : value.getDate();
return year + $delimiter +
month + $delimiter +
day;
}
I hope to find something more performant, but this one divide the execution time by two.
Keep an eye on it
Thanks again.

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();
});

How do I get the ID of an event on eventClick?

My question is pretty straightforward: I want to load a details page from the database on eventClick. So I just need to know how to access the event attributes on the click.
If my question is in any way ambiguous, please let me know and I'll clarify.
Thank you!
The eventClick function returns the original event and it will preserve the attributes you've set (unless they have the same key as something used internally).
$('#calendar').fullCalendar({
events: [
{
title: 'My Event',
start: '2010-01-01',
myId: 123
}
// other events here
],
eventClick: function(event) {
if (event.myId) {
alert(myId);
}
}
});
For version 5
Source : https://fullcalendar.io/docs/eventClick
eventClick: function(info) {
alert('Event: ' + info.event.title);
alert('Coordinates: ' + info.jsEvent.pageX + ',' + info.jsEvent.pageY);
alert('View: ' + info.view.type);
// change the border color just for fun
info.el.style.borderColor = 'red';
}
In version 5.11.3, You can do it like this.
First, you have to set id to an event
events: [
{
id: 1,
title: "All Day Event",
start: "2020-09-01",
color: '#FF0000',
},
],
Then you can access it by with event object.event.id
eventClick: function (info) {
alert('Event: ' + info.event.id);
}
You can also pass in info as a parameter to get other values from calendar
eventClick: (info)=> {
alert(info.id); //ID
var eventTitle = info.title; //TITLE
var eventVenue = info.venue; //VENUE
var eventDescription = info.description; //DESCRIPTION
}

Automatic time update

I'm showing current time on a button in Sencha-2. Time is updating but only once.
I want continuous updation
Below is my code:-
Ext.define("Stackoverflow.view.Demo", {
extend: "Ext.Container",
alias: "widget.demo",
config: {
items: [{
xtype: "toolbar",
id: 'clocktool',
docked: "bottom",
items: [
{
xtype: 'button',
itemId: "clock",
id:'clock',
text: Ext.Date.format(new Date(),'g:i:s A')
}
]
}]
},
initialize: function(){
console.log("initializing main view");
Ext.defer(this.refreshDate, 1000, this);
},
refreshDate: function() {
console.log("refreshing date");
var btn = Ext.getCmp('clock');
btn.setText(Ext.Date.format(new Date(),'g:i:s A'));
console.log("done");
}
});
Thanks in advance. Any other approach for showing the time in sencha-2 is also welcomed.
When the view that contains the button initiates, just do something like this :
Ext.defer(this.refreshDate, 1000, this);
Then juste create a function called refreshDate :
refreshDate: function() {
var btn = ... // get your button
btn.setText(Ext.Date.format(new Date(),'g:i:s A'));
Ext.defer(this.refreshDate, 1000, this);
}
Hope this helps

Resources