Nov 052007

The Dojo Toolkit 1.0 was released this morning. Many of us, including me, has waited patiently for this release. Now I can finalize the updated code for Dojo Calendar.

There are many new, improved and awesome features.

New and Awesome:

  • The Grid. This is the feature everyone’s been waiting for, and now it’s here! With support for virtual scrolling to accommodate huge data sets efficiently, built-in sorting and column resize to help you find what you’re looking for, complex formatting, and fixed rows and column headers, the new Grid lets you slice-and-dice your data as never
    before. The 1.0 grid features a Tundra theme, editing and write-back examples, support for custom cell editors (including the full set of accessible and localized Dijit editing components), and markup-driven instantiation.
  • Charting returns! The new dojox.charting supports automatic axis calculations, widget-driven instantiation, multiple chart types, data sources, and theming. Good-looking, data-oriented default themes help make your data understandable and easy on the eyes at the same time. And since dojox.charting is based on dojox.gfx, the general-purpose 2D drawing layer in Dojo, charting will only get more powerful, responsive, and good looking over time.
  • a11y and i18n: rich experiences for everyone. All Dijit 1.0 widgets feature keyboard navigation, right-to-left text detection and layout, and solid localizations for 12 languages. No matter where in the world you are, Dijit has you covered. Dijit goes even further by providing ARIA role and state hinting to give users of assistive technologies the experience that developers intend.
  • Universal data access. and the growing list of data store implementations makes building and using data-driven widgets simpler and faster.
  • dojox.gfx3d. Beautiful, portable 2D drawing is what dojox.gfx has always been about, and we’re taking it further with the ability to draw 3D scenes. 3D charting is based on gfx3d. This module was developed as a Summer of Code project by Kun Xi.
  • improved widget look-and-feel. The base Tundra theme continues to be improved. New and exciting extension (dojox) widgets are appearing in 1.0, including a new Lightbox widget.
  • Django templating for widgets. Many people have fallen in love with Django’s templating syntax and now you can now use it to build widgets thanks to Neil Roberts’ excellent dojox.dtl package.
  • improved stability, speed, and compatibility across the board.


  • Dijit form widgets obey width in a way that makes visual sense
  • reworked validation indicators for form elements
  • lightbox widget
  • the widget lifecycle has been improved such that create() is now called from postfix(), allowing your constructor code to “get in on the ground floor”
  • the new Drupal front-end for the Neil’s documentation parser is now checked into the util namespace. This version provides disambiguated summaries and detail pages of the parsed object hierarchy, and since these pages are in Drupal, comments can be left by anyone.
  • better command-line functioning of the unit test system
  • an improved Firebug Lite which allows inspection of errors, popup-window placement, and parent-child cross frame logging.
  • smoother animations
  • build system now handles UTF-8 correctly end-to-end
  • improved documentation and unit test coverage for all Core and Dijit APIs/widgets

Congratulations to the Dojo team for this milestone. I know it’s been a lot of hard work.

Sep 282007

Troy & Viktor at g33k in Stockholm, SwedenTroy Reimer and I spoke for a couple of hours in front of 30 or so geeks Tuesday night in Stockholm, Sweden. Ekakan sponsored the event and Troy and I had a great time. We spoke about the Lotus Quickr Templates, you can download them here, and about workflow lotusscript, JSON and the Dojo Toolkit. It was great to see some familiar faces from past years when I was working in Sweden but also several from Lotusphere.

Viktor and Troy at Icebar, StockholmBefore the event they took us to Icebar Stockholm. They made an entire bar in ice from the northern part of Sweden. That’s right, they ship the ice down and build the walls, bar and seats out of pure ice.

The pictures are taken by Joachim Dagerot who also together with Niklas Waller has blogged about the event.

Jul 172007

It’s been nearly four months since IBM said “go” on the Lotus Quickr template project that you’ve read so much about on my and other blogs. Today, after an exhausting but very rewarding development cycle, we get to say “go” too. Code was complete June 29 (as promised to IBM), testing on Lotus Quickr Gold code was July 2-6, last week was CU and finishing the download system, and this weekend we put the final touches on and did a limited test with IBMers. Then yesterday we knocked out one last bug in the download system after flying to London for Collaboration University this week.

In these last months I and the team at SNAPPS had a lot of fun developing these templates. I learned new code and got to dig really deep into the Dojo Toolkit which, you know by now, I really like.

So after all that we’re happy to announce that the SNAPPS templates for Lotus Quickr are ready for you. Make absolutely sure you get the documentation, read it, and install and sign the prerequisite files. Then go have some fun!

I will continue posting on developing and digging deeper into both Lotus Quickr as well as the Dojo Toolkit code.

Jul 052007

Rob Novak’s and my session, BP311: The Great Code Giveaway – Web 2.0 Edition, at Lotusphere 2007 is added as one of the 14 (so far) podcasts that IBM put up on the DeveloperWorks website. The podcast is a recording of the session and a transcript of it is also available, even though they did spell my name wrong in there. Click here to listen or read. You can also go download the session materials and code.

Jul 032007

For the ninth demo, QContacts, we are getting into some eye candy and heavy Dojo work. I showed you a preview of it in my post Embedded Domino forms with Ajax submit and JSON view refresh a couple of days back. From Rob Novak’s blog:

Contacts? Why would you need that when you have a member list? Good question, easy answer. You need more information than the member record can supply, or the project contact isn’t a member of the place, or you need to share role-specific information about this contact with the team. There’s nothing more frustrating than having an out-of-date, incomplete, or low-confidence contact list. QContacts help to solve these problems, centralizing contact information while automating much of the work involved in maintaining it.

The use case is simple. You’re running a project using Lotus Quickr, and you want to maintain a contact list with more comprehensive information than is available in the member list (which is, in fact, mostly for authorization). You also don’t want to re-enter information from the member list, and it makes no sense to duplicate information available about a contact that may be a member of another place, or not a member of a place at all. QContacts consists of a single form for the Lotus Quickr place, and a Domino database to coordinate, automate, and consolidate contact data. It lets you add information about people that can be shared across places including all pertinent addressing information, personal contact information, a photo, and place-specific comments that are kept in context even if the contact is a member of multiple contact lists.

Take a look at the QContacts demo.

Jul 032007

The Dojo Toolkit has released the brand new Dojo 0.9 in beta. Very exciting! This is a brand new Dojo that is much faster than the 0.4 release, easier to customize the branding and with great accessibility (a11y).

SPEED: Stripped of all ‘excessive’, redundant, and backwards-compatible code, the new Dojo core is a speed-demon. It consists of a streamlined, compact Base (aka: dojo.js) which provides a plethora of reliable features for you and your application to expand upon. Our goal was to keep the new Base under 50K on disk and we’re happy to say that even with the many improvements to it since M2, Dojo Base still clocks in under the wire and gzipped it’s even smaller: 24K. The base of the new widget system (dijit.js) is even lighter, weighing in at 21K on disk and 11K on the wire.

You can download it here.

Jun 292007

In today’s three part tutorial I’m first going to show you how to create a sign in form directly on a Domino page. Secondly, I’m going to show how you can embed a Domino form, with security, directly into a floating pane and submit it using Ajax. Last I’m showing you some code how to display a Domino view on the page using JSON and give you some of the code we at SNAPPS used for the Lotus Quickr templates we developed, free for you to download.

I have also created a short Flash preview of what I’m going to show today. It’s a good idea to view that first to get an idea of what I’m trying to explain.


To get this to work there are a few things that are required and you need a basic to medium skill-set of how JavaScript works inside Domino.

The Domino server has to be version 7.0.2 or later. This is because we are getting JSON from the view and this was introduced on that version of the Domino server.

We need to have the Dojo Toolkit library downloaded to our Domino server. Unfortunately, Domino on Windows has a problem. The file name Shadow.js cannot be used. The file just does not show up through the web server. I have created a Dojo version where Shadow.js is renamed to Shadow2.js and everywhere it’s being referenced is changed. This is the version of Dojo that IBM is using inside Lotus Quickr 8. You can download it here: [download#5#nohits]. Remember to put the “dojo” folder inside the “html” directory on your Domino server. If you have a Lotus Quickr 8 server, you don’t have to do this step, but you need to modify the “src=” of the JavaScript to “/qphtml/html/dojo/dojo.js”.

We also must have session based authentication on our Domino server for the Sign In form to work. If you don’t you can still use the other code in this tutorial.

You need to download the database with all the code in it, [download#6#nohits]. You don’t want to type it all yourself do you?

Embedded Sign In FormSign In Form on a Domino Page or Form

What I’m doing here is a sign in form that we can put directly on a Domino Page or Form to let the user sign in without leaving the page to go to the Domino log-in form that redirects us back to where we came from. There is not much code to it. Let’s start.

We start by looking at the “HTML Head Content” of the “Dojo Forms Submission” Page.

"<script type="text/javascript" src="/dojo/dojo.js"></script>" + @NewLine +
"<script>" + @NewLine +
"var dbURL = '/" + @WebDbName + "';" + @NewLine +
"</script>" + @NewLine +
"<style>" + @NewLine +
"body, td {
font-size: 0.9em;
}" + @NewLine +
"</style>" + @NewLine

All we are doing here is calling the Dojo JavaScript file, adding a variable for the database URL and adding some style to our page. Next we look at the “JS Header”. Inside here we have 239 lines of JavaScript code. Don’t worry, we are only going to use 14 of them for this first part of the tutorial. The function we are using for the sign in is “directLogin()”.

function directLogin(){
var poststring = "username=" + dojo.byId("Username").value + "&password=" + dojo.byId("Password").value;
var kw = {
url: "/names.nsf?Login",
postContent: poststring,
load: function(t, txt, e) {
location.href = location.href;
error: function(t, e) {

As you can see we are constructing a string variable “poststring”, by adding the values of the “Username” and the “Password” fields to it. We are setting the “url” to “names.nsf?Login” and the “postContent” to our “poststring” variable. The “load” is what what we want to do after the Domino server returns that it was successful. All I do here is reload the page. We don’t have to that, we are actually signed in, but for the Hide-When formulas to take effect we need to in this case. More on this later. Dojo takes care of the rest by calling the “” and passing in the “kw” object.

Let’s look at the HTML part of our Domino Page. At the top of the Domino Page I have added some text to show who you are signed as and what access level you have. In a normal application, you would obviously not have those there.

<fieldset id="loginFieldset" style="padding-left:5px; padding-right:5px; padding-bottom:5px; width:200px;">
<legend style="font-weight:bold;"> Sign In </legend>
Name<br />
<input name="Username" id="Username" value="" maxlength=256 style="width:100%;" /><br />
<input name="Password" id="Password" value="" type=password maxlength=256 style="width:100%;" /><br /><br />
<input type="button" value="Sign In" onclick="directLogin()" />

We make the form pretty by adding the “fieldset” and “label” HTML tags. The important parts of the HTML code are the two fields and the button. There is nothing special with the fields other than they need to be there and the only thing I added the call to our function. I have also added a Domino Hide-When formula to this text.

@TextToNumber(@UserAccess(@DbName ; [AccessLevel])) > 2

All that the above @Formula does is hide the HTML if we have a user access greater than 2. Which is Reader access. This is the Anonymous access to the database. Default is Author. That’s it, not to hard was it?

Embed Domino forms and submit them using Ajax

Now lets embed a Domino form inside a floating pane on our page. This is not done by any IFrames or pop-up windows. This is the actual HTML code of the form in question embedded onto our page. We will also submit this form using Dojo’s Ajax way.

The form we are going to embed is called “Favorites”. It is a very basic form with three Text fields, a Checkbox field and a Readers field together with two buttons.

I also created a view called “Favorites View” that contains the documents using the form. More on that later in the next part of the tutorial.

First we add some HTML to our Domino Page so that we can open up the form in the floating pane.

<a href="<Computed Value>">Sign Out</a> | <a href="javascript:createNewDocument();">New Document</a>

The first link is the “Sign Out” link. It’s only there so that we can sign out. (It really belongs to the previous section.) The second link is our link to create a new “Favorite” document. As you can see it calls the function “createNewDocument()”. Let’s take a look at that code inside the “JS Header” on our Domino Page.

function createNewDocument(){
var oDiv = document.createElement("div");
oDiv.innerHTML = "Loading...";

var floatingPaneAttr = {
position: "absolute",
top: "100px",
left: "100px",
width: "300px",
height: "255px"

for(var s in floatingPaneAttr){[s] = floatingPaneAttr[s];

var floatingPaneArgs = {
widgetId: "ff-newdocument",
title: "New Document",
href: dbURL + "/Favorites?OpenForm",
displayCloseAction: true,
toggle: "fade",
windowState: "normal",
cacheContent: false,
refreshOnShow: true,
hasShadow: true,
executeScripts: true

g_FloatingPane = dojo.widget.createWidget("FloatingPane", floatingPaneArgs, oDiv);

First we check that we don’t already have an object named “ff-newdocument”. If we don’t we create a new Div element and append it to the document body. Then we add some style attributes to the Div. Here you see an example of how to use JSON directly in your JavaScript code. Then we create the “floatingPaneArgs” object. This is again Dojo and we are using a Dojo widget called “FloatingPane”.

The interesting part of the object is the “href” value. As you can see we are using the “dbURL” variable that we declared in the “HTML Head Content” area of our Page. If you recall, it was using an @Formula; @WebDbName. We then add the name of our form and the ?OpenForm to the string. What the other name-value pairs are I’m not going to go over here.

The last thing we do is to create our FloatingPane widget. We also have to declare to Dojo that we are going to use the FloatingPane widget, so we add this code to the top of our JavaScript.


That’s all there is to it. You can see an example of what it looks like when we open the pane to the right.

As you can see, I have also added a Set Reader Access check-box on the form. If checked, only authenticated users can see the document.

If you open the “Favorites” form and examine the two buttons you’ll see that they both contain JavaScript calls. The Cancel button calls “cancelFavoritesForm();” and the Submit button calls “submitFavoritesForm();”.

These two JavaScript functions do not exist on the Domino Form. They are both in the “JS Header” on our Page. Another proof that we are not doing this by an IFrame or a pop-up window. These two functions looks like this:

function cancelFavoritesForm(){

function submitFavoritesForm(){
var formObject = document.forms["_Favorites"];
var kw = {
formNode: formObject,
load: function(t, txt, e) {
//Reload view
error: function(t, e) {

The first function, “cancelFavoritesForm” is not to exciting, it just closes our Floating Pane. The same result as if you click the X at the top of the Pane. The “submitFavoritesForm” is much more interesting. In Domino all forms you open from the web gets a form tag with the name of the form with an _ (underscore) before it. So we create an object “formObject” by calling document.forms[“_Favorites”]. Now the fun begins. In we can declare a “formNode” value with the form object as it’s value. Dojo recognize that you are passing in a form and submits it using Ajax in the background. You can even have WebQuerySave agents run on the form and it will work. Really super cool.

Just as in our Sign-In JavaScript function, the “load” event is where we declare what will happen after the server returns that it was successfully loaded. Here we call “closeWindow” to close the Pane. We also call a function “getDocumentViewJSON()”. That is for the last part of this tutorial. You can see an example of much more complex Domino Form embedded into a web page by clicking the image on the left. This is from one of the Lotus Quickr templates that we have created, QContacts. It has a WebQuerySave agent, multiple tabs, attachment control and much more. There is also a function called “openDocument” where we just open documents after they have been saved. It looks a lot like the “createNewDocument” function I described earlier. We call this function inside our JSON function. Let’s jump to that.

Displaying a Domino View with JSON

The last part of today’s tutorial is all about Domino views, getting JSON from them and displaying the items on our Domino Page. First on our Page, we add a empty table to the HTML.

<table border=0 cellpadding=0 cellspacing=0 width="500">
<thead id="documentHead"></thead>
<tbody id="documentBody"></tbody>

This is where the documents show up when the JavaScript call is done. We also need to add some more functions to the “JS Header”. Don’t worry, it looks worse then it is.

function getDocumentViewJSON(){
var sURL = dbURL + '/favoritesview?ReadViewEntries&Outputformat=JSON';
sURL += '&Start=' + g_NumOfStartDoc;
sURL += '&Count=' + g_NumOfDocs;
dojoGetJSON(sURL, 'printDocumentTable');

g_DocumentHead = dojo.byId("documentHead");
g_DocumentBody = dojo.byId("documentBody");

The bottom JavaScript, “dojo.addOnLoad” is a really handy way of not calling anything until we are sure that everything on our page has loaded in the browser window. All we do here is to assign two global variables for the table header and the table body and call the function above, “getDocumentViewJSON()”. That is also the function we called from within our submit function in the previous section. In that function, we create a URL string that we pass to the “dojoGetJSON” function. We also pass in a string “printDocumentTable” to that function. That is the name of the function that we want to call when the server has passed back the JSON to the”dojoGetJSON” function. The two functions “dojoGetJSON” and “returnJSONValue” I’m not going to examine in this tutorial, it would be to long. All I can say is that “dojoGetJSON” get JSON back from a server and “returnJSONValue” returns specific column values from a Domino View. Examine them and try them out. We at SNAPPS use them daily in our code. Let’s look at the “printDocumentTable” function instead.

function printDocumentTable(oJSON){
var oRow, oCell;
if(oJSON["@toplevelentries"] && oJSON["@toplevelentries"] > 0){
var viewentries = oJSON.viewentry;
var n_viewentries = viewentries.length;
var unidAttr, entrydata, sTitle;

//Delete all rows in the table
var iRows = g_DocumentBody.rows.length;
for (var i = 0; i < iRows; i++){

if(n_viewentries > 0 && g_DocumentHead.rows.length < 1){
oRow = g_DocumentHead.insertRow(-1);

oCell = oRow.insertCell(-1); = "bold";
oCell.innerHTML = "Name";

oCell = oRow.insertCell(-1); = "bold";
oCell.innerHTML = "Pet";

oCell = oRow.insertCell(-1); = "bold";
oCell.innerHTML = "Color";

for (var i = 0; i < n_viewentries; i++){
unidAttr = viewentries[i]["@unid"];
entrydata = viewentries[i].entrydata;

oRow = g_DocumentBody.insertRow(-1);
oCell = oRow.insertCell(-1);
sTitle = returnJSONValue(entrydata[0]).items[0];
oCell.innerHTML = '<a href="javascript:openDocument('' + unidAttr + '', '' + sTitle + '');">' + sTitle + '</a>';

oCell = oRow.insertCell(-1);
oCell.innerHTML = returnJSONValue(entrydata[1]).items[0];
oCell = oRow.insertCell(-1);
oCell.innerHTML = returnJSONValue(entrydata[2]).items[0];

All I’m doing here is to create rows and cells with values for every document I get back from the call to the view. It might look like a lot of code but it is mostly repeated steps from creating rows and cells and adding values to them.

I will explain a few things though. “unidAttr” is just the UNID of the document. “entrydata” in the for loop represent all the column values that a document have. Calling returnJSONValue(entrydata[0]) returns an object with column type and an items array, even if there was only one value in the column for that document. Remember that a column can have multiple values for each document, a field with multiple values for instance. The function also returns the type of column the items come from, so that we can know what to do with the items. If for instance the column contains date strings we can parse them in the correct format for the application using JavaScript.

That’s if for this tutorial. I hope you have found it useful and maybe even learned something. As always please submit comments on the code and how I can do it better. Until next time. UPDATE! I have corrected some spelling errors. Why can’t everybody just learn Swedish?

Jun 062007

There are many articles out there explaining what JSON is and where to use it, including a very good article written by Scott Good titled JSON and Domino.

What I’m going to try to explain in this tutorial is why associative arrays are our best friend when coding with JSON and Ajax. We have all seen how JSON is starting to dominate the Ajax calls. Face it, XML is so 2006. But let’s jump to the code shall we?

Normal Arrays

We made an Ajax call to our table, or view if we live in the Lotus Domino world, using our favorite way (mine is using the Dojo toolkit) and we now have an array of objects that we need to iterate through. Let’s see an example of what the array might look like.

var aArray = [
{unid: "111AAABBBCCCDDD111", first: "Rob", last: "Novak", phone: "(555) 111-1111", zipcode: "11111"},
{unid: "222AAABBBCCCDDD222", first: "Troy", last: "Reimer", phone: "(555) 222-2222", zipcode: "22222"},
{unid: "333AAABBBCCCDDD333", first: "Jerald", last: "Mahurin", phone: "(555) 333-3333", zipcode: "33333"}

If all we want to do is write the array out to the browser this is fine, we just use a normal for loop.

var sHTML = '<table border=1>';
for (var i = 0; i < aArray.length; i++){
sHTML += '<tr>';
sHTML += '<td>' + aArray[i].unid + '</td>';
sHTML += '<td>' + aArray[i].first + '</td>';
sHTML += '<td>' + aArray[i].last + '</td>';
sHTML += '<td>' + aArray[i].phone + '</td>';
sHTML += '<td>' + aArray[i].zipcode + '</td>';
sHTML += '</tr>';
sHTML += '</table>';


111AAABBBCCCDDD111 Rob Novak (555) 111-1111 11111
222AAABBBCCCDDD222 Troy Reimer (555) 222-2222 22222
333AAABBBCCCDDD333 Jerald Mahurin (555) 333-3333 33333

But what if we have a little bit more complex example. (Stay with me.) What if we had a way of updating user meta data from this document or form and later call code on the server to actually update the record or document in the back-end.

So we have created JavaScript that when a row is clicked, fields are populated with data from the array so the user can update them. The end user clicks a button and our array should be updated with the new meta data. We also want to add a property of “updated” with a value of true (boolean) if it is changed so that we later only pass in those documents that have changed to our back-end code (agent if Lotus Domino).

So in our scenario we have updated one of the records and call a function to update the array. With a normal array this would be done like this.

function updateUserMetaData(sUnid, sFirst, sLast, sPhone, sZip){
for (var i = 0; i < aArray.length; i++){
if(aArray[i].unid == sUnid){
aArray[i].first = sFirst;
aArray[i].last = sLast;
aArray[i].phone = sPhone;
aArray[i].zipcode = sZip;
aArray[i].updated = true;

This works but if we have hundreds or thousands of records in the array it can take a long time. We have to iterate over all the values in our array to find the one with the right “unid”. Even though we are using a break statement when we have found our record it can still take a long time. Associative arrays to the rescue.

Associative Arrays

In JavaScript we have something called objects. They are a mapping from property names to values. Objects are an associative array with one caveat: since property names are strings, only string keys are allowed. That doesn’t matter to us.

We write an object literal as { property1: value1, property2: value2, ... }

Let’s rewrite our code to create an object instead of the array above.

var oObject = {
"111AAABBBCCCDDD111": {first: "Rob", last: "Novak", phone: "(555) 111-1111", zipcode: "11111"},
"222AAABBBCCCDDD222": {first: "Troy", last: "Reimer", phone: "(555) 222-2222", zipcode: "22222"},
"333AAABBBCCCDDD333": {first: "Jerald", last: "Mahurin", phone: "(555) 333-3333", zipcode: "33333"}

Can you see the difference? Not much difference in the text but a huge difference in what we can do.

First we can’t use a normal for loop to write our table any more. We need to use a for(in) loop.

var sHTML = '<table border=1>';
for (var unid in oObject){
sHTML += '<tr>';
sHTML += '<td>' + unid + '</td>';
sHTML += '<td>' + oObject[unid].first + '</td>';
sHTML += '<td>' + oObject[unid].last + '</td>';
sHTML += '<td>' + oObject[unid].phone + '</td>';
sHTML += '<td>' + oObject[unid].zipcode + '</td>';
sHTML += '</tr>';
sHTML += '</table>';

The output is exactly the same as above so we haven’t gained any value there. The big difference is in our function to update our meta data.

function updateUserMetaData(sUnid, sFirst, sLast, sPhone, sZip){
oObject[sUnid].first = sFirst;
oObject[sUnid].last = sLast;
oObject[sUnid].phone = sPhone;
oObject[sUnid].zipcode = sZip;
oObject[sUnid].updated = true;

As you can see we no longer need to iterate through an array to find our record. Since it is an object we can just update the property values directly.


In search for fast JavaScript code, associative arrays will help many times. It may seem a little difficult to code to begin with but after a while it actually makes much more sense. Object oriented programmers will find it easier.

Exactly one year ago from today, June 6th 2006, James Mc Parlane declared JavaScript Array and Object.prototype Awareness Day. Read that article. It will help you code better associative arrays (objects) in JavaScript.

Jun 042007

Several people have commented and emailed me wanting some sort of forum where I can post updates to code, examples and tutorials and where you can post your code variations, updates and ask questions to me and others.

So I have created Forums where you can register and ask questions and write your comments about Dojo Calendar and Lotus Quickr code and tutorials. So go there now and register so we can get some good discussions going.

May 172007

I have put the update of my Dojo Calendar on hold for a while. First I am extremely busy with work here at SNAPPS creating templates for the upcoming release of Lotus Quickr, secondly I’m upgrading all my code to fit better in the upcoming 0.9 release of the Dojo Toolkit.

I’m also looking into integrating with Google Calendar using their API. With PHP you can use the Zend Framework to do that. The next step is to port all my current PHP code over to Java Server Pages (JSP).

I’m very excited that over 200 has downloaded the code from the original post, so there must be some interest out there.

I have a few questions for you the reader.

  • What are your plans to use Dojo Calendar for?
  • What database will you use to store your calendar entries?
  • If you are one of the over 200 that has uploaded the original code. Have you done or are planning any modifications to the code?