As is the case with most COTS products, there is a ton of cool functionality in the ALUI product. As a programmer and certified perfectionist, I am always looking at that cool functionality and thinking, "gee, if I could only tweak it to do XYZ, it would be perfect". Apparently, a lot of my clients are thinking the same thing.
Such is the case with the out-of-the-box Collaboration calendar. The calendar itself is great: it allows addition of events, tasks, month/date scrolling and it all works without a full page refresh. It would probably take me months to perfect that kind of bug-free functionality if I wrote my own. Add to that its already existing project integration features, and you've got a great portlet.
But here's the problem... the calendar limits users to projects on their My Page or those associated with a specific Community. And although it's a "feature", users have to specifically select certain projects they want displayed. There is no automatic way for me to control the Calendar's behavior or make it display one specific project.
From a usability standpoint, this is less than ideal, especially if I want to use some of the cool Collaboration EDK features to automate project use and creation. It sure would be great if I had a calendar portlet that would only display a calendar from 1 project.
Figure 1 - The My Calendar Portlet and somewhat confusing drop down.
Since I don't normally ask questions in my blog that I can't answer, the point of this post is to show you how you I managed to come up with a one project calendar, and maintain existing Collaboration functionality. As always, here is the obligatory "This is not supported" disclaimer:
This is not supported.
But I did it anyway.
Defining Our New Calendar
The way I want my "new" calendar portlet to operate is as follows:
- I pass it a Project ID as a querystring parameter via the web service URL and it displays the project I want. I can then duplicate this web service to display different projects.
- I pass it a Project ID via a session variable and it displays the project ID contained in the session variable. In this way I can have a dynamic calendar portlet that can be manipulated by other portlets on the page.
Cracking Open the Product
The tools and techniques I used to hack into the product are the same as those from my previous post regarding Publisher. As such, refer to that post for downloads and specifics.
In the case of the calendar, I simply looked at the My Calendar Web Service and then browsed to the proper JSP in the collab.war. Next, I took a look at /calendar/portlets/calendar.jsp to see how I could modify it to suit my purposes. What I came up with was the following calendar.jsp.
How It Works
As with past posts, if you just want to get this working, skip to the Installation section of the post.
If you review the source in the JSP, you will note a couple of things:
- The JSP itself looks for a querystring parameter called projectIdPrefName. If the querystring does not exist, the JSP behaves as a normal My Calendar or Community Calendar. This allows for normal collaboration operation in all cases except my custom case.
- If the querystring parameter does exist, the JSP uses the EDK to load the value stored in the Session Preference specified by the value of projectIdPrefName. In other words, the querystring parameter tells the JSP what session preference to load a project ID from. This means I could create multiple web services with different preference values, allowing me to have multiple dynamic calendars on a single page or in a single portal.
- The JSP then creates a custom request wrapper (more on this in a minute) and a brand new instance of a CalendarControl object (the piece that displays the Calendar). The first argument to the constructor is set to 0, which basically tricks the Calendar into thinking it is being displayed in Project Explorer as part of a stand-alone project (one project only).
- The rest of the JSP is the original source, except for the piece that makes AJAX postback requests, which had to be slightly modified to take into account the new Calendar type.
As I mentioned, the only other piece of custom code in this solution is the HttpRequest wrapper (called CollabRequestWrapper). The reason this is necessary is that a CalendarControl object with type 0 will only display one project, but it will read that project ID from the querystring. Thus, we must trick the control into thinking the project ID passed as a session variable is on the querystring. The CollabReqeustWrapper does just this (see source in the jar file for details).
Installation
To install, follow these instructions:
- Stop the Collaboration service.
- Replace the file /calendar/portlets/calendar.jsp with the included calendar.jsp in the $PT_HOME\ptcollab\4.2\webapp\ptcollab.war file by unzipping and rezipping it (use WinRAR, WinZip or the jar utility that comes with Java).
- Add requestwrapper.jar to the folder WEB-INF\lib in $PT_HOME\ptcollab\6.4\webapp\ptcollab.war file by unzipping and rezipping it.
- Start the Collaboration service.
At this point, normal Collaboration behavior should be unchanged. To use the customization, do the following:
- Create a copy of the My Calendar web service in portal administration.
- Rename the new web service and edit the base URL as follows:
/do/calendar?type=my&projectPrefName=<session preference name>
Where <session preference name> is a session preference that contains the project ID whose calendar should be displayed. - Add a session preference to the Web Service (Edit the Web Service, go to the Preferences section) with the name <session preference name> from step 3.
- Create a new portlet based on the updated web service.
- Set session preferences to control project display in the new portlet, as desired, or append &projID=<project ID> to the web service URL.
Finished Product
Figure 2 - The new Calendar Portlet displaying a single project.
As you can see from the above, we now have a calendar that displays only a single project without the drop down and is completely customizable via standard ALUI portal mechanisms.
Leave a comment