XML data binding

According to Wikipedia refers XML data binding to the process of representing the information in an XML document as an object in computer memory. This allows applications to access the data in the XML from the object rather than using the DOM to retrieve the data from a direct representation of the XML itself.

In other words you could tie HTML tables to Notes data and navigate through it without reloading the page.

For this SNTT demo I needed:

  • a form to create Book documents with
  • a view to present the books documents as XML
  • a page on which I define an HTML table and connect the table to the XML view in order to give it content
  • (a $$ViewTemplate for the Xml view)

First step:

  • Create your Notes form with some fields. I choose Title, Author, ISBN and Price.
  • Create a set of documents with this form.

Next:

  • Create a view that presents the ‘Books’ documents as XML data.
  • On the fifth tab under ‘Web access’ d not forget to set the option ‘Treat view contents as HTML’
  • The view must start with an opener and closing tag for each document
  • For each column you define sub child elements

xml view

  • Setup a $$ViewTemplate for this View in order to be able to add a root element:

$$ViewTemplate form

Reminder: do not forget to set the content-type for this Form as HTML.

Continue:

  • Create a Form/Page that will hold the HTML Table.
  • Add the following HTML on it:

HTML for table

As you can see the Table is linked to a datasource, in this case the View books.xml. Each TD in the TBody part is linked to a datafield. In this setup the datapagesize is set to 5, meaning 5 documents at a time will be displayed.

Some extras

By giving the table an ID (xmlTBL) you can add functions to navigate through the table such as:

  • previous / next set of documents
  • first / last set of documents

navigation buttons

I bet you can imagine some much better pagination examples.

At the end your ‘bookstore’ will look like this:

how the local bookstore looks like

I have included a working example here.

Pure CSS Data Chart

Okej, one day too late for SNTT, but some people are also allowed to post SNTT’s already on Wednesdays it seems…

Alen Grakalic wrote a nice article about using pure CSS as data charts. Basically via CSS Alen presents pure data in a graphical way.

Here is how it could look like:

css chart

(almost weekend? or those pills do work?!)

The screen capture is information from a Domino View embedded on a page and transformed with some CSS. Nice? I guess this is a very cheap way of creating more dashboard alike solutions…

Anyway, for those who are curious here is a downloadable working example. Have a nice weekend!

Mimicing the tabbed table function

tab1The problem with the Notes tabbed table is that you can not, by default, add an action when you click on a tab.

I created a tabbed table function in the way you probably would do it on the web (with hidding/showing divs) so a tab is just a table column with a text hotspot in it. When you click on the text a different table would be shown with an ‘active tab’ highlighted:

dialogbox

The reason for this solution is that the form is presented in a dialogbox and I have to set a parameter from which tab the user has selected a document-template (templates may be stored in different databases).

So how to fix this with a Notes tabbed table outlook?

First create images for all active tabs:

tab1 & tab2

Then sharpen your eyes (or use good photo-editor program) and select a part of the horizontal row/border that aligns the table to the width of the page (correctly described?):

This is an enlarged example:

zoomed

Now place your tabbed images in separate tables, give the table a background color and a cell image of the ‘zoomed’ example:

 table properties

On your ‘tabbed’ images you place hotspot rectangles that will do the hide/when-work. Here you can write now also the action that is not possible for a normal ‘tabbed table’:

hotspot formula

At the end the result will look something like this:

result tabbed mimic

Mail an action through Outlook

Some people are just not that fortunate to have the privilige to be working with such an excellent tool as Lotus Notes is. In order to give them the option to add an action document created in a Notes application to their todo list in Outlook the code below will do the job:  

outlook

Sub Click(Source As Button)
 
 Dim ws As New NotesUIWorkspace
 Dim session As New NotesSession
 Dim db As NotesDatabase
 Dim uiddoc As NotesUIDocument
 
 Set db = session.CurrentDatabase
 Set uidoc = ws.Currentdocument
 Set doc = uidoc.document
 
 If uidoc.IsNewDoc Then
  Msgbox “This document has not been saved.” & Chr$(10) & Chr$(10) & “Please save prior to mailing this action!”, 4112, “New Document”
  Exit Sub
 End If
 
 Const Formula$ = { @DbLookup(“”; “”; “$People”; AssignedTo; “Email”) }
 Dim namesList As Variant
 
 Set myOlApp = CreateObject(“Outlook.Application”)
 Set myNameSpace = myOlApp.GetNameSpace(“MAPI”)
 Set myFolder = myNameSpace.GetDefaultFolder(13)
 Set myItem = myOlApp.CreateItem(3)
 
 Dim rtItem As NotesRichTextItem
 Set rtItem = doc.GetFirstItem(“Comment1”)
 
 With myItem
  .Assign
  namesList = Evaluate(Formula$, doc)
  Forall names In namesList
   Set myRecipients = .Recipients.Add(names) 
  End Forall
  .Subject = doc.Subject(0)
  .Body = “Action number: ” & doc.ActionNumber(0) & Chr$(10) & Chr$(10) & rtItem.text
  If (doc.NoDueDate(0)=””) Then 
   .DueDate = doc.DueDate(0) 
  End If
  .Importance = doc.Priority(0)
  .Status = doc.Status(0)
  .Categories = doc.Category(0)
  .Display
 End With
 
 doc.OutlookSave = Date$
 
 Set myOlApp = Nothing
 Set myFolder = Nothing
 Set myItem = Nothing
 Set myRecipients = Nothing
 Exit Sub
 
End Sub

Displaying documents in a View in a ‘Thumbnail Gallery’ format

Showing document information in the normal ‘vertical’ way can sometimes be pretty boring. It also requires a lot of space especially when images as part of the information becomes involved.

On the WWW a lot of examples can be found how to create a ‘CSS Image Gallery

But you will see when images have different sizes and their caption text underneath will differ the result will be quickly dis-satisfying:

css gallery example

Ofcourse you can set the same height and width on the images. But what for the caption text?

With a little bit of DOM scripting using Prototype you can simply rebuild your screen and show the view in a table format. Add the following code to the JS onLoad event:

//ALL DOCUMENT INFORMATION (ROW) IS DISPLAYED IN A DIV WITH CLASS THUMBNAIL:
varThumbs = $$(‘div.thumbnail’);
varThumbs.each(Element.hide);
//NUMBER OF COLUMNS:
var numberDocs = 3
var varRowCounter = 1
var varTable=””;
if (varThumbs.length > 0) {
 varTable+=”<table border=0>”;
 varTable+=”<tr>”;
 for (i=0; i< varThumbs.length; i++) {
  //FYI (5 % 5) =>  5 Mod 5 returns 0
  if (varRowCounter % numberDocs == 0){
   varTable+=”<td valign=\”top\” onmouseover=\”style.backgroundColor=’#F4F4F4′;\” onmouseout=\”style.backgroundColor=’#FFF’;\”>” + varThumbs[i].innerHTML + “</td></tr><tr>”
   varRowCounter=1
  }  
  else{
   varTable+=”<td valign=\”top\” onmouseover=\”style.backgroundColor=’#F4F4F4′;\” onmouseout=\”style.backgroundColor=’#FFF’;\”>” + varThumbs[i].innerHTML + “</td>”
   varRowCounter+=1
  }  
 }
 varTable+=”</tr>”;
 varTable+=”</table>”;
}
$(‘viewbody’).replace(varTable)

‘viewbody’ is the DIV where the $$ViewBody field is nested.

Navigation-menu from view (XML Transformation)

In a previous writing I explained how you can create a navigation-menu that collects it’s information straight from a Notes View.

example navigation 

Using the ?ReadViewEntries URL command Notes outputs the view data in XML form which can be the source of a transformation to HTML using the XSLTProcessor in your browser.

When the project became actual again I found some time to improve it’s functionality, since it was not working 100% in Firefox. So here is an example available for downloading.

Here is short summary of the example’s features:

  • the navigator collects it’s source data from a Notes view using the ReadViewEntries command
  • when navigating through the menu for each subcategory (via the + and – icons) a new AJAX request is done to collect the information withing that (sub)category (so the amount of data is being divided into smaller parts)
  • the information is being transformed into HTML via the build XSLTransformator of the browser
  • when clicking on (sub)category a collection of responding documents is collected and presented in another frame
  • the navigator also contains document links which will load the document info in the right frame when clicked
  • documents can be grouped under whatever structure in the View

Very nice, I did not manage to solve 1 thing yet: if a (sub)category contains subcategories AND documents, the documents are being displayed FIRST. I rather would display the subcategories first and then the documents. Maybe you can help me with that one?

example of results

Documentation, right! How and where?

Documentation is something we would (like to) do if there would be time calculated for it in every project. But in a lot of development projects the customer is not interested to pay for something he/she is not going to read at all so where to ‘store’ the application logic?

To my opinion it can help to use the IBM like approach in delivering brief documention in their templates, just like Rocky Oliver talked in his session ‘Creating Maintainable IBM Lotus Notes and Domino Applications – Writing Readable Code’ at Lotusphere 2007.

documentation example

How do you deliver your documentation?

A sample of above can be found here.

@If variant for aliases

For a computed text I needed to write down the value of a dialoglist field which uses aliases.

Luckily the number of options was limited, but for a list of long options I do not want to use this construction:

@If( condition1 ; action1 ; condition2 ; action2 ; … ; condition99 ; action99 ; else_action )

Therefor I came up with the following solution creating a text-list with options and then go through them using @Elements, @Right and @Left:

status:=”Draft|0″:
“Awaiting Approval|1”:
“Approved|2”:
“Archived|3”:
“Rejected|91”:
“Returned|92″;

@For(n := 1;n <= @Elements(status); n := n+1;
 rightvalue:=@Right(status[n];”|”);
 @If(rightvalue=Tx_Status;leftvalue:=@left(status[n];”|”);””)
);
leftvalue;

Update: ‘Warning before…’ – Demo

I have uploaded a demo application, yuk Notes 8 vocabulary, here for download. The default frameset contains a form. Fill in some data in the fields and try to leave the form. A following warning will show up:

demo screen

Enjoy!

Ps this database was saved with the Notes 8 Designer. Can anyone tell me where the ‘Save’ smarticon went? I could not find it while working on the form. Using the File-Menu-Save really is annoying?

While kicking Notes 8: what the hell must that ‘Preview in Web browser’ icon look like? Notes 8 smart icons: BAD!!!

Warning before navigate away from a web form without save

This posting is merely a big ‘thank you’ to Philippe Gauvin’s posting ‘Warning before navigate away from a web form without save’ and Simon Willison’s posting ‘Simple Tricks for More Usable Forms’.

Philippe describes how you can add a function that warns users when they intend to leave the window without actually saving the document. Simon describes the way how to add event listeners to forms, which is a great add-on Philippe’s article because Philippe ‘forgets’ to write how he implemented the code to work.

So what is the idea?

  • a users has a form opened
  • when he clicks on a link that leads him to another page a warning comes up if he really wants to leave the page without saving or if he wants to stay on the form so the document can be saved
  • the condition I added is: if there are changes made to required fields then I think the user has actually worked on interesting information, so in these cases the warning should pop-up.

In my example each required field has a classname ‘required’ (a bit based upon Andrew Tetlaw‘s really kewl javascript form validation method). When there is a difference between entering the field and leaving the field a third field will change from value “0” to “1” which should initiate the warning.

Adding Eventlistening

I did not want to add into every single field a function that would check if there have been made changes, so on the windows load event we add an eventlistening. As soon as the user enters and leaves one of the ‘required’ fields we run an onfocus or an onblur function.

How to implement?

Just follow Philippe’s instructions. Basically I added a Notes field, gave it an id ‘IsChanged’, default value is set to “0” and I made it hidden. Then I copied in the JSHeader of my form the first part of the code:

// SHOWING A WARNING WEN USERS LEAVE THE FORM WITHOUT SAVING
function formChange(){ 
 $(‘isChanged’).value=”1″;
}

window.onbeforeunload = confirmExit;

function confirmExit() { 
 if($F(‘isChanged’)==’1′)     return “You have not saved the form yet. Are you sure ?”;
}

(by the way, yes we use the Prototype library)

Second, based upon Simon’s article I added the next lines of code in the JS Header:

addEvent(window, ‘load’, function() {
  var input,textareas;
  var inputs = $$(‘input.required’);
  for (var i = 0; i < inputs.length; i++) {
     addEvent(inputs[i], ‘focus’, oninputfocus);
     addEvent(inputs[i], ‘blur’, oninputblur);
  }
  var textareas = $$(‘textarea’);
  for (var i = 0; i < textareas.length; i++) {
     addEvent(textareas[i], ‘focus’, oninputfocus);
     addEvent(textareas[i], ‘blur’, oninputblur);
  }
});

function addEvent(obj, evType, fn){
 if (obj.addEventListener){
     obj.addEventListener(evType, fn, false);
     return true;
  } else if (obj.attachEvent){
     var r = obj.attachEvent(“on”+evType, fn);
     return r;
  } else {
     return false;
  }
}

var tempinputvalue =””;

function oninputblur(e) {
 if (typeof e == ‘undefined’) {
  var e = window.event;
 }
 var source;
 if (typeof e.target != ‘undefined’) {
  source = e.target;
 } else if (typeof e.srcElement != ‘undefined’) {
  source = e.srcElement;
 } else {
  return true;
  }
 if ($F(source) != tempinputvalue) {
  $(‘isChanged’).value=”1″
 } 
}

function oninputfocus(e){
 if (typeof e == ‘undefined’) {
  var e = window.event;
 }
 var source;
 if (typeof e.target != ‘undefined’) {
  source = e.target;
 } else if (typeof e.srcElement != ‘undefined’) {
  source = e.srcElement;
 } else {
  return true;
 }
 tempinputvalue = $F(source)
}
// END – SHOWING A WARNING WEN USERS LEAVE THE FORM WITHOUT SAVING 

 This initates the event listening for the onblur and onfocus events of the fields with classname ‘required’. That’s it. I do not know how I can adjust the default warning popup, but I guess sure one of you know:

warning