Reputation: 3318
I'm using fullcalendar with events retrieved by ajax
call. The URL has a dynamic parameter that is the room id because I would like to show the calendar based on room choice. I have two problems:
events
is called before the user can choose the room (room selection and calendar is loaded at the same time), so the ajax
URL is not valid because there isn't the room id
. Is it possible to avoid the first loading?
The ajax
response is in a particolar format like this:
{
"status":true,"success":true,"result":
[
{
"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00"
},
{
"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00"
}
],
"error":null
}
so I have to use only result
field but eventDataTransform
doesn't work with a JSON different from event
format. Do you know if is it possible to elaborate the response before using it for the event?(I also use status and error to show message)
This is my actual code:
var calendar = $('#calendar').fullCalendar({
selectOverlap: false,
height: 600,
defaultView: 'agendaDay',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaDay'
},
slotMinutes: 30,
minTime: '08:00:00',
maxTime: '18:00:00',
firstDay: 1,
editable: true,
weekends: false,
//this allow the click on month agenda and go to day agenda
dayClick: function(date, jsEvent, view) {
if(view.name == 'month') {
$('#calendar').fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', date);
}
},
eventDataTransform: function(eventData){
return eventData.result;
},
//load room reservation
events: {
url: '/booking/reservation/',
data: function () { // a function that returns an object
return {
idRoom: bookingForm.room,
};
}
}
});
bookingForm.room is loaded on select
event:
roomTable.off('select')
.on( 'select', function ( e, dt, type, indexes ) {
bookingForm.room = roomTable.rows( indexes ).data().toArray()[0].idRoom;
$("#calendar").fullCalendar("refetchEvents");
} );
Upvotes: 0
Views: 2286
Reputation: 3318
I resolved with Fullcalendar events as a function where I can elaborate each single event field. This is my final code
success: function(doc) {
if (doc.status && doc.success && bookingForm.room){
var events = [];
var color = [];
for (index = 0; index < doc.result.length; ++index) {
//change the color if user is the owner of event
if (doc.result[index].owner == document.getElementById('username').innerHTML)
color = '#3c8dbc';
else
color = '#FF0000';
events.push({
editable: false,
id: doc.result[index].id,
title: doc.result[index].title,
start: doc.result[index].start,
end: doc.result[index].end,
color: color,
});
}
callback(events);
}
}
instead the first call to web service has done with a roomId initialize with -1 so it return no result
Upvotes: 0
Reputation: 4472
It is possibile to avoid the first loading?
Sure, simply don't set the events
property and load the events later with addEventSource
See following example please:
var source =
[
{
title : 'event1',
start : '2017-07-01'
},
{
title : 'event2',
start : '2017-07-05',
end : '2017-07-07'
},
{
title : 'event3',
start : '2017-08-09T12:30:00',
allDay : false
}
];
$(document).ready(function() {
$("#calendar").fullCalendar();
});
$("#btnLoadEvents").click(function(){
$("#calendar").fullCalendar("addEventSource", source);
});
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.print.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.js"></script>
<button type="button" id="btnLoadEvents">Load events</button>
<div id="calendar" />
Do you know if is it possible to elaborate the response before use it for the event?
Yes, get the events from your custom ajax response:
var customAjaxResponse = {"status":true,"success":true,"result":[{"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00"},{"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00"}],"error":null};
var source = customAjaxResponse.result;
Then add the source to the calendar:
$("#calendar").fullCalendar("addEventSource", source);
See the final result:
var customAjaxResponse = {"status":true,"success":true,"result":[{"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00"},{"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00"}],"error":null};
var source = customAjaxResponse.result;
$(document).ready(function() {
$("#calendar").fullCalendar();
});
$("#btnLoadEvents").click(function(){
$("#calendar").fullCalendar("addEventSource", source);
});
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.print.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.js"></script>
<button type="button" id="btnLoadEvents">Load events</button>
<div id="calendar" />
Note: You could add events dynamically whenever you want, although other events are already present on the calendar (try to click many times on the buttons in the above example).
I hope it helps you, ciao Luca.
Updated: How to hide/show events with a specific filter:
For each single event you can check whether it's to be displayed or not, with a function on eventRender, like following:
eventRender: function (event, element, view) {
var roomId = getRoomIdFromEvent(event.id);
return $("#chkRoom" + roomId).is(':checked');
},
So, when the function returns true the event will be displayed otherwise it will be hidden.
Finally, when the filters change you have to refresh the calendar:
$(mySelector).click(function(){
$("#calendar").fullCalendar("refetchEvents");
};
See following please:
var customAjaxResponse = {"status":true,"success":true,"result":[{"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00", "room": 1},{"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00", "room": 2}],"error":null};
var source = customAjaxResponse.result;
$(document).ready(function() {
$("#calendar").fullCalendar({
eventRender: function (ev, el, v) {
console.log(ev);
var roomId = ev.room;
return $("#cmdRoom").val()==roomId;
}
});
$("#calendar").fullCalendar("addEventSource", source);
});
$("#cmdRoom").change(function(){
$("#calendar").fullCalendar("refetchEvents");
})
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.print.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.js"></script>
<select id="cmdRoom">
<option value="1">Room one</option>
<option value="2">Room two</option>
</select>
<div id="calendar" />
Upvotes: 1