I want to show on the calendar, that what dates are free dates in the year. For these, i want to set a red background.
My problem is, that with this code, it gives the red background to all the dates.
I am using this in the dayRender event.
var unnep_napok =
[
"2019-01-12",
"2019-01-15"
];
$('#calendar').fullCalendar({
events: valami,
lang: 'hu',
dayClick: function(event) {
$(cell).removeClass('ui-widget-content');
$(cell).addClass('holiday');
$(this).css('background-color', 'green');
},
defaultView: 'month',
contentHeight: 'auto',
slotEventOverlap: false,
eventRender: function(eventObj, $el) {
$el.popover({
title: ' ',
content: eventObj.description,
trigger: 'hover',
placement: 'top',
container: 'body'
});
},
dayRender: function (date, cell) {
for(i = 0; i < unnep_napok.length; i++ )
{
cell.css("background-color", "red");
}
}
});
Update with compare:
dayRender: function (date, cell) {
for(i = 0; i < unnep_napok.length; i++ )
{
if(date == unnep_napok[i] )
{
cell.css("background-color", "red");
}
}
}
Update 2, formatting array elements:
dayRender: function (date, cell)
{
for(i = 0; i < unnep_napok.length; i++ )
{
var datum = unnep_napok[i].moment.format('yyyy-mm-dd');
if(date.getDate() == datum )
{
cell.css("background-color", "red");
}
}
}
Following your update, there are still some problems which could be resolved by reading the documentation (and my earlier comments) more carefully:
1) I didn't give you the literal values to use in the "format" command. Did you read the documentation fully? As you can see, the correct format would be YYYY-MM-DD (big letters not small letters).
2) unnep_napok[i].moment.format ...this is not how you create a momentJS object. I would expect your browser gave an error in the console about this.
3) But anyway 2) is not important really, because as I mentioned in my last comment, it's the date value which you need to format ... your unnep_napok values are already strings!!
4) date.getDate() .. I don't know where you got this from?? MomentJS does not document any such function.
This should work for you:
dayRender: function (date, cell)
{
for(i = 0; i < unnep_napok.length; i++ )
{
if(date.format('YYYY-MM-DD') == unnep_napok[i])
{
cell.css("background-color", "red");
}
}
}
A running example based on ADyson's answer. I have also covered popover example for a quick start.
.popover works this way $(element).popover and doesn't work using element.popover
Running example: https://jsfiddle.net/alifaraze/mr53d7nz/8/
HTML
<div id="calendar"></div>
Script
$(document).ready(function() {
var unnep_napok = [
"2019-01-23",
"2019-01-25"
];
$('#calendar').fullCalendar({
events: [{
id: 1,
title: 'Full Day Event',
start: '2019-01-02',
end: '2019-01-03',
description: 'A full day event description'
},
{
id: 2,
title: 'Whole Week Event',
start: '2019-01-06',
end: '2019-01-10',
description: 'Whole week event description'
}
// more events here
],
eventRender: function(event, element) {
$(element).popover({
title: function() {
return "<B>" + event.title + "</B>";
},
placement: 'auto',
html: true,
trigger: 'click',
animation: 'false',
content: function() {
return "<h4>"+ event.description+"</h4>"
},
container: 'body'
});
},
dayRender: function(date, cell) {
for (i = 0; i < unnep_napok.length; i++) {
if (date.format('YYYY-MM-DD') == unnep_napok[i]) {
cell.css("background-color", "red");
}
}
}
});
})
Related
I'm new in using Fullcalendar io. For example, I want to render the "Hello World" on January 1, 15, and 30 2020. How do I do that in Fullcalendar v4?
dayRender: function(dayRenderInfo) { dayRenderInfo.el.innerHTML = "<p>Hello World</p>"; }
Want to achieve something like this. Just a plain text:
You can achieve that with dayRender function.
$('#my_calendar').fullCalendar({
defaultView: 'month',
events: [{
title: 'some-event',
start: '2020-01-01 10:00',
end: '2020-01-01 19:00',
}],
dayRender: function(date, cell) {
cell.append('<div class="custom-class">Hello World</div>');
},
});
EDIT:
On version 4 it changed to an object (from their docs):
So you should compare the column date to you dates, for example:
dayRender: function(info) {
let colDate = new Date(info.date);
let myDates = [
new Date('2020-01-01'),
new Date('2020-01-15'),
new Date('2020-01-30'),
];
myDates.forEach((date) => {
if (colDate.getYear() === date.getYear() &&
colDate.getMonth() === date.getMonth() &&
colDate.getDate() === date.getDate()) {
info.el.innerText = 'hello'
}
});
}
Using fullcalendar library, I would like to display the start time for each empty cell on my calendar (empty cells are the one marked with a red cross or red dots in the below screenshot, I modified a bit the aspect of the calendar):
So my expected output is a calendar were timeslots become buttons, when you click you start the process of booking a 30 minutes appointment which would start at the written time (the green slot is an hover effect in the following screenshot):
I can't find any easy way to do it through after reading fullcalendar documentation : https://fullcalendar.io/docs
Subsidiary question, I can't find the way to change the style of the empty cell in the CSS. Can't manage to select the elements through my Chrome console.
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
columnHeaderHtml: function(date) {
if (date.getUTCDay() === 0) {
var date_day = "Lundi";
}
if (date.getUTCDay() === 1) {
var date_day = "Mardi";
}
if (date.getUTCDay() === 2) {
var date_day = "Mercredi";
}
if (date.getUTCDay() === 3) {
var date_day = "Jeudi";
}
if (date.getUTCDay() === 4) {
var date_day = "Vendredi";
}
if (date.getUTCDay() === 5) {
var date_day = "Samedi";
}
if (date.getUTCDay() === 6) {
var date_day = "Dimanche";
}
if(date.getMonth() === 0)
{
var date_month = "Jan";
}
if(date.getMonth() === 1)
{
var date_month = "Fev";
}
if(date.getMonth() === 2)
{
var date_month = "Mar";
}
if(date.getMonth() === 3)
{
var date_month = "Avr";
}
if(date.getMonth() === 4)
{
var date_month = "Mai";
}
if(date.getMonth() === 5)
{
var date_month = "Juin";
}
if(date.getMonth() === 6)
{
var date_month = "Juil";
}
if(date.getMonth() === 7)
{
var date_month = "Août";
}
if(date.getMonth() === 8)
{
var date_month = "Sept";
}
if(date.getMonth() === 9)
{
var date_month = "Oct";
}
if(date.getMonth() === 10)
{
var date_month = "Nov";
}
if(date.getMonth() === 11)
{
var date_month = "Dec";
}
var day_num = date.getDate();
return '<b>'+date_day+'</b><br><small>'+day_num+" "+date_month+"</small>";
},
plugins: [ 'interaction', 'dayGrid', 'list', 'googleCalendar','timeGrid' ],
selectable: true,
defaultView: 'timeGridFourDay',
views: {
timeGridFourDay: {
type: 'timeGrid',
duration: { days: 4 },
buttonText: '4 day'
}
},
slotLabelFormat:{
hour: 'numeric',
minute: '2-digit',
omitZeroMinute: true,
meridiem: 'short'
},
locale:'fr',
header: {
left: 'prev today',
right: 'next'
},
validRange: {
start: '2019-08-05',
end: '2019-09-05'
},
allDaySlot:false,
firstDay:1,
minTime:"08:00:00",
maxTime:"20:00:00",
displayEventTime: true, // don't show the time column in list view
// THIS KEY WON'T WORK IN PRODUCTION!!!
// To make your own Google API key, follow the directions here:
// http://fullcalendar.io/docs/google_calendar/
googleCalendarApiKey: 'AIzaSyAL9K2UqkCVfV0n81mDW0iEpOJSwcklfsY',
// US Holidays
events: 'fr.fr#holiday#group.v.calendar.google.com',
eventClick: function(arg) {
arg.jsEvent.preventDefault() // don't navigate in main tab
console.log(arg);
},
select: function(info) {
console.log(info)
},
loading: function(bool) {
},
eventSources: [
{
googleCalendarId: 'contact#vetorino.com',
className: "gcalEvent"
}],
displayEventEnd:false,
events:[
{ // this object will be "parsed" into an Event Object
start: '2019-08-05 12:30:00', // a property!
end: '2019-08-05 14:00:00', // a property! ** see important note below about 'e6d' **
overlap: true,
backgroundColor:"#F7F7F7",
textColor:"#979797",
classNames:"closed",
}],
contentHeight: "auto",
});
calendar.render();
});
So far as shown in my previous screenshot I just managed to have empty cells, the only cells where you find some information are cells containing events.
As discussed in the comments above, there is no single element in the fullCalendar HTML which represents a specific "cell" or "slot" in the timeGrid view. The grid you can see on screen is actually an illusion created by layering multiple tables on top of each other.
So to meet your requirement for a user to be able to select a 20-minute appointment in a free slot, I can see two main options. The first is what I would normally recommend, using the standard fullCalendar functionality. The second is more like what you are asking for, but I think it over-complicates things.
1) This option simply sets the calendar with a slot duration of 20 minutes, and then has code to stop the user from selecting a longer period of time (they cannot select a shorter period, due to the slotDuration setting. This means that they can click on any empty space once and it will know to create an event of the correct length in that location. The user is not allowed to select any slot where an event already exists. (P.S. I expect in reality you will need to collect more data before adding events, but for the demonstration it adds an event instantly.)
document.addEventListener("DOMContentLoaded", function() {
var Calendar = FullCalendar.Calendar;
var calendarEl = document.getElementById("calendar");
var calendar = new Calendar(calendarEl, {
plugins: ["timeGrid", "interaction"],
header: {
left: "prev,next today",
center: "title",
right: "timeGridFourDay"
},
defaultView: "timeGridFourDay",
views: {
timeGridFourDay: {
type: "timeGrid",
duration: { days: 4 },
buttonText: "4 day"
}
},
slotLabelFormat: {
hour: "numeric",
minute: "2-digit",
omitZeroMinute: true,
meridiem: "short"
},
allDaySlot: false,
firstDay: 1,
minTime: "08:00:00",
maxTime: "20:00:00",
contentHeight: "auto",
slotDuration: "00:20:00",
selectable: true,
select: function(info) {
//console.log(info);
calendar.addEvent({ "title": "Test", start: info.start, end: info.end })
calendar.unselect();
},
selectOverlap: false,
selectAllow: function(selectInfo) {
var stM = moment(selectInfo.start);
var enM = moment(selectInfo.end);
var diff = enM.diff(stM, "minutes");
console.log(diff);
if (diff > 20)
{
return false;
}
return true;
},
events: [
{ "title": "Existing event", "start": "2019-08-08 10:00", "end": "2019-08-08 10:20"},
{ "title": "Existing event", "start": "2019-08-08 13:20", "end": "2019-08-08 13:40"},
]
});
calendar.render();
});
Demo: https://codepen.io/ADyson82/pen/aeqJQg
2) This option is closer to your desired UI (from your 2nd screenshot) but is a bit more complicated to achieve. I also, personally, think it leaves your calendar looking cluttered, and making it harder to see where the free and busy slots are, but ultimately it's up to you how you want to implement it. This works by adding a second event source, containing a list of all currently free slots. These are then used to display the start time of each free slot in the centre of it. They are coloured differently from the existing events (indicating a busy slot), so that it's a bit easier to tell the difference.
Of course, this requires you to use your server-side code to calculate all the currently free slots in your database and use that information to populate the second event source. (In the demo the free slot data is static, but of course that will not work in a real application.)
document.addEventListener("DOMContentLoaded", function() {
var Calendar = FullCalendar.Calendar;
var calendarEl = document.getElementById("calendar");
var calendar = new Calendar(calendarEl, {
plugins: ["timeGrid", "interaction"],
header: {
left: "prev,next today",
center: "title",
right: "timeGridFourDay"
},
defaultView: "timeGridFourDay",
views: {
timeGridFourDay: {
type: "timeGrid",
duration: { days: 4 },
buttonText: "4 day"
}
},
slotLabelFormat: {
hour: "numeric",
minute: "2-digit",
omitZeroMinute: true,
meridiem: "short"
},
allDaySlot: false,
firstDay: 1,
minTime: "08:00:00",
maxTime: "20:00:00",
contentHeight: "auto",
slotDuration: "00:20:00",
displayEventTime: false,
eventClick: function(info) {
if (info.event.extendedProps.type == "free") {
calendar.addEvent({
title: "Test",
start: info.event.start,
end: info.event.end
});
info.event.remove(); //delete the "free slot" event
}
},
eventSources: [
{
id: "busy",
events: [
{
title: "Existing event",
start: "2019-08-08 10:00",
end: "2019-08-08 10:20"
},
{
title: "Existing event",
start: "2019-08-08 13:20",
end: "2019-08-08 13:40"
}
]
},
{
id: "free",
backgroundColor: "green",
events: [
{
title: "08:00",
start: "2019-08-08 08:00",
end: "2019-08-08 08:20",
type: "free"
},
{
title: "08:20",
start: "2019-08-08 08:20",
end: "2019-08-08 08:40",
type: "free"
},
{
title: "08:40",
start: "2019-08-08 08:40",
end: "2019-08-08 09:00",
type: "free"
},
{
title: "09:00",
start: "2019-08-08 09:00",
end: "2019-08-08 09:20",
type: "free"
},
{
title: "09:20",
start: "2019-08-08 09:20",
end: "2019-08-08 09:40",
type: "free"
},
{
title: "09:40",
start: "2019-08-08 09:40",
end: "2019-08-08 10:00",
type: "free"
},
{
title: "10:20",
start: "2019-08-08 10:20",
end: "2019-08-08 10:40",
type: "free"
},
{
title: "10:40",
start: "2019-08-08 10:40",
end: "2019-08-08 11:00",
type: "free"
},
]
}
]
});
calendar.render();
});
For this demo I only created handful of the "free" slots (because it was tedious to create them), but hopefully you can get the idea of how it would start to look with dozens of them all over the calendar. Of course again you can amend the CSS to your requirements.
Demo: https://codepen.io/ADyson82/pen/JgpNEX
(You can of course amend the CSS of this further to make it appear more like your desired look and feel.)
Addendum: Here's the OP's final version, for anyone who is interested in the end product - based on taking the above suggestions into consideration: https://codepen.io/hugo-trial/pen/rXdajv
I've got problem with my fullcalendar,but only on Mozilla Firefox browser.I want to add 2 events:
First on date 17.07 to 20.07 another on 18.07 to 22.07.
My browser in result show me first event on date 17.07 without end date and second correct result .I don't know why :/ in another browsers (chrome,opera) it's looks better.
$('.calendar').fullCalendar({
header: {
right: '',
center: '',
left: ''
},
firstDay: 1,
buttonIcons: {
prev: 'calendar__prev',
next: 'calendar__next'
},
theme: false,
selectable: true,
selectHelper: true,
editable: false,
events: [
],
viewRender: function (view) {
var calendarDate = $('.calendar').fullCalendar('getDate');
var calendarMonth = calendarDate.month();
//Set data attribute for header. This is used to switch header images using css
$('.calendar .fc-toolbar').attr('data-calendar-month', calendarMonth);
//Set title in page header
$('.content__title--calendar > h1').html(view.title);
},
eventClick: function (event, element) {
$('#edit-event input[value='+event.className+']').prop('checked', true);
$('#edit-event').modal('show');
$('.edit-event__id').val(event.id);
$('.title').val(event.title);
$('.description').val(event.description);
$('.start_date').val(event.start);
$('.stop_date').val(event.stop);
$('.user_full_name').val(event.author);
},
eventRender: function(event, element) {
startDate=event.start.toISOString().substring(0, 10);
stopDate=event.stop.substring(0, 10);
title = event.title + "<br />"+' [ '+startDate+' ]' + ' [ '+stopDate+' ] ';
element.popover({
title: title,
trigger: 'hover',
placement: 'auto',
container: 'body',
html: true
});
}
});
I've got my data from api and editing it on that function.
function getApiData(daysInMonth){
var api_url = $('input[name="apiUrl"]').val();
api_url = api_url+'/api/eventStart='+y+'-'+m+'-'+'01'+'&eventStop='+y+'-'+m+'-'+daysInMonth;
$.getJSON(api_url,function(result){
$.each(result.data,function(key,index){
bg = event_color(index.category_name)
if(index.category_name == "Holiday"){
title = index.category_name+' - '+index.user_name;
endDate=index.event_stop.substring(0, 10);
endTime=index.event_stop.substring(10, 19);
var datePlus1 = endDate.split('-');
datePlus1[2] = Number(datePlus1[2])+1;
if(datePlus1[2] > daysInMonth){
datePlus1[2] = '01';
datePlus1[1] = Number(datePlus1[1])+1;
if(datePlus1[1]<10){
end=datePlus1[0]+'-0'+datePlus1[1]+'-'+datePlus1[2];
}
else{
end=datePlus1[0]+'-'+datePlus1[1]+'-'+datePlus1[2];
}
}
else{
end=datePlus1[0]+'-'+datePlus1[1]+'-'+datePlus1[2];
}
$('.calendar').fullCalendar('renderEvent', {
id: index.id,
title: title,
start: index.event_start,
end: end,
stop: index.event_stop,
description:index.event_description,
author: index.user_full_name,
allDay: true,
className: bg,
}, true);
}
}
}
`
ok I solved the problem. Function must add '0' to value day if days < 10 becouse the date looks like this 2019-11-1 instead 2019-11-01.
Hi everyone I have events array, on click of day I want to show event details in another panel. I have array with array within array format, I am not getting how to render this to get all the details of event including sub array details on that clicked day. Please see if you can help me with this or can suggest something in it. Here is my code below.
$(window).load(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
eventRender: function(event, element, view) {
for (var i = 0; i <= event.products.length - 1; i++) {
element.append('<span>' + event.products[i].name + '<span>');
};
},
events: [{
title: 'EventName',
start: '2016-05-02',
products: [{
name: 'ProductName'
}]
}, {
title: 'Event',
start: '2016-05-03',
products: [{
name: 'ProductName1'
}, {
name: 'ProductName2'
}, {
name: 'ProductName3'
},]
}, {
title: 'EventName',
start: '2016-05-13',
products: [{
name: 'ProductName1'
}, {
name: 'ProductName2'
}]
}, {
title: 'Event',
start: '2016-05-15',
products: [{
name: 'ProductName'
}]
}, {
title: 'EventNAme',
start: '2016-05-21',
products: [{
name: 'ProductName1'
}, {
name: 'ProductName2'
}]
}, {
title: 'Event',
start: '2016-05-23',
products: [{
name: 'ProductName1'
}, {
name: 'ProductName2'
}]
}, {
title: 'Eventname',
start: '2016-05-25',
products: [{
name: 'ProductName'
}]
}, {
title: 'Event',
start: '2016-05-29',
products: [{
name: 'ProductName'
}]
}],
dayClick: function(date, allDay, jsEvent, view) {
console.log('date' + date.format('DD/MMM/YYYY') + "allDay" + allDay.title + "jsEvent" + jsEvent + "view" + view)
}
});
})
If you see I have events array and each event has products array, so whenever I click on date I want to show title, as well as product details like same name of product. Here is what I have tried so far with calendar.
So when I click on any day that has event the I want to show I dont want to show on click of events, I need whole day clickable right now according to below answer it shows only when clicked on event.
event title product_name
The code is too lengthy so I have created code pen please see if you can edit this, thank you in advance
DEMOTRIAL
Ahaa! Finally I found the solution to render events on dayClick. There is something called clientEvents object that allows us to fetch events inside any full calendar actions (say dayClick, eventClick etc) I used that fucntion to render my events, here is my working demo...
and the dayClick code which I was eagerly searching is below
dayClick: function(date, allDay, jsEvent, view) {
$('#calendar').fullCalendar('clientEvents', function(event) {
// match the event date with clicked date if true render clicked date events
if (moment(date).format('YYYY-MM-DD') == moment(event._start).format('YYYY-MM-DD')) {
// do your stuff here
console.log(event.title);
// if you have subarray i mean array within array then
console.log(event.subarray[0].yoursubarrayKey);
}
}
}
The event click is what you're looking for.
eventClick: function(calEvent, jsEvent, view) {
console.log('Event: ' + calEvent.title);
console.log('Event: ' + calEvent.products[0].name);
}
See updated codepen
This is how to loop all the products name:
for (var i = 0;i < calEvent.products.length;i++){
console.log('Event: ' + calEvent.products[i].name);
}
And to insert the properties inside the panel you do something like this:
eventClick: function(calEvent, jsEvent, view) {
// this is a little function to manipulate the dom
function insert(title, product){
var dom = $("#insert_here")
var template = '<tr><td class="o-box-name">'+product+'</td><td>'+title+'</td><td>Cancel</td></tr>'
dom.append(template);
};
// this is the loop
for (var i = 0;i < calEvent.products.length;i++){
//console.log('Event: ' + calEvent.products[i].name);
insert(calEvent.title, calEvent.products[i].name);
}
}
Another updated codepen
Click on may, 23th
$(document).ready(function(){
$('.fc-button-group').click(function() {
//write code here
});
});
I'm working in week mode and I want to limit visible time range to the earliest event on the week and the latest event on the week.
I guess the right way to solve the problem is to manually filter events that are visible in current week, find the mininum and maximum time and set them to minTime and maxTime property. The problem is that I don't see weekChanged callback (or something like that) which seems a right place to recalculate minTime and maxTime.
This was a lot more work than I expected, hope it works well enough for you. I'm basically doing what I suggested in the comments above.
Edit:
Changed code to improve performance so we don't have to wait for all of the calendar to render before finding out that we need to start all over again.
Note that to do this more effectively we would either have to implement a new callback because none of the existing ones seem to have clientEvents set already or calculate times from the events beforehand (which could get messy in case of timezones).
http://jsfiddle.net/3E8nk/555/
(function(c) {
var startedViewRender = true;
function greaterTime(first, second) {
//Assuming dates are the same year
if (first.clone().dayOfYear(0).isBefore(second.clone().dayOfYear(0)))
return second;
else
return first;
}
var calendarOptions = {
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaWeek'
},
defaultView: 'agendaWeek',
minTime: '00:00:00',
maxTime: '24:00:00',
defaultDate: '2014-06-12',
defaultTimedEventDuration: '02:00:00',
editable: true,
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'
}],
viewRender: function(view) {
startedViewRender = true;
},
eventRender: function(event, element, view) {
if (!startedViewRender)
return;
else
startedViewRender = false;
if (view.name !== 'agendaWeek') {
console.log('not agendaWeek');
return;
}
var events = c.fullCalendar('clientEvents');
if (events.length === 0) {
console.log('no events at all');
//Set to default times?
return;
}
var visibleAndNotAllDayEvents = events.filter(function(event) {
//end not necessarily defined
var endIsWithin = event.end ? event.end.isWithin(view.start, view.end) : false;
return !event.allDay && (event.start.isWithin(view.start, view.end) || endIsWithin);
});
if (visibleAndNotAllDayEvents.length === 0) {
console.log('no visible not all day events');
//Set to default times?
return;
}
var earliest = visibleAndNotAllDayEvents.reduce(function(previousValue, event) {
return greaterTime(previousValue, event.start).isSame(previousValue) ? event.start : previousValue;
}, moment('23:59:59', 'HH:mm:ss'));
var latest = visibleAndNotAllDayEvents.reduce(function(previousValue, event) {
var end = event.end ? event.end.clone() : event.start.clone().add(moment(calendarOptions.defaultTimedEventDuration, 'HH:mm:ss'));
return greaterTime(previousValue, end);
}, moment('00:00:00', 'HH:mm:ss'));
if (calendarOptions.minTime !== earliest.format('HH:mm:ss') || calendarOptions.maxTime !== latest.format('HH:mm:ss')) {
//Reinitialize the whole thing
var currentDate = c.fullCalendar('getDate');
c.fullCalendar('destroy');
c.fullCalendar($.extend(calendarOptions, {
defaultDate: currentDate,
minTime: earliest.format('HH:mm:ss'),
maxTime: latest.format('HH:mm:ss')
}));
}
}
};
c.fullCalendar(calendarOptions);
})($('#calendar'));
You can do that by using eventAfterAllRender, which is executed after all events have been rendered
eventAfterAllRender: function(view) {
var evts = $("#calendar").fullCalendar( 'clientEvents'),
minTime = moment("2014-01-01 23:59:59").format("HH:mm:ss"),
maxTime = moment("2014-01-01 00:00:00").format("HH:mm:ss"),
currentDate = view.calendar.getDate(),
currentMinTime = view.calendar.options.minTime,
currentMaxTime = view.calendar.options.maxTime;
// lets calculate minTime and maxTime based on the week events
// if this event's minTime is 'before' than the minTime, set this as the minTime
for(var i in evts) {
minTime = timeDiff(minTime, evts[i].start.format("HH:mm:ss"), true);
maxTime = timeDiff(maxTime, evts[i].end.format("HH:mm:ss"), false);
}
// If minTime or maxTime don't match, recreate fullcalendar
// This is a pain in the ass : \
// We have to destroy and apply fullcalendar so this can work.
if (minTime != currentMinTime || maxTime != currentMaxTime) {
$("#calendar").fullCalendar('destroy');
$("#calendar").fullCalendar(
$.extend(fcOpts, {
defaultDate: currentDate,
minTime: minTime,
maxTime: maxTime
})
);
}
}
You will have to have a function to calculate which time is the lattest or earliest:
function timeDiff(time1, time2, getMin) {
var d1 = new Date('2014-01-01 ' + time1),
d2 = new Date('2014-01-01 ' + time2);
if (getMin) {
return d1.getTime(d1) - d2.getTime(d2) < 0 ? time1 : time2;
} else {
return d1.getTime(d1) - d2.getTime(d2) > 0 ? time1 : time2;
}
}
See the following JsFiddle for a working example.