Viktor Krantz

Jul 042007
 

The next to last Lotus Quickr Template demo is: QActivities. In QActivities, we have strived for a combination of an approachable, professional user interface and a base level of integration with Lotus Connections. Specifically, QActivities integrates with the Activities server, allowing the user to add any page in the Lotus Quickr place to an activity on the Activities server. This becomes very powerful when combined with the Lotus Notes 8 client and the embedded Activities sidebar. You can add a Quickr page to an activitiy, see it immediately in your Notes client, and launch the Quickr page form the context of the activity. Simple but very cool and effective and dare-I-say-it-again contextual collaboration.

In addition to a refreshed UI accomplished almost entirely with CSS – hence much faster – we’ve added some great features to Lotus Quickr like a list of the last 10 updated documents, a member list that searches for documents created by the member when clicked, and a nice little tab with place statistics!

You can see the demo of QActivities here.

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 eighth Lotus Quickr Template demo has been posted. This time it’s QIssues.

Similar in feel to QSurvey, the form creation process is very simple. A floating window lets you build questions for your issue form and submit them to build the form. There are a couple new types of questions not found in QSurvey, a member list and date control. Once the questions are built, you can move them around, define a layout (1, 2, 3 columns or a wizard) and – this is key – decide right at the form what kind of workflow to put submissions through. And of course, using the workflow engine we’ve bundled with several templates, you can define that workflow yourself.

You can see a demo of QIssues here.

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.

Jul 032007
 

From Rob Novak’s blog:

For the seventh Lotus Quickr Template demo, you’ll see QMeeting, an organizational and planning aid for complex meetings. Not the 2-hour staff meeting or the 90-minute group conference call, those are better handled with your Notes Mail and Quickr’s native group calendar, respectively. The meetings that benefit most from QMeeting are those that make you tear your hair out – multiple agenda items, planned breaks, different people responsible for each agenda item, multiple electronic resources (attachments), and a timeline to keep. Examples of such meetings? Shareholder’s meetings. Conference tracks. Corporate retreats. Financial reviews. The big ones!

QMeeting lets you distribute responsibility for agenda items to individuals, or lets you manage agenda items as discrete elements as a proxy for an outsider, or even create them on the fly. Agenda items are the building blocks of complex meetings, and each can have its own “Owner”, resources, rich text, and set of appropriate attachments. So if John is in charge of Finance, let John manage the agenda item for the financial report!

The meeting manager – a person who puts together the meeting agenda – can then easily assemble an electronic meeting agenda that automatically computes time slots, adds breaks and lunches, and even includes online meetings. If someone hasn’t completed their agenda item, it can be added easily. Once the meeting agenda is built, it has direct links to each agenda item, and (this is cool) direct links to each attachment. This document becomes the easy access point for all meeting participants. In practical use, it can be projected and run by a person when the meeting is live in person, and used online when the meeting is managed via teleconference or Sametime. It becomes a nice adjunct to online meetings by storing all meeting “artifacts” in one place.

Go have a look at the QMeeting demo.

Jul 032007
 

Rob Novak has posted the sixth Lotus Quickr Template demo: QAnnounce. From Rob’s blog:

QAnnounce lets you put structure around the creation, edit, approval and archive process for any kind of “official” communication. The form is fairly simple, with the kind of metadata fields you would expect – a distribution date, a field to track the disposition of the document, and (something new) a field to track comments as each edit is made, and display them in an audit trail along with the name of the person making the edit, the disposition at the time, and the date and time the edit was made. Of course, we’ve included some flexible views to let you categorize the communications by disposition or category.

Go have a look at the QAnnounce demo here.

All the demos are now done. Check back here today for the postings!

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!