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.

Prerequisites

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 {
color:#333333;
font-family:Helvetica,Geneva,Arial,Verdana,Sans-Serif;
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) {
alert(e.message);
}
};
dojo.io.bind(kw);
}

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 “dojo.io.bind” 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 />
Password</br>
<input name="Password" id="Password" value="" type=password maxlength=256 style="width:100%;" /><br /><br />
<input type="button" value="Sign In" onclick="directLogin()" />
</fieldset>

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(){
if(!dojo.byId("ff-newdocument")){
var oDiv = document.createElement("div");
oDiv.innerHTML = "Loading...";
document.body.appendChild(oDiv);

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

for(var s in floatingPaneAttr){
oDiv.style[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);
}else{
dojo.widget.byId("ff-newdocument").show();
}
}

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.

dojo.require("dojo.widget.FloatingPane");

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(){
if(dojo.widget.byId("ff-newdocument")){
dojo.widget.byId("ff-newdocument").closeWindow();
}
}

function submitFavoritesForm(){
var formObject = document.forms["_Favorites"];
var kw = {
formNode: formObject,
load: function(t, txt, e) {
dojo.widget.byId("ff-newdocument").closeWindow();
//Reload view
getDocumentViewJSON();
},
error: function(t, e) {
alert(e.message);
}
};
dojo.io.bind(kw);
}

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 dojo.io.bind 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>
</table>

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');
}

dojo.addOnLoad(function(){
g_DocumentHead = dojo.byId("documentHead");
g_DocumentBody = dojo.byId("documentBody");
getDocumentViewJSON();
});

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){
try{
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++){
g_DocumentBody.deleteRow(0);
}

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

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

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

oCell = oRow.insertCell(-1);
oCell.style.fontWeight = "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];
}
}
}catch(e){}
}

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 202007
 

My wife Beth and I saw Alison Krauss and Union Station featuring Jerry Douglas last night at the Starlight Theater in Kansas City, MO. It was great. Beth and I have been big fans of hers for a long time. Her voice is unbelievable. It was a wonderful evening for an outdoor concert. I give the concert and the night 5 stars. Continue reading »

Jun 202007
 

We have uploaded our fifth demo of our Lotus Quickr Templates: QIdeas.

Rob Novak:

The fifth Lotus Quickr template demo introduces QIdeas, an innovation and idea management template that probably has more uses than I’ve imagined for it. Visualize if you will the free-flowing nature of a wiki where revisions and enhancements to a concept and content are able to be made as simply as clicking “New Version”. Then to this collaborative model add the blog-like ability to let others comment on each version of the evolving document (idea in our case), and — this is key — making sure the comments are maintained in the context of the version with which they are associated. Not a free-flowing discussion about all versions, but very specific comments about the current version. An author might choose to incorporate those comments or not, but there is a record of when and by whom they were submitted.

Now that we’ve combined the concepts of a blog and wiki to collaborate, we have a platform on which to evolve business ideas and innovations to the point where they are worthy of submitting to some authority or group for “approval” or “review”. This is where the business construct of a workflow comes in, but it has to be flexible, manageable by the business user, and be able to be initiated at any time and not based on pre-set rules. The custom workflow engine we’ve built for these templates does just that, as you’ll see in this and four other template demos.

Enjoy this 17 minute demo of QIdeas

Jun 192007
 

Rob Novak has posted the sessions and speakers for Collaboration University for Lotus Quickr, QuickPlace and Sametime in July for both Kansas City and London.

For Sametime

  • Sametime 101 – Deploying Sametime
  • Sametime Meeting Center Customization Tricks – How to Roll Your Own!
  • Top 5 hidden Sametime Hacks and Programming Tricks
  • Developing Sametime Connect plugins
  • Exploiting the Toolkits for Sametime Bots and Automation
  • Sametime Links – Developing your own Queueing Application *Note from Rob – $10,000 in free code anyone???
  • Installation and Configuration — Sametime Gateway for Public IM
  • Deploying Sametime Connect Plugins
  • Sametime 7.5.1 New Features (It’s Bigger than it Sounds!)
  • Clustering Sametime Servers — Models and Examples
  • Bandwidth and Capacity Planning
  • Top 10 Support Issues for Lotus Sametime
  • Monitoring and Managing Your Sametime Servers (Including the new Monitoring Toolkit)
  • A Guide to Telephony Integration – A User’s Guide to Terminology and Options

For Lotus Quickr:

  • Lotus Quickr 8.0 Introduction and Features
  • Lotus Quickr Domino Installation and Configuration
  • Lotus Quickr – Introducing and Understanding the new Templates Part 1
  • Lotus Quickr – Introducing and Understanding the new Templates Part 2
  • Quickr Development Fundamentals – Placebots, Forms and Themes
  • Introducing the Dojo Toolkit
  • Lotus Quickr Development — Leveraging Template Code to Create Your Own Applications
  • Lotus Quickr for WebSphere Portal Installation and Configuration
  • Lotus Quickr for WebSphere Portal Development Overview
  • Using the Dojo Toolkit for Advanced Development in Lotus Quickr
  • Integration Strategies for Lotus Quickr, QuickPlace, Domino and Sametime
  • Flexible Views, Workflow Engines and More Reusable Tools!
  • Roundtable – Small Groups Session (size limited)
  • Lotus Quickr – Deploy How You Want, Where You Want – Integrating the Platforms

We will also have some foundation sessions on LDAP, Firewalls and the popular “Best 10 minutes from each speaker” session on the final day.

Collaboration University is a small, focused conference so you get one-on-one time with real experts and IBM development – folks like Carl Tyler, Rob Novak, Gabriella Davis, Chris Miller and more. Check out the speakers page, and get registered! See you in Kansas City and London!

Jun 192007
 

The fourth Lotus Quickr template demo is posted. This time it is QProject, which contains enhancements to the tasks and notifications in Lotus Quickr, introduces a concept of overall and cross-project status, and implements an enhanced AJAX Gantt chart for viewing tasks and their relationships to other tasks. Relationships? Yes, with QProject you can declare task predecessors and dependencies! One to one, one to many, however you like. The major features include the ability to set these dependencies, visualize them through the Gantt chart, receive consolidated overdue task notifications, and (my favorite) automatically push out dates when a predecessor is completed late. Not that this ever happens, but…

The 16.5-minute demo can be seen here: QProject demo

Enjoy

Jun 192007
 

Lotus Quickr will ship June 29, 2007. Only 10 days from today. Here’s the release. The 4th and 5th bullet are what we at SNAPPS been working with for the last months.

# # #

IBM Lotus Quickr 8 Expedites Team Collaboration

Open, intuitive standards-based Web 2.0 tool eases users into a more collaborative work style
with comprehensive Lotus and Microsoft integration


Armonk, NY…June 19, 2007…IBM (NYSE: IBM) today announces the June 29th
availability of IBM Lotus® Quickr 8 software, an open standards-based team collaboration tool that helps teams inside and outside the company firewall easily and effectively work together across geographies, working styles and operating systems.

Lotus Quickr provides a rich set of team collaboration capabilities, including blogs, wikis and team space templates supporting a variety of business processes to get a collaboration project up and running quickly. Already an enterprise-ready team collaboration offering supporting both Microsoft and Lotus software environments, Lotus Quickr interoperability will be further expanded with a connector to Microsoft Outlook software currently expected to be released in a beta program for Lotus customers this summer.

Easy to use and install with an intuitive Web 2.0 interface, Lotus Quickr software provides an easy way to share a wide range of business documents and access libraries through plug-ins called “connectors”. These connectors let end users work in their familiar desktop applications without impacting their work patterns – and access Lotus Quickr content directly from IBM Lotus Notes, IBM Lotus Sametime, Microsoft Windows Explorer and Microsoft Office software.

Through a beta testing program conducted since early 2007, IBM has taken feedback from dozens of customers and partners to improve Lotus Quickr 8 to meet the needs of the connected workplace. The result is a clean and user-friendly interface designed to ease users into a more collaborative work style and increase visibility of materials and contributors.

“IBM has developed an extremely competitive content and collaboration product with the ability to be extended and customized to meet specific business and industry needs,” said Daniel Lieber, president of Innovative Ideas Unlimited, Inc. “The Lotus Quickr interface is clean, consistent, and straight-forward. We found it to be very efficient for working with collaborative content and accomplishing tasks in a personal, workgroup, departmental, or enterprise environment.”

“Lotus Quickr integrates key Web 2.0 capabilities, such as blogs & wikis that expand the type of collaboration possible, and it provides a breadth of integration across everyday applications from Microsoft & Lotus delivering ease of access to content,” said Ken Bisconti, Lotus vice president of messaging and collaboration software. “This flexible tool bridges gaps in working styles and technical savvy — appealing both to workers embracing Web 2.0 internet content tools such as blogs and wikis along with those who are more comfortable accessing content from the familiar Microsoft Windows Explorer interface.”

Key benefits of Lotus Quickr include:

  • Web 2.0 features that enhance usability: IBM has incorporated Web 2.0 technologies such as AJAX (Asynchronous JavaScript and XML) into Lotus Quickr to deliver an intuitive, integrated and high performing graphical Web-based user interface. This interface includes dynamic action menus that can be accessed through a right click, and easy drag and drop features to seamlessly move documents into team spaces. Lotus Quickr provides the ability to publish and consume Atom-based news feeds, publish team blogs, use the built-in wiki technology for creating content, and to assign tags and permalinks to content. It is easily customizable and extensible without requiring programming skills.
  • Support for open standards, providing customer choice of vendor: Customers are free to mix and match products as they desire. Lotus Quickr integrates with Microsoft Office 2003 and 2007, Microsoft Windows Explorer on Windows XP and Windows Vista, IBM Lotus Notes 7 and 8 (with planned support for Lotus Notes 6.5) and Lotus Sametime 7.5. Lotus Quickr supports Microsoft Internet Explorer, Firefox, and Safari browsers, providing Web access from Windows, Linux, and Macintosh desktops. In addition, IBM currently plans to release a beta version of a Lotus Quickr connector for Microsoft Outlook this summer. IBM also currently plans to release migration and coexistence tools that will allow users to access content in existing Microsoft SharePoint and Exchange public folders via Lotus Quickr’s web 2.0-style collaborative user interface, or to migrate that content out of Microsoft repositories into Lotus Quickr, where it can be easily accessed and widely shared.
  • Easy-to-use features that can be rolled out across enterprise: Many past efforts to create project spaces have been either difficult to use or were not enterprise-ready. Lotus Quickr makes it easy for any team member to get up and running with easy instructions on how to get started, a clean and simple user interface, tutorial style wizards that guide the user. Lotus Quickr also features helpful pop-ups that remind the user when they can opt to place a document inside a shared place rather than send it as an attachment to others.
  • User-driven enhancements that reduce information overload and errors that come with sharing documents among team members through email: When documents are sent from a single user to a group for feedback, the process of tracking edits and changes over email can be inefficient and prone to error. Lotus Quickr allows check in and check out of documents to prevent simultaneous editing and versioning to track changes. In addition, wiki technolology provides an in-place Web editing option with history so a user can revert back to an earlier version of a page. The wiki and library views support posting comments about documents that are viewable in a pop-up screen by rolling the mouse over a document.
  • Business application templates that provide immediate out-of-the-box value and support of common business processes: Lotus Quickr includes business templates, such as a meeting place, project management, image repository, dynamic surveys and more. All templates are customizable, allowing users to easily change the look and feel and add pre-built components, such as a team blog, a project calendar, or an announcement page.
  • Future enhancements to Lotus Quickr include integration with IBM’s enterprise content management (ECM) systems. Customers will be able to use Lotus Quickr to collaborate on content and seamlessly leverage the world-class capabilities of IBM FileNet P8 and IBM DB2 Content Manager software to manage that content.

Lotus Quickr Pricing and availability: Prices will be announced at the time of availability on June 29. For more information, visit: ibm.com/lotus/quickrIBM, the IBM logo, DB2, Lotus, Notes, Quickr and Sametime are trademarks of IBM Corporation in the United States, other countries, or both. Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.
FileNet is a registered trademark of FileNet Corporation, in the United States, other countries, or both.

Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.
Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.

Other company product or service names may be trademarks or service marks of others.

The information above is based on IBM’s current product plans and strategy, which are subject to change by IBM without notice.

Jun 152007
 

Today I added a really cool plug-in for my blog. Instant podcast for all my post entries. It is all done by a free service from Odiogo. It adds this image, , at the bottom of each of my posts. When clicked it will read the contents of the post to you. Super cool. It does take a little time for Odiogo’s servers to parse the text and to create the mp3, but if you click on any of the posts below this one it should work. UPDATE: This post can now be heard as well. You can also go to a podcast page with all the latest posts by clicking here .

Enjoy

Jun 142007
 

Rob Novak has uploaded our third Lotus Quickr template. This time you’re introduced to QSurvey.

In my third demo, you’ll be introduced to QSurvey, a component that allows you to create surveys, lets users take them, and provides two methods of generating survey reports. I’m loving this one myself, because having been in the Lotus world for nearly 15 years now, surveys have been in demand and really hard to do. There have been and may still be some third party products for this. I’ve even built it myself, many years ago. There was much pain in the days when it was nearly impossible to assemble fields onto forms without being a trained developer, and have it look good on the web.

The implementation here in Lotus Quickr is fairly elegant, as we store all the survey questions as JSON, all the answers as JSON, and simply reassemble it all for the live reports. What I like about QSurvey is how easy it is to use…I can create a survey quickly with a question “wizard”, enable it, and let people take it for either a defined period of time or disable it myself. And of course, there are options for securing the survey, deciding who can see result reports, and choosing whether to allow anonymous access.

Click the link to check out the QSurvey Demo.

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>';
document.write(sHTML);

Output:

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;
break;
}
}
}

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>';
document.write(sHTML);

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.

Conclusion

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.