简体   繁体   中英

Using fullcalendar.io with JSONP

I'm trying to add public holidays to full calendar. http://fullcalendar.io/

var actionUrl =  @Html.Raw(Json.Encode(@Url.Action("Calendar", "Lecture")));

        $('#fullcalendar').fullCalendar({
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            eventTextColor : "Black",
            eventSources: [

            {
                url: actionUrl,
                data: function() {
                    return {
                        campusIds: getCampusIds(),
                        lectureRoomIds: getLectureRoomsIds(),
                        lecturerIds: getLecturerIds(),
                        eventTypeIds: getEventTypeIds(),
                    }
                },
                error: function() {
                    alert('there was an error while fetching events!');
                },
                traditional: true
            },

            {
                url: "http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=1&year=2013&country=zaf?callback=?",
                error: function() {
                    alert('there was an error while fetching events!');
                },
            }
        ],

The first event source works and that fetches json from my mvc controller. The second source however doesn't. I understand I need to use jsonp and I think I need to map the returning data over to something that full calendar understands but I can't get this right. Please assist!

Thanks

To begin with you need to make a call with valid parameters to the url ie

http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=1&year=2013&country=eng

This would return data in the following format:

[{"date":{"day":1,"month":1,"year":2015,"dayOfWeek":4},"localName":"New Year's Day","englishName":"New Year's Day"}]

It is then a case of translating that data into the format that expects ie EventData .

This is done by iterating over the date objects returned via the json as follows but setting the properties you need (in the below demo I set the title and start):

  var items = [];
  $.each( json, function( key, val ) {
      items.push({ title : val.localName, start : val.date } );
  });

This all needs to be wrapped up in a getJson call ie

$.getJSON( "http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=3&year=2013&country=eng", function( data ) {

  $.each( data, function( key, val ) {
      items.push({ title : val.localName, start : val.date } );
  });  

});

You can the set your calendar items as follows (simplified for demo):

$('#calendar').fullCalendar({
    events: items
});

jsFiddle

 var items = []; var json = [{"date":{"day":1,"month":1,"year":2015,"dayOfWeek":4},"localName":"New Year's Day","englishName":"New Year's Day"}] $.each( json, function( key, val ) { items.push({ title : val.localName, start : val.date } ); }); $('#calendar').fullCalendar({ events: items }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.6/fullcalendar.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.6/fullcalendar.css" rel="stylesheet"/> <div id='calendar'></div> 

Revised answer

I've found a solution. The service you are using for your dates has the API documentation here . The relevant portion:

JSONP

In each operation you can use JSONP like this: Sample URL returning public holidays in Austria for January 2013: JSON_URL?action=getPublicHolidaysForMonth&month=1&year=2013&country=aut&jsonp=myfunction

So change callback to jsonp and it should work. Also, it works best with FC if you give a range instead of a month. Your ajax call should look like:

events: function (start, end, timezone, callback) {
    console.log(start.format('YYYY-MMM'));
    $.ajax({
        type: "get",
        url: 'http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForDateRange&jsonp=?',
        data: {
            country: "zaf",
            fromDate: start.format('DD-MM-YYYY'),
            toDate: end.format('DD-MM-YYYY')
        },
        dataType: 'jsonp',
        contentType: 'application/json',
        success: function (data) {
            var events = [];
            $.each(data, function (i, holiday) {
                events.push({
                    start: moment({
                        year: holiday.date.year,
                        month: holiday.date.month - 1, //momentjs uses base 0 months
                        day: holiday.date.day
                    }),
                    title: holiday.englishName,
                    allDay: true
                });
            });
            callback(events);
        }
    }).fail(function (jqXHR) {
        alert("failed to get holidays");
    });

Here is a working JSFiddle .

Old answer: (still applicable for non-jsonp servers)

If you are trying to do a cross domain json request (jsonp), the server needs to support it.

JSONP requests are wrapped in script tags and must therefore be valid JS. A literal object is not valid JS (like {a:'b'} ).

jQuery handles this by sending a callback function name parameter to the server. It looks like:

callback=jQuery21003313164389692247_1423682275577

The server must wrap the response data in this function like:

jQuery21003313164389692247_1423682275577( {id:"2",name:"me"} );

which is now valid and executable JS.

So, unless that server's API allows for JSONP requests, you cannot do cross domain requests to it. This is a security limitation of web browsers.

As an alternative, you could proxy the data through your server. Have fullcalendar make requests to your server which in turn loads data from the external source and sends it back to the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM