最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Full Calendar trigger ajax call before event renders on calendar - Stack Overflow

programmeradmin0浏览0评论

I'm a bit lost where is the proper place to make this with the Full Calendar documentation and need some fiddle to point me into the right way. When my calendar loads the events, before them show up on the calendar, I need to make a ajax call into a wordpress db which should return a date of a post. Each post is an event on the calendar. Depending on the response of the database, if the post date is in future time than the current time, then the calendar should show this event in an specific color, if it is past or current time it should be another different specific color.

So basically, before each event renders on the calendar I need to trigger an ajax call for each of them and evaluate the data returned to apply them the right color for past/current events and future events.

Someone experienced with Full Calendar could point me a fiddle with an example how is this done within the Full Calendar documentation?

This is the code I went so far. I am looking to stay in the loop with the calendar refetchEvents and be able to fetch with ajax in the background data from the posts of a WordPress website to use it on the next refetchEvents trigger and so on.

$(function () {
  var date = new Date();
  var d = date.getDate();
  var m = date.getMonth();
  var y = date.getFullYear();

  var webData = null; //array() data

  $('#calendar-holder').fullCalendar({
    eventRender: function(event, element, webData) {
      var dataHoje = new Date();
      /*
        Use webData data taken with ajax on eventAfterAllRender callback option
        inside this conditional statements to draw on the event box
        colors and text values depending on the status and date of the post returned.
      */
      if (event.start < dataHoje && event.end > dataHoje) {
            element.css('background-color', '#FFB347');
            element.find('.fc-event-inner').append('<span class="fc-event-status">ON AIR</span>');
        } else if (event.start < dataHoje && event.end < dataHoje) {
            element.css('background-color', '#77DD77');
            element.find('.fc-event-inner').append('<span class="fc-event-status">Published</span>');
        } else if (event.start > dataHoje && event.end > dataHoje) {
            element.css('background-color', '#AEC6CF');
            element.find('.fc-event-inner').append('<span class="fc-event-status">Schedued</span>');
        }
    },
    eventAfterAllRender: function () {
        webData = '(AJAX CALL TO WEBSITE POSTS I THINK SHOULD GO HERE)';
        console.log(webData);
    },
    eventColor: '#378006',
    plete: function() {

    },
    defaultView: 'basicDay',
    googleCalendarApiKey: 'AIzaSyCtEQZsFtsY41kJ1Av5FftgX9kdfkHKH',
    events: {
      googleCalendarId: 'mywebsite_l84tadr5fulc7j0628g3g6oj3k@group.calendar.google'
  },
  header: {
      left: 'prev, next',
      center: 'title',
      right: 'basicDay, basicWeek, month, '
  },
  lazyFetching: true,
  timeFormat: {
            agenda: 'h:mmt',    // 5:00 - 6:30
            '': 'h:mmt'         // 7p
        },
        weekNumbers: false,
        lang: 'en',
        eventSources: [
        {
          url: Routing.generate('fullcalendar_loader'),
          type: 'POST',
                data: {
                },
                error: function() {
               }
           }
           ]
       });


});

var refreshRate;

function reloadTime() {
  refreshRate = setTimeout(reloadPage, 5000);
}

function reloadPage() {
  $("#calendar-holder").fullCalendar("refetchEvents");
  reloadTime();
}

$( document ).ready(function() {
  reloadTime();
});

I'm a bit lost where is the proper place to make this with the Full Calendar documentation and need some fiddle to point me into the right way. When my calendar loads the events, before them show up on the calendar, I need to make a ajax call into a wordpress db which should return a date of a post. Each post is an event on the calendar. Depending on the response of the database, if the post date is in future time than the current time, then the calendar should show this event in an specific color, if it is past or current time it should be another different specific color.

So basically, before each event renders on the calendar I need to trigger an ajax call for each of them and evaluate the data returned to apply them the right color for past/current events and future events.

Someone experienced with Full Calendar could point me a fiddle with an example how is this done within the Full Calendar documentation?

This is the code I went so far. I am looking to stay in the loop with the calendar refetchEvents and be able to fetch with ajax in the background data from the posts of a WordPress website to use it on the next refetchEvents trigger and so on.

$(function () {
  var date = new Date();
  var d = date.getDate();
  var m = date.getMonth();
  var y = date.getFullYear();

  var webData = null; //array() data

  $('#calendar-holder').fullCalendar({
    eventRender: function(event, element, webData) {
      var dataHoje = new Date();
      /*
        Use webData data taken with ajax on eventAfterAllRender callback option
        inside this conditional statements to draw on the event box
        colors and text values depending on the status and date of the post returned.
      */
      if (event.start < dataHoje && event.end > dataHoje) {
            element.css('background-color', '#FFB347');
            element.find('.fc-event-inner').append('<span class="fc-event-status">ON AIR</span>');
        } else if (event.start < dataHoje && event.end < dataHoje) {
            element.css('background-color', '#77DD77');
            element.find('.fc-event-inner').append('<span class="fc-event-status">Published</span>');
        } else if (event.start > dataHoje && event.end > dataHoje) {
            element.css('background-color', '#AEC6CF');
            element.find('.fc-event-inner').append('<span class="fc-event-status">Schedued</span>');
        }
    },
    eventAfterAllRender: function () {
        webData = '(AJAX CALL TO WEBSITE POSTS I THINK SHOULD GO HERE)';
        console.log(webData);
    },
    eventColor: '#378006',
    plete: function() {

    },
    defaultView: 'basicDay',
    googleCalendarApiKey: 'AIzaSyCtEQZsFtsY41kJ1Av5FftgX9kdfkHKH',
    events: {
      googleCalendarId: 'mywebsite._l84tadr5fulc7j0628g3g6oj3k@group.calendar.google.'
  },
  header: {
      left: 'prev, next',
      center: 'title',
      right: 'basicDay, basicWeek, month, '
  },
  lazyFetching: true,
  timeFormat: {
            agenda: 'h:mmt',    // 5:00 - 6:30
            '': 'h:mmt'         // 7p
        },
        weekNumbers: false,
        lang: 'en',
        eventSources: [
        {
          url: Routing.generate('fullcalendar_loader'),
          type: 'POST',
                data: {
                },
                error: function() {
               }
           }
           ]
       });


});

var refreshRate;

function reloadTime() {
  refreshRate = setTimeout(reloadPage, 5000);
}

function reloadPage() {
  $("#calendar-holder").fullCalendar("refetchEvents");
  reloadTime();
}

$( document ).ready(function() {
  reloadTime();
});
Share Improve this question edited Mar 5, 2015 at 5:08 elvismdev asked Mar 2, 2015 at 22:10 elvismdevelvismdev 1,03511 silver badges23 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4 +50

Changing the color:

The way you did it works, but the easiest way is to do it in eventDataTransform. Like so:

eventDataTransform: function(eventData){
    if(eventData.end.isBefore(moment())){            
        eventData.color = "black";
    }else{
        eventData.color = "green";
    }
    return eventData;
},

Color Demo

Check if event exists

You didn't mention exactly what to do if the database returns false, but I'll assume you don't want nonexistent events rendered.

Since the source for your events is google calendar, this is actually kind of tricky. Normally, you would use the custom events function and do two ajax calls in it (one for the events and one for checking if they are valid). But you can't do this with google cal events.

So instead we will use eventDataTransform and only display the events after we know they exist.

eventDataTransform: function(eventData){
    eventData.display = false; //Don't display until we check the server
    eventData._uid = idCounter++; //unique ID. Don't need this if they already have unique IDs
    ajaxCall(eventData); //check the server (will retroactively update the event to be displayed)
    
    if(eventData.start.isBefore(moment())){ /*...*/ } //colors
    return eventData;
},

The top of your eventRender callback should look like:

eventRender: function(event,element){
    if(!event.display){ //Render only if the event exists
        return false; //return false to stop the event from rendering.
    }
    /*...your other render code if you have any*/
}

Define your ajaxCall function outside of fullcalendar:

var ajaxCall = function(eventData){
    $.get( "ajax/test.html", function( data ) {
        setEvent(eventData._uid,data); //data should be a boolean
    });
};

var setEvent = function(id,exists){
    var fcEvent = $('#calendar').fullCalendar("clientEvents",function(event){ //get the associated event object
        if(event._uid === id){
            return true;
        }
    })[0];
    if(typeof fcEvent !== "object")$.error("Event id "+id+" doesn't exist!"); //Throw error if it doesn't exist
    
    fcEvent.display = exists; // Store the server response in the event
    $('#calendar-holder').fullCalendar("updateEvent",fcEvent); // Updates and re-renders the event
}

JSFiddle Demo (using fake ajax calls)

Some Explanation

Couple of things that might be useful to know:

  • The word render in fullcalendar refers to actually displaying the events. It's done whenever the view changes (more often than events are fetched from the DB)
  • Event sources only fetch events when they are needed. They are stored client-side as data that can be rendered as needed.
  • eventDataTransform is called once after an event source retrieves an event.

So if you put your ajax call in eventAfterAllRender, the ajax call would be done everytime FC decided to render the calendar resulting in more ajax calls that necessary. It also means you would get a delay every time you change the view. It's much better to do it earlier than render-time.

发布评论

评论列表(0)

  1. 暂无评论