« YShout, A PHP and AJAX powered shoutbox | Main | BitFontMaker, Online Bitmap Fonts editor for Win and Mac »

Howto integrate Google Calendar in your website using AJAX

One of the features I find it interesting in Google calendar is the possibility to create shared calendars, but also the availability of your calendar as XML or ICAL whatever it's a private or public one. As soon as we have XML of our calendar available I was wondering why not integrating Google calendar directly in website. For example a community that use the service to manage their events, or to display your future trips in your blog ?

http://ajax.phpmagazine.net/upload/2006/04/ajaxcalendar-thumb.png

First of all I jumped the cross-domain AJAX story since I'm reading data from Google server, I simply written a small PHP script which will read the feeds and resend it again. Then I used my old AJAX RSS Reader, Google calendar don't deliver RSS but it's just XML, it's not a big deal there is just few changes on the code the make it working.

http://ajax.phpmagazine.net/upload/2006/04/calendar1-thumb.png

So to get started I created a shared calendar that I called "AJAX Events", I have added by the was conferences and seminars but it's all happen on may 2006 and I don't know how to make feeds return a longer period. Shared or not shared, since I'm using a PHP script to read from Google calendar you can even use the Private Address which will give you access to your events feeds directly from the reader. Then just copy the url to use it in the script below eventrss.php

http://ajax.phpmagazine.net/upload/2006/04/calendar2-thumb.png

In the javascript side the only changes are in the feed parser and how to handle the elements returned in the XML document. I have added also some more changes like displaying a "no events" message when the calendar is empty.

I have tested the script with Firefox 1.5.0.2 and IE7, it should work also without problems on other browsers. Well a small XML feature and you are open to the world, just use your imagination to personalize the css and find how you can use your calendar.

You can try the AJAX Google calendar Reader online or Download it.

Bookmark this article at these sites
Comments
1

Awesome script.

Incidently, I tried using a private URL and the script just "hangs" at "Retrieving data..."

But it works fine with the public URL ... any idea why?

2

Try first to open the feed url in your browser and see if it's returning data. I noticed this too, even after trying to reset the private url, sometimes it still returning error message.

3

Mine hangs too at Requesting data, for both public and private. In index.html, it seems like I don't get any output (Javascript debugging) after the line: "var node = RSSRequestObject.responseXML.documentElement;"

However if I load my URL in directly, the browser returns an XML page that looks valid. Any thoughts?

4

Hi. I found your site on Digg.

This seems to be an awesome tutorial, which I will try out soon. Thanks.

For developers who also want to make use of Google's calendar, they released their API for it quite early:

http://code.google.com/apis/gdata/calendar.html

Enjoy! :)

5

hi;
is there any way to change time format?

like 22-04-2006 13:30

thanks;

6

Thomas you can use myDate.split('T') then trying to play with the result or with regular expression, I'm really not sure what kind of format its currently using yyyy-dd-MMThh:mm:ss0Z ?!

7

nice post, and bring back the old logo!

8

I am having the hanging problem as well (same as Joe). Did anyone get this figured out. Really cool idea btw thanks.

9

Same hanging problem as above. Don't know if this is related, but if I load the eventrss.php file directly, I get this error:
Warning: file_get_contents(http://...@group.calendar.google.com/public/basic) [function.file-get-contents]: failed to open stream: Permission denied in html/events/eventrss.php on line 7

10

When I click on the URL's, I get XML like http://www.google.com/calendar/feeds/q6lvh75vfj0vmasq95ttapmmu4@group.calendar.google.com/public/basic/7c8516ifv76kn253vifa2gg6v0?gsessionid=tYQ8cSdeTFQ

Is there anyway to go straight to the "alternative" URLs with AJAX?

11

Hey Kyhwana, to get the alternative URL, replace the current itemLink that points to id with the following:

var itemLink = items[n].getElementsByTagName('link').item(0).getAttribute('href');

Works for me! Btw, Hatem, thanks a ton for this.. its very simple to understand. I'll be using it on my own site.

12

Also, to clean up the date, you can do the following:

var atomdate = items[n].getElementsByTagName('published').item(0).firstChild.data;
var itemPubDateDay = atomdate.substr(0, 10);
var itemPubDateTime = atomdate.substr(11, 8);
}
catch (e)
{
var itemPubDateDay = '';
var itemPubDateTime = '';
}

content += itemPubDateDay+': '+itemTitle+'
';

13

Hi,

Nice Post ... will try it out soon..
thanks.

14

I have tried this and it works well but I would really like to implement the date clean up suggested by Chrissy. I have attempted to add the suggested lines but the script then does not run - help!! You will have gathered by now that I am probably out of my depth...

15

@Alan : I have updated the demo http://phpmagazine.net/demo/ajaxcalendar/ with Chrissy date suggestion. Check the code and give it a try it should work without problems.

16

Hatem

Many thanks - works perfectly.

17

Hi,

how do I get these calendar entries sorted into chronological order?

I get a list like the one shown in the snippet below.

best regards

Klaus


* [2006-04-14T07:00:00.000Z] packing up
* [2006-04-14T12:00:00.000Z] driving to Stuttgart
* [2006-04-15T07:00:00.000Z] moving Vaihingen to Plieningen
* [2006-04-17T07:00:00.000Z] (parents, car maintenance)
* [2006-04-17T17:00:00.000Z] back to Offenbach
* [2006-04-20T06:00:00.000Z] GFNW LIVE release
* [2006-04-18T06:00:00.000Z] IWebX LIVE release
* [2006-04-04T19:00:00.000Z] openbc.de@Darmstadt
* [2006-04-19T20:00:00.000Z] Badminton
* [2006-05-11T17:00:00.000Z] phpugffm.de
* [2006-04-22T18:00:00.000Z] HJ: 40. birthday
* [2006-04-16T00:00:00.000Z] (parents)
* [2006-04-14T18:00:00.000Z] Ice Age II?
* [2006-04-28T08:00:00.000Z] webdeliverytransprogress (FS)
* [2006-04-28T07:00:00.000Z] systems staff briefing (MW)
* [2006-04-26T17:00:00.000Z] YMuth visit
* [2006-05-02T06:00:00.000Z] IWebX LIVE release
* [2006-05-04T06:00:00.000Z] GFNW LIVE release
* [2006-05-10T06:00:00.000Z] dentist
* [2006-05-12T17:00:00.000Z] openbc Hanau -- genauer Ort?
* [2006-05-04T20:00:00.000Z] openbc Frankfurt

18

How do I sort? -- The below does not work:

function cmp(a, b) {
c = a.getElementsByTagName('published').item(0).firstChild.data;
d = b.getElementsByTagName('published').item(0).firstChild.data;
if (c == d) {
return 0;
}
// alert('cmp called; c = ' + c + ', d = ' + d);

return (c } // cmp

...


if (items.length == 0) {
content += '

  • No events
';
} else {
// items.sort(cmp);
Array.sort(items, cmp);

19

now,I hava change the server into java.
one javabean
one jsp
Other files has no changes!
If you want to have java version, please mail me
:))

20

this is what i use to parse the date... it's in United States format (mm/dd/yy) but anybody should be able to see how to switch it, if needed.

try
{
var year = items[n].getElementsByTagName('published').item(0).firstChild.data.substring(2,4);
var month = items[n].getElementsByTagName('published').item(0).firstChild.data.substring(5,7);
var day = items[n].getElementsByTagName('published').item(0).firstChild.data.substring(8,10);

var itemPubDate = month + '/' + day + '/' + year;
}

however, this still doesn't solve the problem of sorting it chronologically. having separate variables for the year, month, and day should be helpful though for anybody that wants to attempt it.

21

I would be interested in parsed out event text. Everything after the "Event Description:" would be great.


When: 2006-05-08 to 2006-05-09 America/Los_Angeles

Event Description:Right here

23

you can use array.sort() to sort the content. works great. here is my version of this (note that i'm using a local file as backend) :


Google Calendar Events - RSS Reader


// from > http://ajax.phpmagazine.net/2006/04/howto_integrate_google_calenda.html
// Permission denied to call method XMLHttpRequest.open > http://www.captain.at/howto-ajax-permission-denied-xmlhttprequest.php
var RSSRequestObject = false; // XMLHttpRequest Object
var RequestMethod = "none";
var url = 'file:///D:/googlecalendarbasic.xml'; // Backend url
window.setInterval("update_timer()", 1200000); // update the data every 20 mins

if (window.XMLHttpRequest) // try to create XMLHttpRequest
{
RSSRequestObject = new XMLHttpRequest();
RequestMethod = "XMLHttpRequest";
}

if (window.ActiveXObject) // if ActiveXObject use the Microsoft.XMLHTTP
{
RSSRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
RequestMethod = "ActiveXObject";
}
function ReqChange() {

// If data received correctly
if (RSSRequestObject.readyState==4) {

// if data is valid
if (RSSRequestObject.responseText.indexOf('invalid') == -1)
{
// Parsing Feeds
var node = RSSRequestObject.responseXML.documentElement;

// Get the calendar title
var title = node.getElementsByTagName('title').item(0).firstChild.data;

var channelTitle = ''+title+'';
var eventList = {};
var eventSortList = new Array()
var eventsHTML = "";

// Browse events
var items = node.getElementsByTagName('entry');
if (items.length == 0)
{
eventsHTML = '

  • No events
';
}
else
{
for (var n=items.length-1; n >= 0; n--)
{
var itemTitle = items[n].getElementsByTagName('title').item(0).firstChild.data;
var Summary = items[n].getElementsByTagName('summary').item(0).firstChild.data;
var itemLink = items[n].getElementsByTagName('id').item(0).firstChild.data;
try
{
// Date clean up suggestion by Chrissy
var atomdate = items[n].getElementsByTagName('published').item(0).firstChild.data;
var itemPubDateDay = atomdate.substr(0, 10);
var itemPubDateTime = atomdate.substr(11, 8);
}
catch (e)
{
var itemPubDateDay = '';
var itemPubDateTime = '';
}

head = itemPubDateDay+' '+itemPubDateTime+''+itemTitle+''

eventList[head] = '
  • '+head+'
  • ';
    eventSortList[n] = head;
    }
    eventSortList.sort();

    eventsHTML = '
      ';
      for (i=0;i {
      head = eventSortList[i];
      eventsHTML += eventList[head]
      }
      eventsHTML += '
    ';
    }
    // Display the result
    document.getElementById("content").innerHTML = channelTitle + eventsHTML;

    // Tell the reader the everything is done
    document.getElementById("status").innerHTML = "Done.";
    }
    else {
    // Tell the reader that there was error requesting data
    document.getElementById("status").innerHTML = "Error requesting data.";
    }

    HideShow('status');
    }
    }

    function RSSRequest() {

    // change the status to requesting data
    HideShow('status');
    document.getElementById("status").innerHTML = "Requesting data with " + RequestMethod + " from " + url;

    // Prepare the request
    RSSRequestObject.open("GET", url, true);
    // Set the onreadystatechange function
    RSSRequestObject.onreadystatechange = ReqChange;
    // Send
    RSSRequestObject.send(null);
    }

    /*
    * Timer
    */
    function update_timer() {
    RSSRequest();
    }

    function HideShow(id){
    var el = GetObject(id);
    if(el.style.display=="none")
    el.style.display='';
    else
    el.style.display='none';
    }

    function GetObject(id){
    var el = document.getElementById(id);
    return(el);
    }





    24

    Quite interesting explanation. By now I'm working on my blog, and one aspect I was wondering how to add, was the possibility of including Google Calendar.
    Now I have something new to do :-)

    25

    I am getting incorrect dates on some of these and the times are all incorrect. I'm using the code unmodified (other than providing the correct feed URL)

    26

    I figured it out. The published date/time is not necessarily the time the event occurs. It can be retrieved from the summary but that is already formatted. Is there a way to retrieve the "full" feed instead of the "basic." The full has the GData output that gives the exact datetime range. I've tried just referencing the full URL but it hangs then.

    27

    OK, I've been working on this. The full feed worked after I commented out the summary line in the original code (since there is no summary in the full feed, duh). Anyway, I'm having another problem. IE reads the GData no problem:

    var itemPubDate = items[n].getElementsByTagName('gd:when').item(0).getAttribute('startTime');

    It reads the startTime value from the full feed. However, this same code gives an error in Firefox saying
    items[n].getElementsByTagName('gd:when').item(0) has no properties

    You can verify the difference in their output by going to:
    http://ufacm.dynu.com/ajaxcalendar/
    in both IE and Firefox

    Anyone have any idea why?

    28

    To get a bit more useful link:

    var itemLink = items[n].getElementsByTagName('link')[0].getAttribute('href');

    this causes the link to be like:

    http://www.google.com/calendar/event?eid=<event-id>

    people clicking will have to be logged into google calendar and be able to view your calendar (or the entry must be public)

    29

    Hi, I'm currently experimenting with this on http://supercharged.nl/events/ajaxcalendar/

    I can't seem to make the events sort chrono, even with the example. I'd also like to reference certain strings in the "content" section of the feed. Could anyone provide me w/ more insight? Unfortunately I'm no XML buff...yet. TIA!

    30

    You may want to consider using Trumba. Our free calendars are super customizable and designed for embedding into websites.

    31

    I don't see that there was any solution to th hangin issue many people reported. I too seem to have this problem and would love to get this integrated. Any solution?

    32

    My JavaScript was rust encrusted, but I hacked away at trying to get the output in a more human readable format, and convert it form GMT time to the time zone of my calendar. Code and details are at:
    http://cogdogblog.com/2006/06/03/tinkering-ajax-calendar-date-output/

    33

    Does anybody have the sorting problem/issue fixed. Could you please post the code.

    Thanks
    Dan

    34

    This can only extract public and private data from google.I need to modify the Data(When,Where,What etc) .If any body have the knowledge about these
    with Ajax and php,send the information

    35

    The problem is more than sorting, it is a realization that the Google Calendar RSS does not use the event date/time as an RSS field- the RSS feed is used only to let you know of recent changes to the feed.

    If you want to use an event date ordered data stream, you ought to use the iCal link from the calendar, not RSS. This negates this Ajax approach; I've resorted to using some other code for WordPress- http://dev.wp-plugins.org/browser/ical-events/

    36

    Is there anyone here that would be willing to help a non-programmer get this working? I've got it working in Firefox but it doesn't render at all in IE and my code no longer validates. The site is written in XHTML. I wasn't sure where to put the script so I put it in the head tags.

    It is for a homeschool support group site that I'm in charge of building so it's not like I'll be making money off it.

    37

    With regards to the hanging that's been happening, I still haven't figured out what's going wrong in Firefox, but the code IS working in IE for me. Just thought that might be a point of interest for those who can't seem to get past "Requesting data...". You might want to see if it works in IE to make sure it's WORKING, and then go from there. I'll post more if I figure anything out.

    38

    does anyone have a sample hmtl file I can look at?

    39

    I've got working (when eventrss.php is near the root). I have added Chrissy script but I would like to filter out the past agenda items. How can I only show the current and future events and sort the data to the non-US date format (dd.mm.yyyy)?

    Thanks!

    40

    Er... no one's doing anything daft like me are they - I was also wondering why it was hanging at "Retrieving data..." until I realised that I was using the new HTML address instead of the XML one. Now it works fine. My site is now complete - Thanks!

    41

    sdtgsdg

    42

    I am trying to implement this on a website where PHP is not available and it seems PHP scripts cannot be called when the script is stored on a different server. Does anyone have a javascript replacement for the PHP server script that could be integrated into the same webpage?

    43

    I've updated this script a decent amount and I think the end result is better. I've got it running up on my site right now.

    Like others have pointed out, the key is to grab the "full" version of the gCal XML and parse it for the gd:when date/time.

    Source and demo at:
    http://www.line72.com/mark/?p=6

    44

    Excellent tutorial! Very well laid out with screenshots and numbered code. Thanks much!

    Submitted this tutorial at howtohut.com

    45

    Has anyone resolved the hanging error? I am running into the same problem. Could it be caused by who is hosting your files? I don't see many other pausible variables in the situation if everyone is using the same files and getting mixed results.

    46

    Yay i found a solution for the hanging issue. I did some checking and if you run eventrss.php and you get an error on get_contents() or whatever you most likely have an issue where you host has disabled the use of URLs with that command. The solution is to use some command i've never heard of called 'curl'.
    Replace the contents of your eventrss.php file with this and you should be gold:


    This works if you are on dreamhost i don't know about other hosts. Good luck!

    47

    Sorry, the post stripped the code even tho i escaped the

    you can dl a working version here

    48

    Thanks Skyler! Had no idea where I was going wrong this 'fix' works well.

    49

    Thanks to Hatem for a great integration solution. I did end up messing with the script for a while before finding Mark Percival's further revisions here:
    http://webchicanery.com/gcalajax/
    I HIGHLY recommend going there first if you just started reading / trying this.

    Also thanks to whoever first posted the CURL solution.

    50

    this websiteis really usefull
    thanks for taking the time to post

    51

    ive tried this and it works a treat thankyou

    52

    Hi,

    nice thought.but i do not know how can i use?.now am using offline(localhost),it's not work only show requesting data...ans have a runtime error null is null.how can i use it,and how can i store my data,how can i change it's for my private.pls help

    53

    Visitar este site contiene información interesante sobre metadatos y documentos xml/rdf para recuperacion

    http://metadatosxmlrdf.50webs.org/

    54

    great post tried it and it works great. Many Thanks

    55

    Thanks sooo much, Skyler!! I'm also on Dreamhost and was experiencing errors until you solved the problem!!!

    56

    I'm just about to use google calendar, thanks for the post.

    57

    Hi, first of all, I love your code! Thank you very much. But, as always, I have a question. Is it possible to show the events in the first five or six days? Now I'm getting a list of all the events, which is not interesting for me. I only want the events of the coming four or five days. Can you please help me with that?

    58

    My calendar dates show up as the time I edited my Google calendar.. NOT the time the event is occurring. anyone have a fix for this problem?

    59

    No, i have the same problem Travis. Hopefully there's a fix out there.

    60

    thanks for the help

    61

    Thanks sooo much, Skyler!! I'm also on Dreamhost and was experiencing errors until you solved the problem!!!

    62

    goood work . Thank you very much . i was searching from many dayz but i doesnt fnd ny article. Thiz one is really a goood one. Thanks again.
    electronic projects

    63

    Now that's just a cool thing. I love little scripts like this. It's have tools like this on a site that makes it stand out from the crowd. Thank you for sharing your script!

    64

    Thanks a for a great read, thanks for the script, I really needed something like it :)

    65

    This is indeed a very good job.
    I am having a problem. I want the events to further have links to detailed information, that too in my website, I don't want any google page.
    I tried the same code passing the xml url to id and geting the id, but it is not working plz give me a way out for this


    66

    This is interesting! In one of our test sites, I requested one of our tech people to work on this. When our boss saw the output, he was actually more than glad. Our tech people were able to include our scheduled tasks on the calendar and it was a great help to all of us.

    67

    I have downloaded the ajax code and gave my url to the denoted place.and run it locally.but its not working.only the index.html page is displayed

    my URL :http://www.ticketbozo.com/ajaxcalendar/index.html

    68

    Hello!

    Thanks for this script. It is awsome. I just have one question! Is it possible to include more than one calender in this script? It would be really usefull. I am not an expert on php und java.
    Please Help!

    Thanks

    Michel

    69

    Recently I was recommended to use your site for generating code to integrate RSS feeds on my site. However, I have a query on how to read RSS feeds from an intranet site and display them on a site on the same intranet.

    I require common username & password to login to both the intranet sites. Please provide me the code which I can use to integrate RSS feeds. Can you please help me to develop code for customized RSS reader?

    70

    Is it possible to add task on calendar?

    71

    Thanks to Skyler for the Dreamhost fix... I'm at least getting a feed now. Only problem is my three events showing all have a date of 1970-01-01T00:00:00.000Z and all it says beside it is "busy" instead of any useful calendar data.

    I'm attempting to use this on a hosted google apps domain. Could that be part of the issue?

    72

    I’m not sure that I’m completely clear on what you’re trying to accomplish. Initially you seemed to be arguing that blogging daily wasn’t necessary anymore – in other words, those of us who feel the urge to do it daily COULD relax just a bit

    73

    Thanks for the help on this! I finally got it working thanks to your tutorial. :) You're a life saver!

    Post a comment





    (Email will remain hidden)





    Please enter the security code you see here




    Related entries
    Email to a friend
    Email this article to:


    Your email address:


    Message (optional):