I am using the FullCalendar javascript library on my web site to display a calendar for each employee side-by-side. The calendar displays the Day view so it's easy to see everyones schedule for the day.
I have all of the calendars displaying properly side-by-side (each in their own div).
My problem is, when creating a new event by clicking on the calendar, the event always gets created on the last calendar on the page instead of the actual calendar you click on. I have a feeling it has to do with closure in the select callback function.
/*
* Setup calendars for each sales person
*/
var d = $.fullCalendar.parseDate($("#requested_date").val());
//employee id numbers (each employee has own calendar)
var employees = new Array(445,123,999,444);
for(i=0;i<employees.length;i++)
{
var employeeId = employees[i];
//clear any prevoius calendar info
$('#calendar_' + employeeId).html("");
calendar[employeeId] = $('#calendar_' + employeeId).fullCalendar({
header: {
left: '',
center: '',
right: ''
},
year: d.getFullYear(),
month: d.getMonth(),
date: d.getDate(),
defaultView: 'agendaDay',
minTime: 7,
maxTime: 19,
height: 650,
editable: true,
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
calendar[employeeId].fullCalendar('renderEvent',
{
title: "This Estimate",
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
calendar[employeeId].fullCalendar('unselect');
},
events: {
url: 'calendar/'+employees[employeeId],
type: 'POST',
data: {
'personId': employees[employeeId],
'ci_csrf_token': wp_csr_value
},
error: function() {
alert('there was an error while fetching events!');
}
}
});
}
Thanks
when you select a calendar employeesId is equal to 444 so it render event on the last calendar try this:
select: function(start, end, allDay , jsEvent ,view) {
$(view.element).parent().parent().fullCalendar('renderEvent',
{
title: "This Estimate",
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
$(view.element).parent().parent().fullCalendar('unselect');
}
Related
When I set the FullCalendar to:
initialView: 'dayGridWeek',
The Events are shown with coloured dots instead of solid fill (this is what I want). However, when I set the FullCalendar to:
initialView: 'timeGridWeek',
the Events appear as solid fill. How can I correct this please (i.e., show a coloured dot to the left of each Event)?
My code is:
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
firstDay: 0, //Sunday
weekends: true, //Show the weekends
businessHours: { // days of week. an array of zero-based day of week integers (0=Sunday)
daysOfWeek: [ 1, 2, 3, 4, 5 ], // Monday - Friday
startTime: '09:00', // a start time
endTime: '17:00', // an end time
},
initialView: 'timeGridWeek',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
locale: 'en-gb',
selectable: true, // gives ability to select multiple days and then have a callback event when this occurs
buttonIcons: false, // show the prev/next text
weekNumbers: true, // show week numbers
navLinks: true, // can click day/week names to navigate views
editable: true, // can make changes and add changes
dayMaxEvents: true, // allow "more" link when too many events
displayEventTime: false, // display the start time
displayEventEnd: false, // display the end time
eventTimeFormat: {
hour: '2-digit',
minute: '2-digit',
},// display time with minutes
eventDisplay: 'auto', //Controls which preset rendering style events use. 'block' - changes an event with start and end times from a list-item to a block
eventConstraint: {
start: moment().format('YYYY-MM-DD'),/* This constrains it to today or later */
end: '2100-01-01', // hard coded goodness unfortunately
},
events: responseJson1a,//Populate Sessions/Events using JSON
I have added the following from Kibé M.C:
eventDidMount: function (info) {
//you need to get the color from "info" argument and place it on the CSS style let eventColor = info."YourEventColor"
if (info.event) {
info.el.insertAdjacentHTML("afterBegin", '<p class="largeDot" style="color:${info.borderColor}">•</p>');
}
},
I also tried:
style="color:${info.event.borderColor}"
However the dot is not picking up the 'red' from borderColor and the text drops out of the border:
Also, the 'month' and 'list' views have two dots:
You can use eventDidMount
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
...
eventDidMount: function (args: any) {
if (eventsExist) {
args.el.insertAdjacentHTML("afterBegin", "•");
}
},
UPDATE
You should only see one dot.
Send a screenshot of the two dots so I try debugging the issue
You can add CSS to define a fixed size
To have dynamic colors on the dot, you can simply do this:
eventDidMount: function (info)
//you need to get the color from "info" argument and place it on the CSS style
let eventColor = info."YourEventColor"
{ if (info.event) { info.el.insertAdjacentHTML("afterBegin", `<p style="color:${eventColor}">•</p>`);
} },
With the help of Kibe I got:
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
firstDay: 0, //Sunday
weekends: true, //Show the weekends
hiddenDays: calendarHidenDays, //non working days to hide
businessHours: { // days of week. an array of zero-based day of week integers (0=Sunday)
daysOfWeek: [ 1, 2, 3, 4, 5 ], // Monday - Friday
startTime: '09:00', // a start time
endTime: '17:00', // an end time
},
initialView: 'timeGridWeek',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
locale: 'en-gb',
selectable: true, // gives ability to select multiple days and then have a callback event when this occurs
buttonIcons: false, // show the prev/next text
weekNumbers: true, // show week numbers
navLinks: true, // can click day/week names to navigate views
editable: true, // can make changes and add changes
dayMaxEvents: true, // allow "more" link when too many events
displayEventTime: false, // display the start time
displayEventEnd: false, // display the end time
eventTimeFormat: {
hour: '2-digit',
minute: '2-digit',
},// display time with minutes
eventDisplay: 'auto', //Controls which preset rendering style events use. 'block' - changes an event with start and end times from a list-item to a block
eventConstraint: {
start: moment().format('YYYY-MM-DD'),/* This constrains it to today or later */
end: '2100-01-01', // hard coded goodness unfortunately
},
events: responseJson1a,//Populate Sessions/Events using JSON
eventDidMount: function(info) {
console.log(info.event.borderColor);
var icon = info.event.extendedProps.icon;
if (info.event.extendedProps.icon) {
if (calendar.view.type == "dayGridMonth") {
$(info.el).find('.fc-event-title').append("<i class='fa "+icon+"'></i>");
}else {
$(info.el).find('.fc-event-title').prepend("<i class='largeDot' style='color:"+info.event.borderColor+"'>•</i>").append("<i class='fa "+icon+"'></i>");
}
}else{
//
if (calendar.view.type != "dayGridMonth") {
$(info.el).find('.fc-event-title').prepend("<i class='largeDot' style='color:"+info.event.borderColor+"'>•</i>");
}
};
},
});
The variables passed back from the serverside are:
id, title, daysOfWeek, startRecur, endRecur, startTime, endTime, backgroundColor, classNames, extendedProps1, icon, setAllDay, borderColor, textColor
I'm using fullcalendar version 3.6.2 with some events.
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listWeek'
},
editable: true,
eventLimit: true, // allow "more" link when too many events
navLinks: true,
nextDayThreshold: '00:00:00', // 9am
events: [
{
title: 'Tesst tesst',
allDay: false,
start: '2017-11-12T08:00:00',
end: '2017-11-13T15:00:00'
},
{
title: 'Birthday Party',
start: '2017-11-19T10:00:00',
end: '2017-11-21T06:00:00'
},
{
title: 'All Day Event',
allDay:true,
start: TOMORROW,
end: TOMORROW
},
{
title: 'Long Event',
start: '2017-11-07T10:00:00',
end: '2017-11-10T06:00:00'
},
{
title: 'Conference',
start: '2017-11-26T10:00:00',
end: '2017-11-28T04:00:00'
},
{
title: 'Meeting',
allDay: true,
start: TODAY + 'T10:30:00',
end: TODAY + 'T12:30:00'
},
]
});
My plunk: demo
I want to make long events display in all-day event in agendaWeek/agendaDay like Allday event.
Any way to do this?
Thanks so much!
Had a similar problem, try this:
The eventDataTransform Is key here, this allows you to manipulate the data before it’s rendered on to the calendar.
In my example, because others that create events on our calendar frequently create multi-day events that then take up most of the screen in agendaDay view, I opted to reclassify these events as all day events which relocates them to the top of the view.
I’ve chosen to reclassify any event >=5 hours as an all day event.
It’s important to catch eventData.end == null as well!
Multi day events will need to be identified further as to those which need the end date redefining to midnight the following morning. This is useful where for example as multi-day event finishes at 1500hrs on the last day this will also be moved to the top as an all day event. Without this amendment the last day will be cut off. There’s some more info on this here: FullCalendar - Event spanning all day are one day too short
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: '',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'month',
editable: false,
aspectRatio: 0.77,
eventDataTransform: function (eventData) {
var dur = eventData.end - eventData.start; //total event duration
if(dur >= 18000000 || eventData.end == null){ // 5 hours
eventData.allDay = true;
//eventData.end needs ammending to 00:00:00 of the next morning
if (dur > 86400000) {
var m = moment(eventData.end);
var roundDown = m.startOf('day');
var day2 = moment(roundDown).add(1, 'days')
eventData.end = day2.toString();
}
}
return(eventData);
},
});
According to the fullCalendar documentation there are nine different views available. Five of these views have demos while the others do not. Becuase the monthly view is not responsive I am interested in having the view change into the dayList view when on mobile. The default view is currently month but when setting this to defaultView: listDay as a property of the plugin I get the following error:
spec.class is not a constructor
I am using version 2.7.2 with the correct style sheets from a CDN. I am most interested in having my calendar display similar to the calendar found at https://fullcalendar.io/docs/list_view/intro/
Here is what my code looks like to generate my calendar.
$('#calendar').fullCalendar({
defaultView: 'listDay',
eventColor: '#9ADCC6',
eventTextColor: '#000',
header: {
left: 'title',
center: '',
right: 'today prev, next',
},
displayEventEnd: true,
buttonIcons: {
prev: 'left-single-arrow',
},
eventClick: function(event, jsEvent, view){
$('.myModal3 .title').text(event.title);
$('.myModal3 .date').text(event.start.format('MMM Do YYYY # h:mm:ss a'));
$('.myModal3 .modal-body').text(event.desc);
$('.myModal3 .modal-body').append(" <a href='"+event.link+"' target='_blank'>Learn More</a>");
$('.myModal3').css('display','block');
$('.myModal3.fade').css('opacity', '1');
},
events: function(start, end, timezone, callback) {
$.ajax({
url: '/events-iu-rss/calendar.asp',
data: {
start: start.unix(),
end: end.unix()
},
success: function(doc) {
var events = [];
// e = key, a = value
$(doc).find('event').each(function(e, a) {
var time = $(a).find('start-date-time').text();
//Wed, 16 Sep 2015 10:00:00 EDT
var endTime = $(a).find('end-date-time').text();
var formatEndTime = moment(endTime).format();
var formatTime = moment(time).format();
//console.log(a);
//console.log(formatTime.substr(11));
//console.log(formatEndTime.substr(11));
html = $.parseHTML( $(a).find('description').text() );
//stripping out first 11 characters of formatTime and formatEndTime, comparing the two times, and setting allDay value based on result
if((formatTime.substr(11))==(formatEndTime.substr(11))){
events.push({
title: $(a).find('summary').text(),
link: $(a).find('event-url').text(),
start: formatTime,
end: formatEndTime,
allDay: true,
desc: $($.parseHTML( $(a).find('description').text() )).html()
});
}
else{
events.push({
title: $(a).find('summary').text(),
link: $(a).find('event-url').text(),
start: formatTime,
end: formatEndTime,
allDay: false,
desc: $($.parseHTML( $(a).find('description').text() )).html()
});
}
});
callback(events);
}
});
}
});
I am trying to add events on calendar cell click in .NET like this:
http://arshaw.com/js/fullcalendar-1.5.3/demos/selectable.html
I took the help of this post:
create event with fullcalendar when clicking on calendar (rails)
I am getting the Selected date and text on Alert , bit not able to post it on selected cell ..
I have tried same solution on jsfiddle:
http://jsfiddle.net/5o66w860/
My code:
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var events_array = [
{
title: 'Test1',
start: new Date(2012, 8, 20),
tip: 'Personal tip 1'},
{
title: 'Test2',
start: new Date(2012, 8, 21),
tip: 'Personal tip 2'}
];
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
events: events_array,
eventRender: function(event, element) {
element.attr('title', event.tip);
},
select: function(start, end, allDay) {
var title = prompt('Event Title:');
if (title) {
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
/**
* ajax call to store event in DB
*/
jQuery.post(
"event/new" // your url
, { // re-use event's data
title: title,
start: start,
end: end,
allDay: allDay
}
);
}
calendar.fullCalendar('unselect');
}
});
});
I also to remove , events array . .. but still not working
Ok , got It after some googling :
Just need to change Code on select
select: function (start, end, jsEvent, view) {
var abc = prompt('Enter Title');
var allDay = !start.hasTime && !end.hasTime;
var newEvent = new Object();
newEvent.title = abc;
newEvent.start = moment(start).format();
newEvent.allDay = false;
$('#calendar').fullCalendar('renderEvent', newEvent);
}
To better understand my question, take a look at the JSFiddle Example.
Basically there are tree kinds of unique items on the calendar that are all day events: Today, Completed, and Incomplete days. I need to figure a way to populate days that don't have anything on them (Today, or Incomplete), in this case they would be populated with "Completed". How can I figure out what these days are?
Also any way to limit the calendar to a set months range? For instance Quarter 1 would be Dec 1st to Mar 31st.
//Calendar
$(document).ready(function() {
// Figure out todays date and provide link to enter data
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
// Staff Data Calendar
$('#calendar-staff').fullCalendar({
header: {
left: '',
center: 'title',
},
businessHours: true, // display business hours
handleWindowResize: true, // responsive layout
editable: false,
events: [
// red areas where no events can be dropped
{
title: 'No Data',
start: '2015-02-03',
url: '#',
color: '#E64C65'
},
{
title: 'No Data',
start: '2015-02-17',
url: '#',
color: '#E64C65'
},
{
// Display Today
title: 'Enter Data for Today',
url: 'staffing_data_edit.html',
color: '#5E9EF3',
start: new Date(y, m, d)
}
]
});
});
You can use and apply a custom check on a event dayRender Click here for reference
Or you can use event eventAfterAllRender which call after the calendar is ready to draw. you can use a loop and check the empty days.
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2018-10-25',
navLinks: true, // can click day/week names to navigate views
selectable: false,
selectHelper: true,
select: function(start, end) {
},
dayRender: function(date, cell )
{
console.log(date);
console.log(cell);
},
eventRender: function(event, element, view) {
},
eventAfterAllRender: function(view)
{
if (view.name == "month") {
var allEvents = $('#calendar').fullCalendar('clientEvents');
for (var index in allEvents) {
var event = allEvents[index];
}
}
},
eventClick: function(event) {
return false;
},
loading: function(bool) {
//$('#loading').toggle(bool);
},
timezone: true,
editable: false,
eventLimit: true, // allow "more" link when too many events
eventLimitTex: 'More shifts',
events: eventsJson
});