Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

arshaw fullcalendar : several issue

Hello,
I am using arshaw fullcalendar v1.5.2 (only month view ) for property booking website , its a great plugin but I stuck in few problem, 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

  • Fetched events data from two different json files below

    • json_events.php : this holds booking detail which is booked from front end by user; admin can not change any details of these type of events.

    • new_charges.php : this holds special charges events detail ,admin add/update delete the new charges for any future date(s) .

  • admin can view the details of any event when he click on an event

  • admin can add/edit and delete new events on calendar for future dates or range of dates, that will stored on new_charges.php

here is my issues

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?

like image 317
diEcho Avatar asked Jan 24 '12 11:01

diEcho


2 Answers

// 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> 
            }
}
like image 180
Sergey Ratnikov Avatar answered Sep 28 '22 03:09

Sergey Ratnikov


a) I want that only one event is allowed for a date(s).

Does this problem get resolved if we resolve the problem B? I mean I think you got it in the dayClick callback, right? alert('Sorry this date is already taken');

b) How do i stops further propagation if a day already have an event ?

Have you tried to return false in the callbacks? Or can't you just use eventClick callback? It's more relevant to your needs as far as I can tell.

c) does eventRender() method is called only once when initialize the calendar or each time when we go prev or next month?

The docs says:

Triggered while an event is being rendered.

So, I suppose it's called each time you go to next and previous month.

e) how to hide all events related to previous months?

I think you could just use eventRender callback to decide if that event should be rendered or not? (Returning false on this callback will prevent the event from being rendered.)

like image 29
frbry Avatar answered Sep 28 '22 02:09

frbry