Implementing AJAX with DXL is easy task |
Sin traducciones disponibles |
Published January 30th, 2007 in MGDevelopers
Implementing AJAX with DXL is easy task. Developing dynamic and cross-browser web applications on an IBM Lotus Domino platform is a simple task if we know how to take advantage of the possibilities that Domino XML offers, the AJAX concepts and Sarissa.
Level: Intermediate
August 2006
Introduction
Many times we find applications in which we would like to use new technologies to improve user’s experience. However, we don’t always dare to innovate because we don’t have the necessary time for investigating such task or perhaps because we don’t know the difficulties involved in its implementation.
At the present time, the use of dynamic and asynchronous technologies is more frequent in the communication between clients and server due to the fact that, by doing so, you can lower the bandwidth in the communication and also improve times of response and the system's usability. At the same time, the need to reach more clients has become a priority objective for which AJAX and Sarissa are absolutely necessary at the time of having the application supported by different browsers.
Since IBM Domino Server 6.0 we’ve had the possibility of working with any element from a data base through a common interface in XML format.
This article has the objective of deepening the presented technologies and the cases in which its application becomes useful, and also to develop a dialog of multiple selection, similar to “Dialog window” available at IBM Lotus Notes clients. Both proposals focus on Notes developers not too experienced with basic knowledge of HTML, JavaScript and XML.
DXL
Domino XML (DXL) is a set of tools offered by lotus Domino to work with the elements of a data base in XML format.
With DXL information from documents as well as design elements can be exchanged. This means that we can consult or modify documents, views, forms and also the ACL of a data base.
The XML used in communications has a predefined format (in a DTD), and its structure is very simple. The tags are descriptive and easy to associate, therefore DXL becomes very similar to the XML generated by some other application we can build. Following is an extract of DXL generated from a document.
Example 1 - DXL Format
-
<document form ="ContactInfo">
-
<item name ="UNID">
-
<text>A6706DF66CEA473D0325719C0059DB17</text>
-
</item>
-
<item name="firstname">
-
<text>John</text>
-
</item>
-
<item name="lastname">
-
<text>Smith</text>
-
</item>
-
<item name="email">
-
<text>john.simth@mycompany.com</text>
-
</item>
-
</document>
At the time of having to transport information from one Lotus Notes system to another (for any given platform), the use of DXL is highly recommended, as the various tools Lotus Domino gives us, particularly reduces the effort of implementation.
We will dedicate the next paragraphs to show the simplicity with which you can obtain data from a document and, at the same time modify any field. The simplification of tasks is possible because with DXL, it is not necessary to generate a code to understand XML and then modify documents, because this job is already done through the available classes. In the same way, it is also very easy to consult a view and obtain the fields of any document.
To obtain more information on Domino XML please consult the reference section.
AJAX
AJAX is the acronym of "Asynchronous Javascript And XML", which means asynchronous communications through javaScript and XML. In most cases when developers think of AJAX they don’t usually associate it with Domino. However, this is absolutely possible as Domino has enough tools to integrate the server with the browser in a very simple way.
AJAX is not a technology by itself, but a method to transfer information between the clients and the server, which uses several different technologies, many of which are used every day by all applications developers oriented to the web, for example Dynamic HTML, CSS, JavaScript, XML and XSL.
AJAX main objective is to get the user’s interface not to refresh every time an update of data in the server is requested, but instead to have the possibility of making any requests or modifications in a dynamic way. Therefore, AJAX improves the user’s experience, and he can continue working without the obligation of waiting for the page to refresh. Asynchronous communications with the server allows users to keep control of the window, which means users are able to continue interacting with the window while the server retrieves the date requested.
The main component used in AJAX is the object XMLHTTPRequest, which allows generating communications with the server (with methods GET or POST) and obtain the result in a DOM object. Every time information to the server is sent or obtained, the AJAX engine will create a request to the back-end system and will inform us when the answer is available.
To read more about AJAX please consult the reference section.
Sarissa
Sarissa is a framework based on a set of ECMAScript libraries which give us a layer of abstraction of the APIs of native XML in different environments. Its use in dealing with XML becomes very efficient because, among many other possibilities, it allows the instantiation of DOMDocument objects, load of XML from an URL, or from strings, the transformation with XSLT and X-Path queries.
Supported browsers are Mozilla Firefox and family, Internet Explorer with MSXML 3.0 parser or higher, Konqueror (KDE 3.3+), Safari and Opera. It is important to consider that although the framework can be used in a wide range of browsers, there are cases where the functions are limited, as in the case of Konqueror, Safari and Opera, which lack of support of XSLT/X-Path.
The use of this framework does not require an effort higher than that of include its libraries. The codification is substantially simpler, as we can avoid evaluations of the browser type used by the client, and at the same time we can standardize the way in which web applications are developed. Such normalization is very important as it leads to re-use.
Lets see some examples.
Example 2 - Instance of a DOMDocument object
-
var oDomDoc = Sarissa.getDomDocument();
-
-
// en Mozilla este método es equivalente a:
-
var oDomDoc = document.implementation.createDocument();
-
-
// en Internet Explorer este método es equivalente al siguiente, dependiendo de la versión del parser de XML:
-
var oDomDoc = new ActiveXObject("Msxml2.DOMDocument.4.0");
Example 3 – Asynchronous loading of a DOMDocument object from a remote source
-
var oDomDoc = Sarissa.getDomDocument();
-
oDomDoc.async = true; // true es el valor por defecto
-
-
// agregamos un listener el evento que se dispara cuando la carga se completa
-
function loadHandler(){
-
if(oDomDoc.readyState == 4)
-
alert(oDomDoc.xml);
-
};
-
-
oDomDoc.onreadystatechange = loadHandler;
-
oDomDoc.load("someDocument.xml");
Example 4 – Creation of a XMLHttpRequest object.
-
var xmlhttp = new XMLHttpRequest();
Example 5 - Asynchronous loading of a XMLHttpRequest object from a remote source
-
var xmlhttp = new XMLHttpRequest();
-
xmlhttp.open("GET", "someDocument.xml", true);
-
-
// agregamos un listener el evento que se dispara cuando la carga se completa
-
function loadHandler(){
-
if(xmlhttp.readyState == 4)
-
alert(xmlhttp.responseXML.xml);
-
};
-
-
xmlhttp.onreadystatechange = Function("loadHandler()"); // otra forma de asignar el listener del evento
-
xmlhttp.send(null);
In the example we use of GET method when doing the requests to the server. In our demo we will use the POST method, as information will be sent to the server to be processed, according to W3C recommendation.
Example 6 – Transformation of a DOMDocument object with a XSLT
-
// obtenciĂłn del documento fuente
-
var oDomDoc = Sarissa.getDomDocument();
-
oDomDoc.async = false;
-
oDomDoc.load("someDocument.xml");
-
-
// obtenciĂłn del xslt
-
var oXslDoc = Sarissa.getDomDocument();
-
oXslDoc.async = false;
-
oXslDoc.load("aStylesheet.xsl");
-
-
// transformaciĂłn, el resultado se obtiene como un String
-
var sResult = oDomDoc.transformNode(oXslDoc);
-
alert(sResult);
For downloads and more information on Sarissa consult the references section.
Hands On
Presentation of the application
We will next present the development of the dynamic component and we will initiate it with the exhibition of our reference implementation through a screenshot.

Figure 1 – Contact charge/selection of options Form (Mozilla Firefox - Windows)
Our reference implementation consists of a system to administrate contacts which uses a contact charge form in which you can find multivalue fields which are completed with the use of the selection dialog. This dialog allows us to create new options and modify existing ones.
The application structure
To understand how the application is built, a table with the design elements and its dependences is presented.

(*) These elements are part of the component
For a wider overlook of the relation among the design elements consult system documentation with UML diagrams.
The superagent
The agent processing AJAX requests is called AJAXProcessor. It will be in charge of taking care of the user’s interface requirements to then give an answer back.
In our example, we will only process creations and updatings of documents although this does not exclude the possibility of extending its capacity to eliminate documents among other possible functions. Lets find out about the tasks done by the agent.
Code 1 - Agent AJAXProccesor
-
Sub Initialize
-
Dim dContext As NotesDocument
-
Dim requestContent As String
-
Dim response As String
-
-
Set session = New NotesSession
-
Set dContext = session.DocumentContext
-
-
requestContent = dContext.GetItemValue("Request_Content")(0)
-
-
response = Import(requestContent)
-
-
Print "Content-Type: text/xml;"
-
Print response
-
-
Set dContext = Nothing
-
End Sub
At the beginning of the agent, we obtain the context document which will have all the required http fields. Of these fields we are interested in highlighting Request_Content where we find the information sent when doing the POST request. In other words, the XML with the documents to be created or updated will be sent in the Request_Content variable.
Then we call the Import function which will translate the XML into Domino documents. At the end of this function we will return another XML as a reply, which will indicate if the processing was successful. Finally, we eliminate the generated objects, to free memory.
Now, we will see what the Import function does:
Code 2 – Import method
-
Function Import(requestContent As String) As String
-
On Error Goto errorHandler
-
-
Dim db As NotesDatabase
-
Dim stream As NotesStream
-
Dim importer As NotesDXLImporter
-
-
Set db = session.CurrentDatabase
-
Set stream = session.CreateStream
-
-
stream.WriteText(requestContent)
-
-
If stream.Bytes = 0 Then
-
Import = "<?xml version='1.0'?><response error='1'><error><description>Cannot read input" & _
-
"stream!</description><code>-1</code></error></response>"
-
Exit Function
-
End If
-
-
Set importer = session.CreateDXLImporter(stream, db)
-
importer.DocumentImportOption = DXLIMPORTOPTION_UPDATE_ELSE_CREATE
-
Call importer.Process
-
-
Import = "<?xml version='1.0'?><response error='0' />"
-
-
Set db = Nothing
-
Set stream = Nothing
-
Set importer = Nothing
-
-
Exit Function
-
-
errorHandler:
-
Import = "<?xml version='1.0'?><response error='1'><error><description>" & Error(Err) & _
-
"</description><code>" & Err & "</code></error></response>"
-
Exit Function
-
End Function
As first step, we will generate a NotesStream object with the text obtained at the beginning of the agent. The DXL types only support stream objects as parameters of entry, therefore we must take this step. Next we check if the object was generated successfully, otherwise an error message is returned in XML format.
To be able to convert XML into Domino objects, DXL has the class NotesDXLImporter. To generate a new object, we have to give the stream to be processed as a parameter and the database where to act (in this case the current database). Then, we specify the way documents will be imported. We choose “Update, otherwise create”. This option makes a new document to be created with the specified fields in case the server cannot find the document to updated. Finally, we call the Process method to carry out the importation.
According to planned, the provided XML will be imported to the database and will update the desired document. Therefore we return a successful reply in a pre-defined XML format.
As you can see, thanks to the use of DXL libraries (Dominio XML), it is not necessary to code the functions to process the XML, as this task is done by the Domino server. This way it becomes unnecessary to dedicate efforts to interpret the entering XML, or locate documents and fields, among others. We simply obtain the information we want to import and process it. In a few lines we have solved a problem which if it had been implemented with XML ad-hoc,, it would have generated longer time investment.
Note also, that if we’d like to update more than one document at a time, or create 3 documents and modify others, we wouldn’t have to re-code our agent.
The magic of AJAX
The action begins when you click on the button which opens the dialog, executing the following function:
Code 3 – Dialog opening
-
//Encabezado de la funciĂłn
-
function openPickList(dbPath, category, fieldName) {
-
//...
-
}
-
-
//Por ej, llamada desde el botĂłn del campo 'Subscriptions'
-
openPickList(getFieldValue('DbPath'), 'S', 'subscriptions');
This function receives as a parameter the database path, the category of options to display and the field identificator where the result of the selection should be stored.
Note: The field identificator must match the value of the field's property “id”.
Once our selection form is opened we load the options though a call to the function getOptions(). It is very useful to see it in detail.
Code 4 – Loading dialog options
-
function getOptions() {
-
var dbPath = getFieldValue("DbPath"); //Path de la base de datos
-
var category = getFieldValue("category"); //CategorĂa de las opciones
-
var url = dbPath + "/LookUpValues?ReadViewEntries&RestrictToCategory="+category;
-
processAJAXRequest("GET", url, "", "processOptions()");
-
}
We can see that values of database path and the category of the options you want to consult, are obtained. With this data an URL is made to consult the LookUpValues view. Here, it is important to highlight two points:
- The view is consulted using the ReadViewEntries command, to get to the information in XML format.
- The command RestrictToCategory is used to load the options of the desired category.
Finally, the call to the processAJAXRequest() will be done, who, in our case, is in charge of the communication with the server. Following, we described its functioning.
Code 5 – ProcessAJAXRequest Method
-
function processAJAXRequest(method, url, xml, returnFunction) {
-
var timeStamp = new Date().getTime();
-
url += "×tamp=" + timeStamp;
-
xmlhttp = new XMLHttpRequest();
-
xmlhttp.open(method.toUpperCase(), url, true);
-
xmlhttp.onreadystatechange = Function("processAJAXRequestLoaded('"+returnFunction+"')");
-
xmlhttp.send(xml);
-
}
-
-
function processAJAXRequestLoaded(returnFunction) {
-
if(xmlhttp.readyState == 4){
-
eval(returnFunction);
-
}
-
}
See that this function receives the following parameters:
- method: The method to be used when making the request to the Server (GET or POST, whether you want to obtain information or do any type of processing on the server side).
- url: The URL of the resource to request.
- xml: The content to be sent together with the request.
- returnFunction: Function to be called when obtaining an answer from the Server.
The XMLHttpRequest object is instanciated and the asynchronous process of the requested resource is done. It is important to say that it is not necessary to run verifications on the browser type. Please note that the use of Sarissa allows the code to be cross-browser. When a reply is obtained we call processAJAXRequestLoaded() function. As the status of the answer changes more than once, it is necessary to have it checked by this function. The values it can take are:
-
0 = uninitialized
1 = loading
2 = loaded
3 = interactive
4 = complete
Every time the status changes, the onreadystatechange event is triggered, in this case we will only process the reply when the request is completed, to be able to keep the simplicity of the development. To do this, we will process the reply when the status is 4.
The processAJAXRequest() and processAJAXRequestLoaded() functions, are our tools to have the communication with the Server at the AJAX style.
Continuing the development of the dialog, we were at a point when the request of the options is done. We do this by reading the view, called LookUpValues, in XML format, as shown below:
Example 7 - LookUpValues Inquiry
-
<?xml version="1.0" encoding="UTF-8"?>
-
<viewentries toplevelentries="17">
-
<viewentry position="1" unid="5D2D3FE74805400403257199006BE5BD" noteid="A12" siblings="17">
-
<entrydata columnnumber="0" name="value">
-
<text>Argentina</text>
-
</entrydata>
-
</viewentry>
-
<viewentry position="2" unid="1642D64F90F8A90B03257199006A488C" noteid="9EE" siblings="17">
-
<entrydata columnnumber="0" name="value">
-
<text>Brasil</text>
-
</entrydata>
-
</viewentry>
-
...
-
</viewentries>
This information is processed by the function processOptions(), which goes through the XML nodes and builds the HTML corresponding to the list of options.
So far we have explained how the initial loading of the dialog options and the rendering of the interface are done. We’ve seen which functions take part of the process and the structure of the consulted XML. At this instance, we will explain in which way the above described functions are called when adding or editing an option in the dialog.
A continuaciĂłn se describe la forma de dar de alta nuevas opciones y de modificar las existentes.
To add or modify an element from the list we call the function processAction(). The following diagram shows the sequence of functions involved in such action:

Figure 2 - Function processAction
To add a new entry, you must complete the field at the end of the picklist dialog and then press the button next to it. When pressing this button, the function processAction() is called, indicating that you want to add a new entry.
Code 6 - Function processAction
-
function processAction(action, obj) {
-
// Obtengo los datos claves para crear el documento
-
var dbReplicaID = getFieldValue("DbReplicaID");
-
var docUNID = "";
-
var docNoteID = "";
-
var fieldValue = obj.value;
-
var xmlRequest = "";
-
var urlRequest = getFieldValue("DbPath") + "/AJAXProcessor?OpenAgent";
-
var category = getFieldValue("category");
-
-
// Verifico que acccion realizar
-
switch(action) {
-
case "edit":
-
docUNID = obj.getAttribute("unid");
-
docNoteID = obj.getAttribute("noteID");
-
break;
-
case "add":
-
// Al agregar un documento, hay que especificar un UNID y Note ID inexistentes
-
docUNID = "01234567890123456789012345678901";
-
docNoteID = "01234567";
-
break;
-
}
-
-
// Genero el XML necesario para DXL
-
xmlRequest = composeDXLRequest(dbReplicaID, docUNID, docNoteID, category, fieldValue);
-
-
// Hago la peticion a AJAX para crear / actulizar el documento
-
processAJAXRequest("POST", urlRequest, xmlRequest, "getResponse()");
-
}
The first step is to get some data, as the replicaID of the database and the value you want to add, to pass as parameter when calling composeDXLRequest(). As reply, we will get the necessary XML for the DXL importer to generate a new document.
-
function composeDXLRequest(dbReplicaID, docUNID, docNoteID, category, fieldValue) {
-
var dxlDocument = "";
-
// Genero el XML con el formato especificado segun la DTD de DXL
-
dxlDocument += "<?xml version='1.0' encoding='ISO-8859-1'?>";
-
dxlDocument += "<document xmlns='http://www.lotus.com/dxl' version='6.0' replicaid='" + dbReplicaID + "' form='Option'>";
-
dxlDocument += "<noteinfo noteid='" + docNoteID + "' unid='" + docUNID + "' sequence='1' />";
-
dxlDocument += "<item name='category'><text>" + category + "</text></item>";
-
dxlDocument += "<item name='value'><text>" + fieldValue + "</text></item>";
-
dxlDocument += "</document>";
-
return dxlDocument;
-
}
We send this XML to processAJAXRequest() indicating that getResponse() will be the function to execute when the server returns the response.
Note: In case of creating a new document, we must inform DXL a UNID and NoteID not to correspond with any document of the database.
Once the server create the document, our AJAX engine, will call the function getResponse() which, after checking possible errors, will refresh the values list calling getOptions().
Below you will see how to create a new entry.

Figure 3 – PickList dialog with a new entry (Mozilla 1.0.1 - SUSE 9)
The process to edit an entry is identical to the explained above, except that when processAction() is called we will specify the method “edit”.
In the following figure we show how to modify an existing entry.

Figure 4 – PickList dialog modifying an entry (Internet Explorer 6 - Windows)
Finally, when clicking the OK button all selected options will be stored on the field of the parent window from which the picklist was opened.
Conclusions
We’ve shown, through multiple examples, the simplicity with which the back-end and the front-end of a Domino web application are integraded, as a consequence of the use of DXL and Sarissa, under a design pattern aligned with the concepts of AJAX. To this simplicity we can add the benefits offered by the development of applications of this type in aspects such as the lowering of the bandwidth in communications between the client and the server, the improvements in the times of reply and in the usability of the system, the simplification in codification, as well as the induction to standardize and re-use libraries.
Finally, we would like to dedicate some lines to point that although the use of AJAX becomes a very useful tool, in some occasions doesn’t seem to be a good option. For example, the introduction of AJAX could substantially complicate its implementation in very simple applications to be developed under the concept of synchronous communication between the client and the server, that is applications which, because of their simplicity in development or codification don’t justify the investment of time needed to develop the client’s functions under the concept of asynchronous client-server communication. In the case of the demo we have developed in the article, for example, it wouldn’t have made sense to load the contacts details in an asynchronous way. The reasons is clear if we compare the amount of time needed for developing the client's functions for loading the user's interface in asynchronous way, against that needed to develop a simple form.
Therefore, if the objective is to improve the user’s experience with the use of the new technologies, it is important not to miss the fact that the best results are not obtained from its unreasonable use but they come from evaluating and selecting in which precise moments of a system it is convenient to use the dynamic and asynchronous technologies in clients-server communications.
Document options
Reference
- DXL
DXL: Including XML in Designer applications (Base de Ayuda de Lotus Notes Designer) - AJAX
Ajax: A New Approach to Web Applications - http://adaptivepath.com/publications/essays/archives/000385.php
(y miles de artĂculos más en la web) - Sarissa
Sarissa - http://sourceforge.net/projects/sarissa - HTML
- HTML
W3C Form submission - http://www.w3.org/TR/REC-html40/interact/forms.html#submit-format
About the authors

Andres Sommariva, Senior I/T Specialist, MicroGestion Andres Sommariva, Senior I/T Specialist, MicroGestion
Andres Sommariva se desempeña como Team Leader en el area de consultorĂa de MicroGestion, con cuatro años de experiencia en proyectos basados en J2EE ha utilizado XML y AJAX en el desarrollo de soluciones complejas para empresas de primer nivel utilizando IBM WebSphere Application Server.

Matias Moncho, Senior I/T Specialist, MicroGestion Matias Moncho, Senior I/T Specialist, MicroGestion
Matias Moncho es desarrollador Senior del area de consultorĂa de MicroGestion, especializado en IBM Lotus Domino (CLP R5 y R6) ha incoporado desde el año 2002 tecnologĂas como DHTML, XML y AJAX para el desarrollo de aplicaciones web centradas en el usuario.








Nice article and well explained!
stw
I would love a followup article where you use the Dojo toolkit and replace the popup windows with Dojo Layers.
Hello Gentlemen
This is a good job but it’s not organized to build an example,
I spent almost one day to see what I can do the function, but I couldnt do anything.
please, if possible, send me a steps of how could I build a working example.
Thanks