Multi-informatica
 

 

 

Products

 

Resources

 

 

 

Ajax for Intraweb

Download delphi example implementing the Ajax

Intraweb has become a very popular library to make web server programs. It makes transparent many web programming inconvenients for the programmers. For example, to make the first IntraWeb program it is not necesary to write any HTML code, besides our application will run in several independent users in simultaneus way, it means, intraweb is encharged of management of the different user sessions. There are a lot of aids which intraweb offers for programming. However, it uses a classical/traditional scheme of web programming. The main user actions in the web browser trigger a http request in the web server. The server processes the request () and as a response to the client there is a HTML document page. This model is an adaptation of the original use of the Web as hipertext media, but it is not necessary the best one for making software applications.

When a user changes any data, this change can involve other changes in the fields of showed information, but this change is produced only when we refresh the page.

We would like a more active response in our application. And the data changed by the user could produce other changes in the page without refreshing again.

Here we introduce the AJaX concept. The kernel code of an AJaX component is a JavaScript code wich connect with the server to make request, and handle the responses. As this responses, generally produce changes in the user interface, AJaX is associated to GUI libraries in JavaScript which enhances the use of windows and/or more complex controls than traditional.

We want a simple target: We want only to exchange the data user input with the server which produces little changes in the interface ( in labels and edit fields)

We will center our attention on GpAjax1.js, which is our first approach to this technique. It is inspired in a good article in http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/

 


//	 AJaX plugging  
var request;

function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
}

Because of differences between Microsoft and other browsers, we must try different way to create the object. The most important thing to understand in this code, is that we are creating the object to make request the server.

Now, there is the most important 'trick' in this article; We must use the request object to make the query to the IntraWeb server. But IW has its own rules to make this request. The first is that it does an automatic management of user session. The information of the user session must be implicit in the http request ( in the URL and/or in the cookies or hiden fields). So, if we don't want any problems in the management of the request in lower level way, we will need to manage this request as another normal action (for example a click of the button )

Here, we must see how an user action is processed in the correct user session form in the IW server, reffering to an object in this form, and sending to it any param or command, which must produce an active response ( sending a file for example), or pasive (making 'internal' operations which produces the changes in the page by loading again). A web page generated in IW, generally uses 'POST' commands to exchange information with the server. It sends the data in the associated fields to this POST * and it adds at least 4 fields more that make references to the form, object and the action or command to this object.

IW_FormName : Form name, which content the response handler.

IW_FormClass: Class name of the form.

( This can be not necesary in our case, but we will maintain it for compatibility )

IW_Action : Object name which handle the response.

IW_ActionParam : Paramethers or commands passed to this object.

* We must remember than is a POST request call, the data are sended as following character secuence.

NameField1="Value1"&NameField2="Value2"....

That is the fields are represented as a name, the sign =, and a value. And to separate different fields the sign & is used

Now, we have all the params to make the AJaX call.


var hostAjax;
var formName;
var formClassName;
var actionObject;
function getElemento(nombre,valor) { createRequest();
// alert (sss); var cmd = "/ajax"+nombre+"=" + escape(valor); var url = hostAjax+"?"+cmd; request.open("POST", url, true);
request.onreadystatechange = updatePage;
var sss="IW_Action="+actionObject+ "&IW_ActionParam="+cmd+
"&IW_FormName="+formName+ "&IW_FormClass="+formClassName;
request.send(sss); }

As you can see, we use a function updatePage. This function can be something like the following code:

function valor (s) {
var sepa = s.split("=");
elemen=sepa[0];
va = sepa[1];
// processAjax (elemen,va);
}


function updatePage() {
  if (request.readyState == 4) 
  {            
   if (request.status == 200) 
     {
var response = request.responseText.split("|");
for (var i = 0; i < response.length; ++i) {
valor (response[i]);
}
} else alert("status is " + request.status);
}
}

 

As the use can be different, the limit is your imagination to send request or receive responses from the server, and handle it with JavaScript code.

In out example we will receive the response fields as following secuence:

NameField1="Value1"|NameField2="Value2"....

In updatePage function, we divide the fields (separated by '|' char), and send each of them to an abstract function processAjax, where the content of NameField and Value will be interpreted.

A very simple code can be the following:

function processAjax (elemen,s)
{
if (elemen) {
var el=document.getElementById (elemen);
if (el) { elemNodeName = el.nodeName; var os=elemNodeName.toLowerCase(); if (os == "input" || os == "select" || os == "option" || os == "textarea") { el.value = s; } else { el.innerHTML = s; }
} }
}

It is not so sophisticated but it is effective in many cases. The generated HTML information in our IW application, is usually HTML labels with assigned Name or ID params , which means that each important label has a name and it can be assigned by JavaScript.

That will be a bit problem to make the responses in the server, because we must use these names to locate the objects both in server and client.

Now we only need to trigger the event which calls the AJaX function. We will use the onBlur event in the INPUT fields in the HTML form.

 



function getAjax (sender) {
var el = document.getElementById(sender);
if (el) {
var valor ;
if (el.value) {
valor =el.value;} else
{valor ="";}
return getElemento (sender,valor);
}
}

<input type="TEXT" name="IWDBEDIT2" id="IWDBEDIT2" onBlur="getAjax('IWDBEDIT2')">

 

The previous AJaX example can produce problems in the actual use, due to the use of global variable (request and responses), different simultaneus AJaX commands can interfere in each other.

The clue is to encapsulate all the AJaX functionallity in a JavaScript object, so as that each one of the AJaX simultaneus calls have their own 'local vars'.

We will use a function called miAjax (host,forma,clase,accion), which generate the object instance which is used to make the process. We will include other minor functions for more flexibility functionallity.

The FindNameId function to locate the HTML label by name or ID. First, it try to locate the element by using the standart IW/JS FindElem function (which try to locate a form element by the name), and if it is not finded then try with generic JavaScript function : getElementById (wich try to find the element by 'ID'). The processAjax function is very similar than the previous example..

 


function FindNameId (nombre) { 
var el = FindElem (nombre);
if (!el) {el = document.getElementById(nombre); };
return el;
} function processAjax (elemen,s){
if (elemen) { var el=FindNameId (elemen); if (el) { elemNodeName = el.nodeName; var os=elemNodeName.toLowerCase(); if (os == "input" || os == "select" || os == "option" || os == "textarea") {el.value = s; } else { el.innerHTML = s;} } } } function SetComando (s) {
if (s!="none") {
var sepa = s.split("=");
processAjax (sepa[0],sepa[1]);
}
} function mai (host,forma,clase,accion) {
this.request = null; this.hostAjax = host;
this.formName = forma; this.formClassName = clase; this.actionObject = accion; this.responseStatus = new Array(2); this.onLoading = function() { }; this.onLoaded = function() { }; this.onInteractive = function() { }; this.onError = function() { }; this.createRequest = function createRequest() { try
{ this.request = new XMLHttpRequest(); }
catch (trymicrosoft)
{
try
{ this.request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (othermicrosoft) { try { this.request = new ActiveXObject("Microsoft.XMLHTTP");} catch (failed) {this.request = null;}
}
};
if (!this.request) {alert("Error initializing XMLHttpRequest!");}; }; this.getElemento =
function (nombre,valor)
{
var cmd = "/ajax"+nombre+"=" + escape(valor);
var url = hostAjax+"?"+cmd;
this.request.open("POST", url, true);
var self=this;
this.request.onreadystatechange =
function() { switch (self.request.readyState) { case 1: self.onLoading(); break; case 2: self.onLoaded(); break; case 3: self.onInteractive(); break; case 4: self.responseStatus[0] = self.request.status;
self.responseStatus[1] = self.request.statusText; if (self.responseStatus[0] == "200") {
var respon = self.request.responseText.split("|");
for (var i = 0; i < respon.length; ++i) { SetComando (respon[i]); };
} else {self.onError();}; } }; this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var sss="IWGRANPRIMO1=&"+"IW_Action="+actionObject+"&IW_ActionParam="+cmd+ "&IW_FormName="+formName+"&IW_FormClass="+formClassName ; this.request.send(sss); }; this.createRequest();
return this;
}


 

 

 

¿ What happens with the server?

Basically, the response to AJaX commands, can be done in the servercontroller or in the form which generated the page.

Doing it in the servercontroller, can be usefull in 'automatic responses', (which are not dependent on the user or the form), for example, simple operations or file services...

Make it in the form is necessary if you want to identify the user session or if other objects in the form must be used. Although you must consider that the changes in the form are not rendered in the normal way, because there is not any refreshment of the page.

In our AJaX call, the server receive the command as other 'normal' call, submiting the Ajax request in following format:

("/ajax"+)ElementName=Value

So, we have the name of the HTML element which has changed, and the new value.

To process it, we must to do the following steps:

1- Find wich element in our form is the refered control by ElementName.

2- To cause the change of the new value of that element

3- To locate that other elements of form must change

4- To send these changes to the client Web .

It is complicated to offer a generic solution for all the cases, by the so great number of different objects that can be used in form IW.

In our first TIwAJaX component we want to give solution to a simple situation :

We have a form of data input to a table. In a typical desktop application , as we introduce fields in the form of data, these can cuase changes in other fields of the data base or in the calculated fields (since they go off to events onCalcFields, onDataChange...)

This we want to do it in IntraWeb, that as we enter data in each one of the fields of the form, these will be sent to the serve, triggering the events oncalcfields in the table and we will give back that elements than have been changed, to the form Web.

We will use the following example :

It uses the table country of dbdemos database. Country, Population and Area are phisical fields in the table, and Density or extended are calculated fields.

When we change the population or area fields, then Densisty label will change too.

As if you change country or population fields, the extended information will change too.

Download delphi example implementing the Ajax

order

Related articles

http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/

http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/

http://blogs.phparch.com/mt/?p=51

Links

http://blog.marcocantu.com/blog/ajax2.html

http://ajaxpatterns.org

http://weblogtoolscollection.com/archives/2005/03/21/some-ajax-links/

AJaX Platforms

http://www.backbase.com

http://www.orbeon.com/

http://www.telerik.com/

http://bennolan.com/behaviour/

http://ajaxpatterns.org/Ajax_Frameworks

Examples

http://www.start.com/

 

Articulos en castellano:

http://www.uberbin.net/archivos/internet/ajax-un-nuevo-acercamiento-a-aplicaciones-web.php

http://adaptivepath.com/publications/essays/archives/000385.php

 

 

 

 

   

 

 

 

Teléfono: 978-610539 - Fax: 978-610861 -Trav.Agustina Aragón 1,1e 44002 Teruel ( España ).webmaster

Copyright © 1997-2004 , [Multi-Informatica Teruel, S.L].La información contenida en este documento está sujeta a modificaciones sin previo aviso. Otros productos u organizaciones mencionadas aquí son marcas comerciales o marcas registradas propiedad de sus respectivas organizaciones o propietarios.

  Zapatec