Hacking Google Calendar Using jQuery

I did a pretty cool hack using jQuery yesterday. It took me a couple of hours, but I finally figured out how to make it work.

CompanionLink Task Synchronization Gone Awry

I use a product from CompanionLink Software to synchonrize my Outlook 2007 calendar with Google Calendar. I recently upgraded my version of CompanionLink for Google Calendar to CompanionLink for Google, which includes new synchronization features for Outlook Contacts and Tasks, as well as support for Google Apps.

The Outlook Task synchronization "feature" caused me a lot of grief by uploading all of my tasks (including completed ones for the past several years) into my calendar as events. In addition, any tasks that did not have a due date were added as events on the day that I first tried the sync feature. In other words, I had hundreds of tasks loaded as events for April 13th, 2008.

I was not happy. Needless to say, I immediately deactivated the task synchronization portion of the application and stuck with calendar only. Unfortunately, I was left with the task of cleaning the "task events" out of my Google Calendar. The problem is that there's no quick way to do this in Google Calendar's interface.

Google Calendar Lacks a Delete Multiple Events Feature

Google Calendar lets you search for events using the usual search box at the top of the page, then clicking "Search My Calendars." The resulting list of events is displayed with one line for each match, which can be expanded to show more details and offer a "Delete" link for the desired event. Unfortunately, there is no checkbox for each item to allow you to delete multiple events simultaneously. This seems odd for a Google app, especially since GMail allows to delete multiple messages at once.

jQuery+Firefox+Firebug Allows Deleting Multiple Events

The first step was to click my "Append jQuery" bookmarklet in my Firefox toolbar. Next, I fired up Firebug to dissect the page's HTML. After I narrowed down the target elements, I was in business.

Here are the steps I used to automate deletion of multiple events. (All code shown below was executed in the Firebug console.)

  1. Expand all "line items" in the search results to expose the "Delete" link by simulating a click on the item.
    $('a.event-title').each(function(i){
        this.onmousedown();
    });
    

    This caused each item in the list to expand, thus building and displaying the "Delete" link.

  2. For each exposed "Delete" link, simulate clicking it. Then, as each event deletion is confirmed with an AJAX modal popup, simulate clicking the "Delete" button to confirm your intent. (Note: Extra comments have been added for explanation.)
    // initialize the delay counter
    var waitTime = 1000;
    $('li.response span.delete a').each(function(i){
        // parse the delete handler code out of the "Delete" hyperlink
        var deleteScript=this.href.replace('javascript:void(','');
        deleteScript=deleteScript.substr(0, deleteScript.length-1) + ';';
        waitTime = waitTime + 2000;
        // trigger the "Delete" link for the desired event
        setTimeout(deleteScript, waitTime, 'JavaScript');
        waitTime = waitTime + 1000;
        // simulate the click of the "Delete" button in the prompt window
        setTimeout('rE(0,0);', waitTime, 'JavaScript');
    });
    
  3. Repeat the process until all the target events are deleted. A single pass will do between 20-30 events. If your search returns 200 or more, you will need to babysit the console and continue executing the code, but it sure beats clicking hundreds of delete links and confirmation popup window buttons by hand.

Notes

I encountered a few challenges during the course of the exercise. Here are some notes:

  • You must be positive that you want to delete ALL of the results from your search. Make sure you verify that your search query is returning the correct set of events before you run this code.
  • For some reason, when I used other methods of triggering a click on the modal popup confirmation, only one event deletion would be confirmed, and control would not resume in my jQuery each function loop. That's why I had to resort to a "staggered timeout" approach to force each piece of code to execute in a sequence evenly spaced out, first with the click of the Delete link, then with a fake click of the confirmation button.
  • Google Calendar will do some strange things when returning multiple results from a search.

    First, it will show only up to 200 results in the number of hits found by your query. As you delete events, the number 200 will start to decrement to reflect your action, but if you re-run the search, it will bump back up to 200 if you have more than 200 events remaining.

    Second, it will only show around 15 or so actual matching events in the list. The overflow setting on the container for list of events is set to hidden, so there's no way to scroll to see the items that extend below the visible area. I think this is a terrible design choice on Google's part. My early versions of the script included this code:

    $('div#gridcontainer').css('overflow', 'auto');
    

    Unfortunately, each event deletion caused that CSS value to be reset, so the scroll bar I added was immediately removed.

I apologize for the lack of pictures, but at the time, I was concentrating more on actually making it work than I was on writing the blog post explaining the process.

Feedback

Do you have any other ways of deleting multiple events in Google Calendar? Do you see a better way to code the "hack?" Add a comment, and let me know.

Trackback URL for this post:

http://www.jmill.net/trackback/99

Comments

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
By submitting this form, you accept the Mollom privacy policy.