Hello,
I am using fullcalendar v1.5.2 (only month view ) for property booking website , its a great plugin but i stuck in few problems, I have seen similar issues on google code , but there is nothing clear really. :( . please help me to solve these problems
Here is working demo and JS Code
What i have done so far
Now here is my problems.
a) I want that only one event is allowed for a date(s).
b) Currently if user click on a day on which any booking event or special charges event is there, then it alerts that day is booked,
but after that it will show a prompt box to enter event title,
this is occured because I have used both dayClick and select methods
How do i stops further propagation if a day already have an event ?
c) suppose a day 15 january (wrapped by fc-day17 div) is booked ( I have applied a class booked for events ) and now when I go to next month and click on fc-day17 div, it also alert that day is booked whereas there is no booking
by examining the code i found that it still have the class booked for another months for the same divs
I think there is something missing during eventRender methods?
does `eventRender()` method is called only once when initialize the calendar
or each time when we go `prev` or `next` month?
d) I have changed background-color for special charges events during rendering events via json file, but when I delte that events, it does not change back the normal background and still say that day is booked.
how do I make default background of a date if I delete the events of that day??
e) how to hide all events related to previous months?
// a) and b)
// We dont need dayClick event, only select
// I think you created calender something like this
// var calendar = $('#calendar').fullCalendar({ ... })
select: function(start, end, allDay) {
//debugger;
var events = calendar.fullCalendar( 'clientEvents' );
for (var i = 0; events.length > i ; i++){
//If we have 1 day event
if((events[i].end == null && (events[i].start.getTime() >= start.getTime() && events[i].start.getTime() <= end.getTime())) ||
// If we have many days event
(events[i].end != null && ((events[i].start.getTime() >= start.getTime() && events[i].start.getTime() <= end.getTime()) ||
(events[i].end.getTime() >= start.getTime() && events[i].start.getTime() <= end.getTime()) ||
(events[i].start.getTime() <= start.getTime() && events[i].end.getTime() >= end.getTime()))
)){
alert("Realy busy!!!");
return;
}
}
// If this time is not busy, for example, we promt to enter Event Title
var title = prompt('Event Title:');
if (title) {
//............Adding event into calendar
}
calendar.fullCalendar('unselect');
},
// c) and d)
// This is invoked when we navigate throw the month callender
eventAfterRender: function(event, element, view ){
$(".booked").removeClass(".booked"); // Remove all booked class from element
var elements = $(".fc-widget-content:not(.fc-other-month)").filter(function(){
//We try to find day number witch corresponds to the event date
return (event.end == null && $(this).find(".fc-day-number").text() == event.start.getDate()) //If we have 1 day event
|| (event.end != null && $(this).find(".fc-day-number").text() >= event.start.getDate() // If we have many day event
&& $(this).find(".fc-day-number").text() <= event.end.getDate())
});
elements.addClass("booked");
// e)
// Hide all events related to previous and next months
// If we event ends in previous month or starts in next we dont show it!
if(
(event.end == null && (view.start.getMonth() != event.start.getMonth())) //If we have 1 day event
|| (event.end != null && (view.start.getMonth() > event.end.getMonth() // If we have many day event
|| view.start.getMonth() < event.start.getMonth()))
){
$(element).hide();
}
}
EDIT This construction
var elements = $(".fc-widget-content:not(.fc-other-month)").filter(function(){
//We try to find day number witch corresponds to the event date
return (event.end == null && $(this).find(".fc-day-number").text() == event.start.getDate()) //If we have 1 day event
|| (event.end != null && $(this).find(".fc-day-number").text() >= event.start.getDate() // If we have many day event
&& $(this).find(".fc-day-number").text() <= event.end.getDate())
});
meansthat we select days of current month (:not(.fc-other-month)) which satisfy the filter conditions (return true) : The days of month equal the days of events
About your code as I said you must remove dayClick event, and your select event is:
select: function (startDate, endDate, allDay, jsEvent) {
// This is my addition //
var events = calendar.fullCalendar( 'clientEvents' );
for (var i = 0; events.length > i ; i++){
//If we have 1 day event
if((events[i].endDate == null && (events[i].start.getTime() >= startDate.getTime() && events[i].start.getTime() <= endDate.getTime())) ||
// If we have many days event
(events[i].endDate != null && ((events[i].start.getTime() >= startDate.getTime() && events[i].start.getTime() <= endDate.getTime()) ||
(events[i].end.getTime() >= startDate.getTime() && events[i].start.getTime() <= endDate.getTime()) ||
(events[i].start.getTime() <= startDate.getTime() && events[i].end.getTime() >= endDate.getTime()))
)){
alert('Sorry this date is already taken');
return;
}
}
// /This is my addition //
console.dir(jsEvent);
if (liveDate > startDate) {
alert('This date has been passed');
return false;
} else {
var title = prompt('New Charges:');
if (title) {
calendar.fullCalendar('renderEvent', {
title: title,
start: startDate,
end: endDate,
allDay: allDay
}, false // make the event "unstick"
);
var startDateString = $.fullCalendar.formatDate(startDate, 'yyyy-MM-dd');
var endDateString = $.fullCalendar.formatDate(endDate, 'yyyy-MM-dd');
$.ajax({
type: 'POST',
url: './new_event.php?action=add',
data: {
startDate: startDateString,
endDate: endDateString,
eventTitle: title,
propID: propID
},
dateType: 'json',
success: function (resp) {
calendar.fullCalendar('refetchEvents');
}
});
} // end of inner if
} // end of else
calendar.fullCalendar('unselect');
},
About viewDisplay.
Its is fired every time when we go to previous or next month, and it fired after eventAfterRender. If we use eventAfterRender and go to month without events we have no effect. The free cells stay booked.
I offer analyse events of current month inviewDisplay:
function viewCalDisplay(view) {
//...................
// Your code
$(".booked").removeClass("booked"); // Remove all booked class from element
var events = view.calendar.clientEvents(function(event){
//we need only events of current month
return event.start.getMonth() == view.start.getMonth();
} );
for(i = 0; events.length > i; i++){
var event = events[i];
// We need only days of current month. We select <td> of calender table (by class .ui-widget-content)
var elements = $(".ui-widget-content:not(.fc-other-month)").filter(function(){
//We try to find day number witch corresponds to the event date
return (event.end == null && $(this).find(".fc-day-number").text() == event.start.getDate()) //If we have 1 day event
|| (event.end != null && $(this).find(".fc-day-number").text() >= event.start.getDate() // If we have many day event
&& $(this).find(".fc-day-number").text() <= event.end.getDate())
});
elements.addClass("booked"); //Only for this <td>
}
}