Donnerstag, Dezember 29, 2005

An AJAX enabled bible reader

Handbook

This is a small documentation for the online available Bible Reader at http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx.

The reader can be started just by opening a window with the given URL. The page loads completely and starts with one of the available versions (of course) on the first book, first chapter, first verse: "In the beginning...".

You can select one of the server-side installed bibles by using the first select box:

sf_kjv_strongs_rev1b:A English version of the bible.
en_gb_KJV2000_1:A more modern English version of the bible.
luther1912:A German version of the bible.
biblehebr:a Hebrew version of the bible.

Yes, it's right to left - Does it look right?
I see some differences between FireFox and IE.
Maybe anyone can help on that topic !

In the second select box you can choose one of the available book. Some bibles provide names for the books, others don't and you have to use the given numbers. The New Testament starts with book 40.

In the third select box you can choose the chapter you want to read and in the forth select box you can finally choose the verse.

As you change the values of these select boxes you will see that the select lists will be updated automatically so that only valid entries are available. If you choose a book, the list of chapters will be updated, If you choose a chapter, the list of verses will be updated...

In the big text box below the text of the selected verse will be shown.

It is possible to change the version without changing the selected book, chapter and verse so you can easily switch between German and English or different English versions.

Below the text boxes are 2 buttons that enables the forward and backward navigation cross all book and chapter boundaries in a given version.

You navigate across multiple 5 MByte sized books. Fast !

Technology

The published web page available at http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx is already a AJAX application and more than just a small technology driven demo page that shows how to use a specific control or piece of code.

I started working on this application to show how it all works together and to see where we need common functionality and what features we need within the controls.

Cascading Select Elements

The 4 select boxes at the top of the page are dynamically linked together by raising and listening to some page-level data connections. Together they form the cascading 4-level specification of the available verses.

Here, the AJAX Select box control is used together with a AJAX action and some JavaScript code. The chapter select box is defined by

<ajax:Select id="ChapterSelect" runat="server" pageproperty="chapter" style="width: 120px">
</ajax:Select>

and the JavaScript code just below it reacts on changes of the version or the book. The AJAX Action is used to fetch all the Chapters from the server by using the BibleData WebService and the ListChapters method.

<script defer="defer" type="text/javascript">
  var obj = document.getElementById("ChapterSelect");
  obj.GetValue = function(prop, value) {
    if (((prop == "version") || (prop == "book")) && (jcl.DataConnections.GetPropValue(prop) != value)) {
      ajax.Start(this.ChapterAction, this);
    }
  }; // GetValue
  jcl.DataConnections.RegisterConsumer(obj, "*");

  obj.ChapterAction = {
    delay: 10,
    prepare: function(obj) {
      key = jcl.DataConnections.GetPropValue("version")
       + ";" + jcl.DataConnections.GetPropValue("book");
       return (key); },
    call: proxies.BibleData.ListChapters,
    finish: function (value, obj) {
      obj.CreateOptions(value);
      if (obj.selLast == true)
        obj.options[obj.options.length-1].selected = true; 
      obj.selLast = false;
    },
    onException: proxies.alertException
  }; // ChapterAction
</script>

Very similar scripts can be found for the other 2 cascaded select boxes.

Retrieving the Vers Text

To fetch the vers text, another AJAX action, named VersTextAction is used. The 4 properties version, book, chapter and vers are retrieved and passed to the BibleData WebService and the GetVers function. The returned text is then written into the text area.

obj.VersTextAction = {
  delay: 10,
  prepare:
    function(obj) {
      key = jcl.DataConnections.GetPropValue("version")
       + ";" + jcl.DataConnections.GetPropValue("book")
       + ";" + jcl.DataConnections.GetPropValue("chapter")
       + ";" + jcl.DataConnections.GetPropValue("vers");
      return (key);
    }, // prepare
  call:
    proxies.BibleData.GetVers,
  finish:
    function (value, obj) {
      obj.style.direction = ((jcl.DataConnections.GetPropValue("version") == "biblehebr") ? "rtl" : "ltr");
      obj.innerHTML = value;
    },
  onException:
    proxies.alertException
}; // VersTextAction

A very similar AJAX Action is used to look for a Prolog Text that might be describing the current book. The rest of JavaScript programming is for the sequential navigation through the verses, chapters and books.

On the Server a ASP.NET WebService, written in C# with 5 methods is used to deliver all the data that is needed by the Bible Reader Web page. see: http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BibleData.asmx

That's all. All the source you need for this application has only about 15 kByte of text. You might not get any application of this functionality with less coding.

Programming AJAX Web Applications can be easy and without a lot of source code if you choose the right technology and level of programming.

Dienstag, Dezember 20, 2005

Powerpoint Slides on AJAX

I had to give a speech at the Karlsruher Software Council about AJAX some days ago.

Now I've posted the Powerpoint slides titled "AJAX – Hype and Reality" on my site at PowerPoint Slides on AJAX

There are really a lot of low level articles on AJAX that explain how to use te xmlhttp object. My summary on that: Have a look at the productiviy of yourself or your programmers and find a useful level of abstraction above the native xmlhttp objects.

Maybe you find the slides useful.

Donnerstag, Dezember 15, 2005

JavaScript Proxies for WebServices extended

I updated the bits on the AJAX Engine site some days ago. There are some new features I want to let you know:

  • WebServices with arrays of primitive types (strings, numbers etc) are now supported by the generator of the JavaScript Proxy objects and the client side runtime in ajax.js. Have a look into the inline comments.
  • There is now a new sitemap available for the whole site. You can find the link on the home page at http://www.mathertel.de on the left side. It's very easy now to discover all the posted source code files.

Mittwoch, November 16, 2005

Moving the server

Update you favorites ! (and I hope that my AJAX project is part of them)

Thanks to http://www.centron.de I could host the samples live on a beta web site for ASP.NET 2.0 for free, but that time is over soon.

I decided to move my personal domain http://www.mathertel.de/AJAXEnginethat moved to a ASP.NET 2.0 enabled host so I can put both sides together.

If you have saved a link to the AJAX Demo WebSite you should update this link.

You can find the new samples at http://www.mathertel.de/AJAXEngine and the documentations at http://www.mathertel.de/AJAX.

This blog and the rss url will stay here, but I plan to bring the valuable content into a eBook that I started some time ago.

Stay tuned.

Sonntag, November 13, 2005

Tuning TableData

After realizing the first working version of TableData I found several things that did not work as expected so I published a better version with some enhancements.

Speed

The first version (still available here) retrieved the row from the WebService one row each time. The time that is needed to update a page full of visible rows was only a second or two when developing on my local system but is about 4-6 second on the real internet. The reason for this slow down is the time a package needs to be transferred from the client to the server and back. You can use the tracert command (tracert www.mathertel.de) line tool to verify this timing. You can see how long an almost empty package needs to be transferred and that is extremely longer than a package that doesn't leave a development machine. Reducing the number of packages is the key and I decided to bundle the Fetch call for all newly visible rows together into a singe call to the server.

FireFox compatibility

After some months of working with both browsers (IE and FireFox) I've got some experience in implementing one source for both browsers - but forgot to test.

I fixed some minor things:

  • The parentElement attribute of the html dom should not be used. Use parentNode instead.
  • The firstChild attribute might get a text node in FireFox that is skipped or not existing in IE. Whitespace should not be used between a parent node and the fist child node.
  • The onscroll event it is not documented but works as expected in FireFox. Great !

Reusability

When trying to reuse the controls on a different project I found that I need more parameters to make them portable. The name (alias) of the service that is used for selecting and fetching the data is now configurable.

Freitag, November 11, 2005

Displaying huge tables using AJAX

There are many implementations available in the ASP.NET framework to display tabular data. Most of them send the content of the table to the client as a part of the page including all the other parts of the page. If it comes to mass data situations the implementations offer a mechanism to navigate through pages containing a smaller set of the records and sending the whole page again and again.

Here comes another approach that offers paging and scrolling even with huge datasets without refreshing the page that uses AJAX calls to a WebService to fetch the data.

If you have followed by posts in this blog or the documentation on the sample web site you can easily identify the AJAX part of the sample. Most of the JavaScript you can see on the client is written to handle all the events and the HTML DOM operations.

In fact it's a 3 steps approach:

  1. When the page loads an empty table that acts as the template is downloaded to the client. No data integration is needed for this pahse to finish.
  2. Then a query is started by passing some parameters to the WebService that selects all the rows that should be displayed and returns a unique ID for each row.
  3. Then every row that is visible is fetched from the server using another WebService call that returns a XML document for each row.

The amount of data that is transferred has some overhead in the case of the first page that is displayed but if you scroll down to the next page by using the scrollbars or the page navigation buttons, only the new row data is fetched from the server - far less than a whole page refresh. It gets better when you scroll back to a region or page that was already displayed because the data is already on the client and can be displayed without requesting the server at all.

Also when you request another set of records by using another sort criteria all the rows that are already known on the client can they can be displayed without fetching them again from the server.

As you can imagine, using this approach it is possible to send huge tables to a client without the need to send all record data immediately.

Give it a try and check out the sample implementation at: http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TableData.aspx.

First select some data using one of the 3 Select buttons. You can now page through the recordset or (by favorite) press the all-button and scroll through the table. You can see the deferred loading of the table rows.

The implementation consists of a WebService, 2 Web Controls and the AJAX Engine that does the asynchronous communication and the caching.

DataTablePager Control

The DataTablePager is the client side controller of the MVC pattern and is an AJAX Control that implements the AJAX action for retrieving the dataset on the client side.

There are some methods available that can be used by additional buttons to load a specific view or to clear the actual data.

Buttons can use these functions to select rows by supplying a filter and a sorting criteria.

The events that are triggered by scrolling the table also use methods of this control to fetch data from the server.

DataTable Control

The DataTablePager is the client side view of the MVC pattern and is responsible for dynamically building up the table that displays the record data fetched from the server formatted by the format given by the template row.

When the page load the template gets saved and when new row data must be shown this template is copied for every row that should be displayed.

Right now there is only a very simple template processing functionality implemented that can only display columns as simple text and the template is constructed on the server by interpreting the cols attribute of the datatable tag.

Every time a row gets visible a fetching the data is initiated by calling the DataTablePager Control's FetchRow Method.

When data comes back from the server the AJAX Action will call the DataTable Control's FillRow method to fill up the corresponding row with the record data.

The TableData WebService

The WebService that is used by the AJAX Actions of the DataTablePager Control is the server side model of the implementation. This WebService must implement the methods defined by the ITableData interface.

To bind all 3 elements together only some lines of coding are needed and the sample page itself, containing the controls and the WebService’s proxy, has only some specific attributes that must be set. – Have a look.

I see still some optimization potential in reducing the number of call to the server by bundling the records that got visible together into a single WebService call. – Stay connected.

Donnerstag, Oktober 13, 2005

CustomValidation AJAX Control Sample

The ASP.NET Web Forms offer a collection of validation controls out of the box to check the values in the fields of a form. The validation process takes place in 2 situations:

  • When the form data is sent back to the server a specific server-side functionality of the control or the page is called.
  • When the user changes the value of a field and leaves the field a specific client-side function is called.

Now, with the help of AJAX and the possibility of asynchronous calls to the server in the background a third kind of validation can be implemented without great effort and combines the power of the server side processing with the good user experience of the immediate verification in the client.

When the user changes the value of a field and leaves the field a specific WebService can check the value.

The implementation is obvious.

1. We use the built-in CustomValidator control to attach a client side function:

<input autocomplete="off" id="EMAIL_IN" runat="server" name="EMAIL" />
<asp:CustomValidator ID="CustomValidator1" runat="server"
  ControlToValidate="EMAIL_IN"
  ErrorMessage="Please enter a valid e-mail address." 
  ClientValidationFunction="validateEMail">*</asp:CustomValidator>

2. The client-side validation function that is used by the control as specified by the ClientValidationFunction attribute always leaves the arguments.isvalid flag set on true (default) to hide any shown error and then start the Ajax action with the source object as parameter.

function validateEMail(source, arguments) {
  ajax.Start(validateAction, source);
} // validateEMail

3. The AJAX action needs to be declared and is based on some implementation details of the client-side validation mechanism:

var validateAction = {
  delay: 0,
  prepare: function (source) {
    // from the Validator Common JavaScript
    return(ValidatorGetValue(source.controltovalidate));
  },
  call: proxies.ValidatorDemo.ValidateEMail,

  finish: function (val, source) {
    // from the Validator Common JavaScript
    source.isvalid = val;
    if (! val)
      Page_IsValid = false;
    ValidatorUpdateDisplay(source);
    ValidationSummaryOnSubmit(null);
    },
  onException: proxies.alertException
} // validateAction

There is nothing data-verification specific here except the link to the WebService we use to validate e-mail addresses so the declaration can be reused for different purpose.

The integration of the Ajax action is a little bit tricky as you can see because the validation process of the built-in validation controls of ASP.NET do not expect any asynchronous processing but wants an immediate decision to be taken and the Validation Summary sometimes does not update correctly.

The WebService itself can do what ever it wants to do. In my sample I use the Dns class to resolve the domain name and check if it exists. That cannot be done by the client and is a sample for the power you have on the server available, but not on the client on its own.

The sample can be found at http://www.mathertel.de/AjaxEngine/S03_AJAXControls/ValidatorDemo.aspx

Montag, Oktober 03, 2005

Using AJAX enabled controls in ASP.NET Forms

The use of web forms is for many web applications the most important functionality. They rely very much on it because it was implemented by all old browsers they also the modern ones still provide this functionality.

Using AJAX functionalities in your web applications doesn't mean that everything needs to be re-implemented. With the AJAX functionality these applications can easily be extended with controls using asynchronous functionalities in the background without breaking up the existing applications structure:

  • Validate values immediately on the server after the user exits the field without reloading the form.
  • Help the user to find the right value by extending a field with a specific lookup function.
  • Show or hide a field, depending of already entered values.
  • Fill fields in the form, depending of already entered values.
  • Fill the OPTIONS of HTML SELECT elements depending of already entered values.

Common to these scenarios is that a pure client-side implementation is often hard to do or impossible because some data is required and this data is not available on the client directly. On the server in contrary, the information is available and is in classical Web Forms used to validate the input of the user before accepting and executing the functionality.

If you integrate AJAX controls into your existing web applications it is possible to make your forms more responsive and give faster feedback and help to the user. The processing of the Web Form can stay as it is by submitting the data of the form to the server and reloading or redirecting the page after the server side processing is done.

On the sample website to this Blog at http://www.mathertel.de/AjaxEngine/Default.aspx you can find some samples that show the usage of AJAX based functionality in regular Web Form applications:

Validator Demo

http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ValidatorDemo.aspx shows how to use a server-side DNS lookup to check if the host part of an email address is known on the web without reloading the whole form.

Bible Reader

http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx here you can see beside other things how to populate OPTIONS of a HTML SELECT element dependent of other values without reloading the whole form.

Montag, September 19, 2005

Connecting Controls

Separating and encapsulating the functionality into components helps to build a reusable framework. But most components do not exist alone but must be linked to other elements.

The classical approach

When using the standard built-in controls of ASP.NET you will use the events that are exposed on buttons, fields and the page and write small methods that response to these events. Inside these event handlers you reference to other objects directly because they are part of the page or control class or by using their id or at runtime unsing a search method.

These handlers are executed by using a submit() of the HTML form element - a post-back situation that should not happen in AJAX applications. We need a solution on the client side of the application in JavaScript.

You can also follow this approach on the client by writing event handlers and attaching them to the native HTML events of the HTML objects.

The drawback of these architectur is that when using complex controls the object that exposes this event might be an inner part of the control without an id or maybe not existing while the page is still loading.

If you want to follow this approach you can use jcl.AttachEvent. This is a method from jcl.js include file that you can use for this purpose and that works across the browser platforms and that allows multiple event registrations..

Even when you know all inner details of the actual control you might not want to use that knowledge because you will give away the chance to extend or re-implement a control without also changing all the implementations on the pages.

The WebPart approach

With Sharepoint and the ASP.NET 2.0 WebPart Framework came another mechanism of connecting components by using a provider-subscription pattern. Components can register themselves for publishing (provider) or consuming (subscription) a specific property-value. Every time when the value of a property changes in a provider all controls that registered a subscription for this property are informed about that.

There are some advantages for this approach:

  • It works even if the controls that build up a page are not known at compile-time. (Sharepoint)
  • Multiple controls can easily publish the same property.
  • Multiple controls can easily consume the same property.
  • We do not need any browser- or object-specific events.
  • The IDs of the objects must not be known.
You see that this is a higher level approach that fits better into the problem space of component based pages and portals and it can in addition be combined with the eventing model of the native HTML objects.

The Connection Test Sample

This sample uses 3 kinds of controls implemented with JavaScript Behaviours to show (and test) the implementation and usage of the client side controls connections. There are 3 properties used in this sample (x, y and z) that can be modified by 2 different Controls and that are visualized by a simple bar chart.

See: http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ConnectionsTestPage.aspx

PropInput Control

This control renders a HTML input element that is extended by a JavaScript Behaviour to raises a change of its value to the property that is specified by the "name" attribute.

This control also registers itself as a consumer to display the actual value when changed by another control.

PropHSlider

This control implements is a horizontal moveable rectangle that acts as a slider. It can be used to change a property value that is specified by the "name" attribute in the range from 0 to 100.

This control also registers itself as a consumer to display the actual value when changed by another control.

PropBarChart

This control implements a simple bar chart to display multiple values. The names of the properties are displayed below the bars.

The names of the values can be specified by the "properties" attribute by using a semicolon separated list of names.

The max displayable number can be specified by the "maxvalue" attribute. This value is used as a scale factor for the display.

PropEventLog

This control logs every change of any property and lists the new value on the page.

DataConnections Reference

The names of the properties are always converted to lowercase characters so they should only be compared by after a toLowercase conversion.

DataConnections.RegisterProvider(obj, propName)

An object that provides a property must register itself using this function.

The name of the property set to a '*'-character to register for all existing properties.

DataConnections.RegisterConsumer(obj, propName)

An object that wants to be informed about the values of a property must register itself using this function.

The name of the property can be specified by a star-character to register for any properties that exist on the page.

DataConnections.Raise(propName, propValue)

This function must be called to raise the change of a property. All registered objects for this property get their GetValue method are called immediately.

DataConnections.GetPropValue(propName)

This function can be used to poll the actual value of a property. This eliminates the need for implementing a array of the current values of the properties an multiple controls.

DataConnections.PersistPropValue(propName)

Using this function a property can be persisted into a cookie value and will be raised when the page loads again. This help a lot for surviving page reloads.

The used cookie is not a permanent cookie so the content will be not available after the browser was closed.

control.GetValue(propName, propValue)

This function must be implemented by a control to receive the notification changes.

Freitag, September 16, 2005

Anatomy of an AJAX Control

AJAX Web Control architecture

Writing an AJAX enabled control (here AJAX Control) is as easy as writing another AJAX enabled web applications. The only difference lies in the kind of separating HTML, JavaScript and the clueing stuff like AJAX Actions and Server calls into the right places so that the control can be reused in other places.

If you just want to separate a part of your application so that other members of the team can work on it separately then you can place all the code of the control into the User Control’s *.ascx file.

You should be familiar with the technique of the <ajax:Lookup ... LookUpService="OrteLookup" ... />


What you see here is NOT HTML code but a descriptive declaration of rendering some HTML code here. When using ASP.NET User Controls these attributes do not get automatically rendered as HTML attributes. Instead the ASP.NET framework matches them to properties of the class that builds the control on the server. So any attribute that is used as a parameter must also be defined as a field or property of the control’s class to make the value available on the server.

<%@ Control Language="C#" ... %>
<script runat="server">
  public string lookupservice = "DefaultService.asmx";
  ...
</script>

To make it available on the client the values of these members must then be written out in the HTML code that is generated by this control:

<input ... lookupservice="<%=this.lookupservice %>" ... />

The consequence of this is that the default-values for parameters that are not specified in the source code must be specified in the initialization of the class members and that values assigned to in the JavaScript prototype objects are always overridden.

Writing specific HTML code for a User Control is simply done by writing it down at the end of the *.ascx file. It can be as complex as you like it to be.

Be sure to also add the unique id of the control into the generated HTML code:

id="<%=this.UniqueID %>"

An ASP.NET User control doesn’t automatically create an outer HTML object. It is also possible to generate multiple objects in a row. In this case the JavaScript behaviour is attached to the object that is assigned the unique id.

If you need a reference to another web resource you can use the ResolveUrl method of the Page object:

src="<%=Page.ResolveUrl("~/controls/images/drop.gif") %>"

Programming the Behaviour

The specific JavaScript behaviour that should be used to implement the client-side functionality for a User Control should be implemented in a separate JavaScript include file. This is not strictly necessary but is good for the overall performance because it can be cached in the browser.

I use the same name as the *.ascx file for this control specific include file and place them all into the ~/controls folder.

To attach the behaviour to the html object a small JavaScript fragment is also part of the rendered HTML code:

< script defer="defer" type="text/javascript">
  jcl.LoadBehaviour("<%=this.UniqueID %>", LookUpBehaviour);
</script >

AJAX Actions

The AJAX Action that is used by the Control can be declared as a part of the Behaviour’s prototype object. In the LookUp Control you can find the _fillAction property that is the declaration object of the AJAX Action.

// declare an AJAX action to the lookup service
_fillAction: {
  delay: 100,
  prepare: function(fld) { fld.savevalue = fld.value; return (fld.value); },
  call: null, // is assigned later
  finish: function (val, fld) {
    if (fld.savevalue != fld.value) {
      ajax.Start(fld._fillAction, fld); // again
    } else {
      var dd = fld.CreateDropdown(fld);
      fld.FillDropdown(dd, val);
    } // if
  }, // finish
  onException: proxies.alertException
}, // _fillAction

If you only have one single instance of the Control on the page you will not get into trouble. If there are multiple instances of the Control on the same page these actions definitions will be shared by all controls so you better make a copy of it using the jcl.CloneObject function because they will use different WebServices.

The reference to the WebService should also be set in the init function after the page was loaded because it is not guaranteed whether the WebService proxies are already setup correctly when the behaviour is attached.

this._fillAction = jcl.CloneObject(this._fillAction);
this._fillAction.call = proxies[this.lookupservice].GetPrefixedEntries;

Registering the script includes

Before the HTML text is send to the client all the JavaScript include files that are needed by the control must be registered on the page. This can be done in the OnPreRender method:

protected override void OnPreRender(EventArgs e) {
  base.OnPreRender(e);

  ...

  // register the JavaScripts includes without need for a Form.
  if (!Page.ClientScript.IsClientScriptBlockRegistered(Page.GetType(), "CommonBehaviour")) {
    Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "CommonBehaviour", String.Empty);
    ((HtmlHead)Page.Header).Controls.Add(new LiteralControl("<script type='text/javascript' src='"
      + Page.ResolveUrl("~/controls/jcl.js")
      + "'><" + "/script>\n"));
  } // if

  if (!Page.ClientScript.IsClientScriptBlockRegistered(this.GetType(), "MyBehaviour")) {
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyBehaviour", String.Empty);
    ((HtmlHead)Page.Header).Controls.Add(new LiteralControl("<script type='text/javascript' src='"
      + Page.ResolveUrl("~/controls/LookUp.js")
      + "'><" + "/script>\n"));
  } // if
} // OnPreRender
p>All the code fragments can be found in the third part of the samples:

OrteLookUp.aspx is the implementation of the page,

~/controls/LookUp.ascx is the first visible control and

~/controls/LookUp.js is the corresponding JavaScript Behaviour.

Mittwoch, September 14, 2005

AJAX Engine documentation update

Today I updated the documentation of the AJAX Engine.

See http://www.mathertel.de/AJAX/Aspects%20of%20AJAX_index.htm.

It’s not necessary any more to read the articles from the end to the beginning because they layer upon each other partially.

ATLAS

The AJAX Framework from Microsoft called ATLAS was published yesterday. I am glad to see that Microsoft follows my idea of generating proxies for WebServices.

They use a JSON syntax and not SOAP or WSDL for the communications so it’s not very portable to other server-side platforms.

Dienstag, September 13, 2005

Using ASP.NET

When using ASP.NET on the web server some things become easier because it brings a built-in framework for reusing HTML code fragments, building controls and components and managing some useful things around it. I will use some features of the page model, ASP.Net user controls and Web Controls here to make it easy building AJAX Controls.

Together with the JavaScript Behaviours I wrote about some days ago and that are used to build the client side the ASP.NET Controls on the server are a solid basis for building AJAX Controls.

There are good articles on the web that explain how to build this kind of controls and there are a lot of samples too. But there are some tricky things around too to reuse this for building AJAX controls.

User Controls

The very useful functionality of ASP.NET User Controls is the possibility of writing often needed HTML code only once in an *.ascx file and reuse it as often as needed by writing only referencing tags into the ASP.NET pages.

Web Controls

Some things are hard to be done when using User Controls. Especially when the Control is only a framing element for more inner HTML objects User Controls cannot be used. Here some Web Controls, that have to be implemented as special classes, are easier to be implemented so you can find both technologies in the samples.

No Form element

AJAX controls are built for NOT posting back, submitting the changes the user did to the server by using the HTML form element and reloading the whole page. That’s why we want AJAX in our web applications. In contrary, ASP.NET controls are made for exact this kind of client-server interaction and therefore are most of the time placed inside a HTML form element. Because we do not use autopostback functionalities nor do we directly implement some script to call form.submit() we do not get problems with a possible existing HTML form element.

If you plan to extend your existing ASP.NET Web Forms with AJAX Controls – which is one of the scenarios I want to support – you will need this HTML form element. If you build new web pages without using the server side functionality of ASP.NET web forms you can eliminate this HTML form element completely.

The Return key

One thing will disturb users when a form element is present: pressing the or key in an input field is (like F5) reloading the page. All information that came to the page since the time it was loaded and displayed by using some asynchronous communications will be lost too.

Pressing return on input-fields outside a HTML form element normally has no visible effect because the return character will not be added to the value of the HTML input element.

There is a simple trick built into the jcl.js file that can help you to get around this situation. By capturing all keypress events and test if return was pressed, it is possible to cancel the keypress event early and prevent the automatic call of the submit functionality.

To enable this trick for the input fields they just must have an attribute "nosubmit" set to "true". You can add this attribute to the HTML code or add it to the JavaScript behaviour bound element too.

Common JavaScript

The AJAX Controls are using the JavaScript behaviours and therefore need all the common include file "~/controls/jcl.js " and most of them also need a specific include file containing the specific JavaScript behaviour prototype.

Registering Script includes

A very useful server-side functionality of ASP.NET Web Forms is the way how controls can control that a JavaScript include file is needed for a control to work sucessfully. The function "RegisterClientScriptBlock" that is available on the Page object as well as on the new Page.ClientScriptManager object in ASP.NET 2.0 can be used to specify some html code that will be included inside a HTML form element before all other HTML content.

With "IsClientScriptBlockRegistered" it is possible to check if a include file is already registered.

Using such a mechanism is perfect for building AJAX Controls because the web programmer needs not to know about the control specific JavaScript include files that must be included for a Control to work properly. He can just include the AJAX controls at the right place and everything else gets magically done.

Page.RegisterClientScriptBlock("CommonBehaviour",
  "<script type='text/javascript' src='"
  + Page.ResolveUrl("~/controls/jcl.js 
  + "'><" + "/script>\n"));

When having a HTML form element on the page the form element will automatically include all the submitted scripts before all other contained HTML content.

If you want to use ASP.NET version 1.1 you need only include a HTML form element before all other HTML code to get the includes into the page. This doesn't mean that the AJAX Controls must be inside the form element, they also may be positioned after an empty form element.

Registering Script includes without a form element

When using ASP.NET 2.0 you can use a little trick to get the HTML script tags for the include files added to the end of the HTML head element that should be marked with "runat=server".

// register the JavaScripts includes without need for a HTML form.
if (!Page.ClientScript.IsClientScriptBlockRegistered(Page.GetType(), "CommonBehaviour")) {
  Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "CommonBehaviour", String.Empty);
  Page.Header.Controls.Add(new LiteralControl("<script type='text/javascript' src='"
    + Page.ResolveUrl("~/controls/jcl.js ")
    + "'><" + "/script>\n"));
} // if

Using this trick, it makes no difference whether a HTML form element exists in the page or not.

Samples and Downloads

There are already some samples for AJAX controls posted on the Samples Web Site. I have added a portal page for the project. Just open the [Samples] tab and look into the third part of the samples collections.

You can also download the whole project - as it is. It’s made for ASP.NET 2.0 Beta 2 build but it also works with the August drop.

Dienstag, September 06, 2005

Caching with AJAX applications

AJAX applications offer better response times and are faster (or at least seems to be faster) that traditional web applications.

The main reason behind this is the separation of the initial page loading from the loading of additional data and the absence of reloading this page again and again when the data of the page changes.

Building up a page works by using conventional call of a URL using the http-get mechanisms. Calling the server in the background by using asynchronous XMLHttpRequests is the second and often repeated part.

Caching can help to speed up both kinds of server requests and the best results can be bought out by preventing calls to the server.

Caching the initial page download

The page that is downloaded by navigating to the URL can be improved most effectively using the client-side cache features of the web browser. After adding the right http headers the browser will not ask the server for the specified time for new versions of the url-resource and will rely on the bytes that can be found in the client-side cache. Some things must be taken care of to make this working properly.

There is a very useful tool for windows from Eric Lawrence called fiddler available at http://www.fiddlertool.com/. He also wrote a good article on tuning and the http protocol: http://www.fiddlertool.com/Fiddler/help/http/HTTPPerf.mht.

Also http://msdn.microsoft.com/library/default.asp?url=/workshop/author/perf/perftips.asp is worth reading.

  • The initial page download MUST NOT contain any data or information that changes frequently or must be available to the client very soon after it changes. If any change of this data is initiated by a click or any other action on the client it is possible to force a request in this case even if the cache period has not ended yet. In this case you can live with a long caching period and an immediate change of the page.
  • The page MUST be designed to be a (almost) static resource from the view of the client.
    It however can vary for different users. When delivering personalized versions, the caching proxy servers as well as the caching features of the server must be turned off.
  • The smaller, the faster.
    I do not recommend using huge graphics and many inline style attributes. The Google applications show, that building fast web applications without many graphics is possible.
  • Use include files for JavaScript and CSS-files.
    Include files can be cached too on the client and can also be shared among different pages. It is good to use include files with common functionality or styles. Rarely ore once-only include files slow down the application.
  • Use only lowercase character in URLs.
    It is not obvious to windows users that page.aspx and Page.aspx are two different resources on the web. Even if the server (IIS and ASP.NET) treats these resources as equal, the client will retrieve and store them twice. The fact that makes them different is the kind of writing in the references in HTML tags "src" and "href" attributes. Because I am never sure how a reference is written in other places I prefer using lowercase character only.
  • Use the right http headers.
    For the IE there are the 2 special cache specific attributes pre-check and post-check that should be set correctly so that the IE does NOT even ask for a version but silently uses the version of the resources found in the client cache.

Caching the asynchronous requests

After the page is loaded there are more requests to the server now by using asynchronous calls in the background using the XmlHttpRequest objects.

When calling long running methods on the server for example complex SQL retrievals or expensive calculations is possible to instruct the server to cache the results and returning them without executing the same methods multiple times.

In ASP.NET you can use the CacheDuration property on the WebMethod attribute to specify the number of seconds the result may stay in the web server cache.

[WebMethod(CacheDuration=60)]

A simple sample on this can be found in the article at: http://support.microsoft.com/default.aspx?scid=kb;en-us;318299

The advantage in this approach is that all clients share the same cache and if there are multiple clients requesting the same service you might get very good response times.

It’s also possible to cache on the client. An approach that leads to less traffic on the net because repeating the same calls can be prevented. Http headers do not help in these situations because the request is not an http-get request and there is always a payload in the http body. Caching must therefore be done by some scripting on the client.

The caching feature in the JavaScript WebService proxy implementation can be enabled by calling the proxies.EnableCache method and passing the function that should further use caching. I added a button to the CalcFactorsAJAX.htm sample to how to enable show this:

proxies.EnableCache(proxies.CalcService.CalcPrimeFactors)

Also the TableData.aspx sample uses caching to prevent retrieving the same records multiple times.

By calling this method a JavaScript object is added that stored all results and is used to prevent a call to the server if an entry for the parameter already exists inside this object.

This is not a perfect solution, but it works under the following circumstances:

  • The parameter must be a string or number that can be used for indexing the properties of a JavaScript object.
  • The cache doesn’t clear itself. It can be cleared by calling EnableCache once again.
  • Only methods with a single parameter are supported.

Caching works good into AJAX applications and speeds up by preventing calculations, downloads and webserver calls.

Donnerstag, September 01, 2005

Project Site Update

This was a long week, not writing text but code. I updated the AJAX Aspects project side http://www.mathertel.de/AJAXEngine/ and I hope you find it more useful. It got more structure and there is now a good place to start the next steps.

  • I decided to clarify the conditions for using this work and added a statement and link to the Creative Commons Attribution 2.0 Germany License. Now it’s clear hat anyone can use it also for commercial projects. Please list my name in your license conditions.
  • I separated the pre-AJAX samples (part 1) from the AJAX samples (part 2). Old links might not work any more.
  • The third part of the project is building reusable AJAX components – AJAX Controls. Some samples are already on the side so if you are curious go and find them.
  • I added a "Impressum" and you can find my E-Mail address in there more easily. It’s a gif file so spiders do not reach me too easily.

I hope you like it :-)

Montag, August 22, 2005

JavaScript Behaviours

This technique has nothing (not yet) to do with AJAX because it is a general usable implementation for reusing JavaScript code for components. Also, this technique has also nothing to do with ASP.NET because it only uses the client-side (browser) available HTML objects and JavaScript. It will be the client side functionality for the upcoming AJAX controls and it fits perfectly into a server-side HTML controls framework that enables also the reusing of HTML code fragments.

General

HTML pages without any more than HTML offer only a limited functionality and allow only displaying information and filling out forms. As a result HTML pages are often extended by using JavaScript for handling input validation, reacting on clicks or bringing optical effects.

But when it comes to reuse once-written functionalities there is no built-in concept to HTML and JavaScript except the flat programming model of include files. Copying sourcecode around is the often used response to this weakness and leads to unsupportable huge web sites often too.

Proprietary behaviours

Both most used browsers, Internet Explorer from Microsoft and the Mozilla/Firefox from the Mozilla foundation, have both their own incompatible way to allow reusing JavaScript functions and HTML on a component level.

Common to both solutions is the big advantage over global script include files that the functionality is bound and accessible through a specific HTML object, can be bound to multiple objects and support specific methods, attributes and event handlers.

Lightweight, compatible behaviours

Building a cross-browser functionality that is very similar to the built-in behaviours of the browsers is not very hard to do.

It basically consists of defining new properties, specific methods and event handlers by building a JavaScript prototype object for each behaviour. Also a common binding functionality is needed that attaches these definitions to a HTML object after the page is loaded. Script include files can be used to bring the prototype objects into the pages.

A simple example

This is the HTML object

<div id="TimerSample" style="...">click here</div>

Here is a simple behaviour that is handling the onclick event and brings in a new update method that is changing the content of the bound HTML object:

var TimerSampleBehaviour = {
  onclick: function (evt) {
    evt = evt ||window.event; // get a compatible event object
    evt.srcElement.update();
  }, // onclick

  update: function() {
    var d = new Date();
    this.innerText = d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
  } // update

} // TimerSampleBehaviour

The behaviour functionality must be bound to the HTML object by calling one method only:

LoadBehaviour(document.getElementById("TimerSample"), TimerSampleBehaviour);

The "magic" work behind the LoadBehaviour() method is to loop though all elements of the given JavaScript object and assigning each of them to the HTML object.:

  • Methods. Starting with "on" are assumed to be event handlers and are attached using the browser specific methods for attaching events. Only the bubbling phase of the event is used because it is implemented by both browsers.
  • Other methods are just bound to the HTML object as function objects.
  • All the other objects are assigned if there is not already an assigned property existing on the HTML object. These objects are shared for all HTML objects that are bound to the same behaviour.

We might expect more functionality from behaviours but this is a set of functionalities that are available in all the supported browsers.

This simple sample can be found on the sample website:

http://www.mathertel.de/AJAXEngine/ in Samples Part 2.

The relevant code can be found in the html page itself and in the include file cb.js.

Writing event handlers

Event handlers use a naming convention to be distinguished from object specific methods by starting with "on". The name of the function should always be lowercase and the function must have a single parameter holding the event object.

Because the IE is not passing the event object through the parameter of an event method we always need a first line to get a compatible event object:

evt = evt || window.event; // get a compatible event object

The clicked HTML object is available by using the srcElement property of the event object.

This is not a native property of Mozilla/Firefox but is made available using a specific patch that is also included – beside other patches – in the common include file cb.js.

I think that it’s a good idea not to implement much in these handlers but to call another method soon because the event handlers always expect an event object and therefore are not reusable for being called from other events or methods.

Writing methods

Writing a method for a behaviour is as simple as writing compatible JavaScript.

Properties or attributes as well as other methods of the bound HTML object are accessible by using the "this" object reference to the HTML object. Never call any method of the prototype object directly, they all are also available through "this".

To make it easy to write compatible JavaScript methods there are some extensions implemented in the common include file cb.js. Mozilla/Firefox has a very powerful extensibility concept that allows easily to define new properties to built-in objects and to control their usage. IE is far behind this point so I use this extensibility to bring IE specific properties to the Mozilla/Firefox platform. Details can be found in the common include file cb.js inline comments.

Defining default values

New properties on the behaviour objects need not to be defined; they just can be used – but always through "this". The properties that are used as parameters to define a aspect of the functionality can be assigned default values in 2 ways:

  • An attribute can be set on the HTML object
  • A property on the JavaScript prototype can be set to an initial value and is used if no attribute is already defined on the HTML object.

When defining complex objects (arrays, structures) inside the JavaScript prototype you have to pay attention to the fact that these objects are shared among all HTML objects using this prototype. If individual complex objects are needed it is better to create and assign them in the "init" method.

The init method

A method named "init" can be defined in the JavaScript prototypes to implement special needs after the methods, event handlers and properties are bound to the HTML object. This method is automatically called by the LoadBehaviour method.

When the "init" method is called it is not guaranteed that the whole page is already loaded and that all other behaviours are bound to their HTML objects. If you need this point in time you have to attach a special handler to the onload event of the page.

Links

The Mozilla/Firefox behaviours: http://www.mozilla.org/projects/xbl/xbl.html

The IE behaviours: http://msdn.microsoft.com/workshop/components/htc/reference/htcref.asp

Search for behaviours using Google: http://www.google.com/search?q=htc+filetype%3Ahtc

Sonntag, August 21, 2005

Application Aspects

The examples on AJAX I’ve published up to now, had to point out special aspects of the technical design and the implementation. They correspond to the "Bottom UP" method and are about the base components Javascript, XMLHTTP, XML and the asynchronous processing - the aspects That giva AJAX its name.

However, it is not the goal to play some technological games but to realize, improved or modernized a complete application with the assistance of the AJAX engine. The use of AJAX technologies fortunately does not need any principle proceeding at the level of the application but starts at the level of components.

Integration of AJAX components

In some cases we can integrated a functionality which is based on AJAX into an existing web application to better solve the problem of a component.

The LookUp example can be used e.g. in conventional web form and the background validating of the content of a HTML form can be guide the user before a regular positing of the form data.

The amount of JavaScript code that has to be loaded on the client is only about 18 kByte for the AJAX engine and the additional code for handling the selection list not very large.

It helps however to save a multiple this size since the data portion does not have to be sent completely to the client and the multiple reloading of the pages saves several times. AJAX based components particularly develop their largest advantages and it is importantly to have easy integrable components.

AJAX controls

When building new pages it is again a big advantage if the realization does not have to be made on each individual page on a very much detailed level. Here we prefer pre-fabricated components side by side with regular HTML objects to build up the final page.

To reach a high percentage of reusability those components are realized outside of the individual pages and are parameterized for their concrete usage.

HTML is used for the description of the appearance of the controls and JavaScript for the implementation of the behaviour. The binding of Javascript methods to the HTML objects is offerend by the Internet Explorer (*.htc) and by the Mozilla/Firefox (*.xbl) however in very different implementations that would lead into a double implementation. I use therefore a simple but compatible binding.

ASP.NET and AJAX controls

My choice to realize a collection of AJAX capable control falls on ASP.NET and the built-in user controls. These components are easy to implement and adapt. They offer already enough possibilities compared with Web Controls that must be implemented as classes. In addition to ASP.NET 1.1 they can also be compiled completely with ASP.NET 2,0

Building a complete new framework is not my intention because there are already some very useful frameworks that permit building component-based web applications.

Because the controls to be implemented are substantially based in HTML and JavaScript they do not really use the ASP.NET functionalities available on the server. Only building up the HTML code of a page from components will needed and this can also to be done by other tag libraries of other environments.

The advantage of ASP.NET is beside that is the simple realization of Web services.

Donnerstag, August 11, 2005

Model View Controller (MVC) Pattern

Thinking about the structure and the layering of the components of solutions is important for software architects. It’s about getting the right distance to a concrete implementation, detecting the principles and unnecessary deviations.

Sometimes those thoughts exceed this range and lead into almost religious discussions about holy principles.

Discussing the Model-View Controller (MVC) is one of those topics that describes the distribution of objects and functionalities of a application with a user interface on a high level. There are books about I and a also the material on the web is very detailed.

Because AJAX style applications is for many developers a new kind of modeling web applications I have collected some of my thought on this topic.

Here I want to look and analyze the existing AJAX Engine and not build a ideal optimal AJAX architecture.

Definition of MVC

There are many different definitions for the Model-View-Controller Pattern (google it). I stay with the short one that can actually be found at Wikipedia: http://en.wikipedia.org/wiki/Model-view-controller

  • Model: This is the domain-specific representation of the information (data and methods) on which the application operates.
  • View: This renders the model into a form suitable for interaction, typically a user interface element.
  • Controller: This responds to events, typically user actions, and invokes changes on the model or view as appropriate.

Model

The Model part of the architecture all is relatively easy to discover in the WebServices. Here all functional aspects should be discoverable. There are of course also functional aspects in the User Interface but this code is implementing a more comfortable way of interaction and handles topics of the presentation.

Based of the role this code takes over in the whole architecture some typical aspects very similar to the SOA architecture of the model can be identified. Here some keywords:

  • Independent of HTML objects
  • No culture or language specific implementations
  • Manipulating and storing data
  • Stateless
  • Checking and securing of the parameters of the webmethods.
  • Reliable algorithms and functionalities

View

The View part can be localized in the realization of the User Interface by using HTML objects and some supplement JavaScript methods.

The base functionality of the HTML objects like editing values in input fields is covering a lot but also a lot of the Javascript implementation in the pages of my samples for example the LookUp List and displaying graphics is part of the view.

  • UI Events
  • Active elements like input fields
  • Layout elements and decorative additions
  • Converting of numbers and date formats to strings
  • Methods to support the working

Controller

But where is the Controller part in a AJAX application and how does it work ?

A simple answer is obvious: The AJAX Engine. Beside the WebService and the HTML there are only the script include files left to implement this part. The proxy methods for the webservices can be defined as part of the network infrastructure.

Page Controller

When comparing the traditional ASP.NET Web Forms with the MVC pattern the page-controller term is used very often. When comparing the 2 most used approaches ASP.NET and Struts you can easily detect that the server side implementation only covers the collaboration of the objects of a single page.

The transitions between the pages are not really supported with a structure by ASP.NET 1.1. Hyperlinks or Redirect statements are used on the server and some problems have to be solved for transferring information from one page to the next one. With ASP.NET 2.0 it is possible to have 2 pages in memory at once and transferring data is easier to implement but this is no solution for controlling the global flow of a web application.

Struts mixes up both aspects what may end in complex struts-config.xml files.

Both approaches for realizing web applications are described and compared regarding the MVC pattern in http://msdn.microsoft.com/library/en-us/dnaspp/html/ASPNet-ASPNet-J2EE-Struts.asp as well as in http://struts.apache.org/userGuide/building_controller.html.

When realizing an AJAX application the controller is shifted to the client and is implemented in JavaScript. Like with ASP.NET is can control only the activities of the one loaded page because all local information is lost when navigation to another page and a new UI and controller is built up. This is the reason why some AJAX applications have only one active URL using a complex page or framesets.

I have to compare this situation with the 2-tier application architecture of the 90’s. Here the controller also was implemented on the (fat) client and the server added data and methods (SQL connections and stored procedures).

Samstag, Juli 30, 2005

Extensions to the proxy generator

With Version 2.0 there is now more support for different datatypes.

Simple data types

Up to now only those methods where supported that where converting of the parameters and result values was not necessary. This applies to strings and numbers.

Now the data types defined on the server and the WSDL are passed to the client so that the data types can be converted using JavaScript at runtime.

In the generated proxy code, the listing of the names of the parameters is now extended by an optional specification of the data type. Without this the values are treated as strings.

proxies.CalcService.AddDouble.params = ["number1:float","number2:float"];
proxies.CalcService.AddDouble.rtype = ["AddDoubleResult:float"];

In the HTML object model, the JavaScript data types are not well supported. The values that is displayed inside an input field is always a string, even if it’s containing only digits. For this all the parameters when calling the proxy are also accepted as JavaScript strings and converted if possible to the right types.

XML data

Passing XML documents was implemented to make it possible to pass complex data. In the browser clients the XMLDocument Object from Microsoft or Firefox and on the server the XmlDocument class can be used.

A Method has to be is declared in C# like this:

[WebMethod()]
public XmlDocument Calc(XmlDocument xDoc) {
...
return (xDoc);
} // Calc

The proxy functions also accept the XML document as a string type. In this case, the contents of the passed string is passed directly to the server any must for this reason contain a valid XML document without the declarations any without any “XML processing Instructions" <? ... ?>.

With this data type it is possible to pass complex data from a HTML form directly to the server an there is no need to define a method with many parameters. If the form is extended with new fields it will not be necessary to give a new signature to the WebService.

The disadvantage of this approach is that the content of the XML document cannot be validated by the WebService infrastructure because there is no schema for this part of the conversation available.

Supported Datatypes
XML data type Alias in the proxy JavaScript data taype
string string / null String
int, unsignedInt,
short, unsignedShort,
unsignedLong,s:long
int Number, (parseInt)
double, float float Number, (parseFloat)
dateTime' date Date
boolean bool Boolean
In Mozilla / Firefox:
XMLDocument
Im Internet Explorer:
ActiveXObject("Microsoft.XMLDOM")
ActiveXObject("MSXML2.DOMDocument")
x System.Xml.XmlDocument

Donnerstag, Juli 28, 2005

Sample for AJAX Forms

This sample implements the processing of data of a form using the AJAX engine and the AJAX Forms.

AJAX also brings some advantages to this kind of application on the validation and calculation of formular data. Instead of "sending" the data and retrieving new to be displayed HTML an asynchronous communication only transfers the data part of the form using XML documents.

The supplementing functions necessary for the handling of AJAX Forms it is necessary to include the ajaxforms.js scripts in the HEADER of the page.

<script type="text/javascript" src="ajaxForms.js"></script>

The connection to the corresponding WebService is done by using the proxy generator:

<script type="text/javascript" src="GetJavaScriptProxy.aspx?service=_Kreditcalc.asmx"></script>

In this example the validation of the input values and the calculation of the new values are together implemented in the same method. The communication of the values between the client and the server uses the XML format defined by ajaxForms.js module. The two functions ajaxForms.getData and ajaxForms.setData that implement the transfer of the data from the XML format to the HTML of objects therefore can be used directly in the setup of the actions.

Exceptions

The function ajaxForms.processException can be used to handle and display the exceptions that occur within validating the passed data.

If a wrong or missing value is detected inside the passed form data the server should throw an ArgumentException using the name of the element as the name of the wrong parameter.

This name is then passed to the client using an exception return package.

ProcessException then recognizes that an ArgumentException was thrown and shows the error text beside the input field. To show these texts, a SPAN element is used for each field inside the form:

<span class="AJAXFORMEXCEPTION" name="LOAN"></span>

The Form

The layout of the form and the data together with the format of the XML document is specified by the HTML code of the page. The DIV element with id frm (having a green border) is used as a container for all fields of the form. Inside this object you can find the INPUT elements like:

<input id="loan" name="LOAN" value="100000">
  ...
<input name="MONTHLYREPAY" disabled="disabled">

The Actions

The first functionality on the server implements the calculation a simple credit case. On the left side of the form some values like the loan amount and the rates can be modified by the user. These values are used to calculate the monthly payment, the duration of the credit and the totals of payment that are displayed on the right side of the form.

For that purpose all the data of the form is send over the network to the server as a XML document as well as the result of the calculation.

The first action uses the functions getData und setData from ajaxForms.js and needs no further programming.

// declare an AJAX action
var action1 = {
  delay: 200,
  prepare: ajaxForms.getData,
  call: proxies.KreditCalc.Calc,
  finish: ajaxForms.setData,
  onException: ajaxForms.processException
} // action1

The second implemented method on the server gets the same XML document information as the first method but returns a XML Document containing the monthly balance of the credit.

The code on the client is the responsible for displaying the chart by using the special local implemented method displayAmortization. Here the XML document passed back from the server is transformed into a HTML document fragment by using a XSLT transformation on the client. This transformation uses a lot of small blue and red images that are sized and positioned as needed to make the chart look like it should.

Because the transformation is done on the client only about 23% of the necessary HTML code is transferred over the network. The XSTL is retrieved only once and is cached on the client.

var action2 = {
  name: "Amortization",
  delay: 800,
  prepare: ajaxForms.getData,
  call: proxies.KreditCalc.Amortization,
  finish: displayAmortization,
  onException: proxies.alertException
} // action2

Starting the actions

To start the asynchronous actions again the onkey event is used. In this sample 2 actions are started by one event. Because both actions have a delay time specified they will stay in the queue and will be removed abd started again when another key is pressed before the delay time is over.

The second parameter on starting the actions is used to reference the AJAX form.

onkeyup="ajax.Start(action1, 'frm');ajax.Start(action2, 'frm')"

Mittwoch, Juli 27, 2005

A lookup example for city names

In example of implementing an AJAX action you can see how to load and display data fragments from a huge dataset on the server.

On the server, there is a big list of German towns and cities in the file orte.txt. If you would include this information into the page as a list of OPTION elements for a SELECT element you would have to download about 400.000 bytes of additional HTML code – too much. Instead a simple INPUT field is combined with the possibility to search in this dataset.

The WebService that implements this lookup functionality can be found in OrteLookUp.asmx and, again, has no AJAX specific implementations. The method gets one parameter passed that contains the first characters of a possible name of a city and returns up to 12 found entries of the list back to the client.

The connection to this WebService is done by using the proxy generator:

<script type="text/javascript" src="GetJavaScriptProxy.aspx?service=OrteLookup.asmx"></script>

This lookup method must be called in several situations: The code on the client that display the list and the completion of the current entered text is somewhat complex and most of the JavaScript of this page is about that. The call ajax.Start(LookupAction) that can be found several times starts the action.

The action itself is implemented very compact in one place and you can see that a not a lot of coding is necessary because the AJAX engine handles a lot.

var LookupAction = {
  delay: 100,
  prepare: function() { return (document.getElementById("inputField").value); },
  call: proxies.OrteLookup.OrteStartWith,
  finish: function (val) {
    var fld = document.getElementById("inputField");
    var dd = createDropdown(fld);
    FillDropdown(dd, val);
    if (isIE)
      NextDropdownEntry(fld);
  },
  onException: proxies.alertException
} // LookupAction

Looking at this script you can again see the actual flow of the action and there is no need to implement several JavaScript methods outside of the definition.

Samstag, Juli 23, 2005

AJAX Form Services

The implementation of the AJAX Form Services, that allows an efficient implementation of forms can be found in the JavaScript include file ajaxForms.js.

Again, only one global object named ajaxForms is defined to minimize possible name conflicts. Attached to this object the following methods are available.

data = ajaxForms.getData(obj)

This method searches all INPUT, TEXTAREA and SELECT elements that are contained inside the passed object and uses their values to build up the elements of a XML document.

The obj parameter can be passed using the id of a formular or as a reference to a HTML Object.

This result of this method is a XmlDocument object.

ajaxForms.setData(obj, data)

This method transfers all values from data into the corresponding INPUT, TEXTAREA and SELECT elements of the HTML form. All HTML elements that are part of the form but have no value in data will be cleared or unchecked.

The obj parameter can be passed using the id of a formular or as a reference to a HTML Object.

The data parameter can be passed as a XML text of a XmlDocument object.

This method also calls clearErrors at the end (see below).

ajaxForms.clearData(obj)

All HTML INPUT, TEXTAREA and SELECT elements that are part of the form are cleared or unchecked.

The data parameter can be passed as a XML text of a XmlDocument object.

ajaxForms.resetData(obj)

All HTML INPUT, TEXTAREA and SELECT elements that are part of the form get their initial value that is coded inside the

The obj parameter can be passed using the id of a formular or as a reference to a HTML Object.

ajaxForms.processException(ex)

AjaxForms implements a mechanism to display exceptions that are thrown by the server nearby the fields that causes them. If exceptions are handled by ajaxForms.processException() all ArgumentException are detected.

To enable the developer how the exception text is shown SPAN elements tagged with the css-class AJAXFORMEXCEPTION can be defined inside the form. The text of the exception is then inserted into this Element and can be formatted by using a CSS rule.

<span class="AJAXFORMEXCEPTION" name="LOANVALUE"></span>

ajaxForms.clearErrors()

This method clears all exception texts inside the form.

Donnerstag, Juli 21, 2005

AJAX and Forms

The good old HTML form element is used by many web pages for the communication of the data from forms. This mechanism was developed to work without any JavaScript or XML and long before AJAX.

It’s a typical scenario in web applications that they have some more or less static forms with input fields for displaying and editing data values. Therefore a concept to handle form situations is also needed in a AJAX engine.

This part is about the programming we need on the client. It’s implemented in JavaScript and uses intensively XML documents. Some words about the extensions in the Proxy Generator as well as the implementation on the server will follow. Some samples can already be found on the samples WebSite.

Classical approach and drawbacks

The mechanism behind form element works since the beginnings of HTML to send the data that is entered or changed by the user back to the WebServer. The format used by these postings has nothing in common with XML but uses for in many cases a URL like format defined by the mime type application/x-www.form-urlencoded. With the upcoming XHTML 2.0 definition also a XML Format and some more advanced form functionalities will be available. But all these good news are not supported by the wide spread browsers available today.

A direct access to the data inside a HTML Form in a whole does not exist in the browser nor in JavaScript. But of course the individual elements can be accessed one by one. The values that are shown to the user are normally included inside the HTML code that is sent from the server to the client. Collecting the values and sending them back to the server is hard coded to the submit action of the form that normally downloads new HTML Code and displays them in the window,

It’s obvious that this approach doesn’t fit into the processing of AJAX. The graphical elements of the form and the data is not separated properly.

Using Form Data

One way to realize an access to the data in a HTML form for AJAX applications is to use JavaScript. The include file ajaxForms.js was written to enable the developer to handle this effectively and without using long scripts in every form but to help with a collection of methods.

The goal of this approach is to distinguish between the data of the form represented as a XML document and the HTML elements that are used to display and edit the data.

To define a form on a HTML page you need a HTML Element that contains all the form elements. This encapsulating element can be a DIV tag.

All the input fields, checkboxes, textareas and select objects with a name that are inside this HTML element are considered holding data in the appropriate object properties. This data is the assembled into a XML document with a data root element by using the names of the HTML elements as the names of the inner tags.

This HTML code ...

<div id="frm" style="margin: 2px; padding: 2px; border: solid 1px green"
  <p>F1: <input name="F1" value="one by one"></p>
  <p>F2: <input type="checkbox" name="F2"></p>
  <p>T1: <textarea name="T1" style="width: 400px; height: 80px">some
text
lines</textarea>
  <p>S1: <SELECT name="S1">
    <option value="10">ten</option>
    <option value="11">eleven</option>
    <option value="12" selected="selected">twelve</option>
    <option value="13">thirteen</option>
  </SELECT>
</div>

... corresponds to this XML document:

<data>
  <F1>one by one</F1>
  <F2>false</F2>
  <T1>some
text
lines</T1>
  <S1>12</S1>
</data>

The data of a form is now available as a single value and therefore fits well into the existing functionalities of the AJAX engine.

In AJAX applications it is a typical that the same HTML Form is reused several times before getting and displaying new HTML code from the server so we also need methods for the reverse data flow that puts the data of an XML document back into the HTML form.

Montag, Juli 18, 2005

More Options for AJAX Actions

Since the first publication I have implemented some changes and additions in the AJAX engine and the framework for WebServices.

ajax.Start(action1, option)

prepare(option) / finish(data, option), onExeption(ex, option)

When starting an AJAX action the only options that could be specified where those that are part of the JavaScript object describing the action. These options are the same for all executions of this action. With this addition it is now possible to define an option for a specific execution.

The ajax.Start Method now has a second parameter. This value is stored into the queue of the AJAX engine together with the fist parameter specifying the action.

When the prepare and finish methods are executed as well on handling en exception, this value is passed as an additional parameter. By using this value it is possible to store a context of an action. That may be for example a HTML object that started the action. Because all methods have access to it, it is now possible to use the same action definition for multiple fields, forms or other situations. Without this parameter it was necessary to implement the direct access to the HTML objects inside the prepare and finish methods.

proxies.cancel()

Calling this method will close the actual connection to the saver by calling the abort method of the xmlhttp object before the result is returned from the server.

This is only possible on asynchronous calls.

proxies.alertResult()

This method makes it easy to watch the communication of the return value of a server call. But the situation is similar to the Heisenberg uncertainty principle: If you watch the package you cannot see the effect anymore because the data from the server is shown to the user but is not passed to the finish method. Also the timing situation is ruined because an alert box is used.

This option can be activated by assigning the alertResult method to the otherwise internally used corefunc property.

proxies.service.method.corefunc = proxies.alertResult;

Even if it breaks, it was necessary from time to time to see the result of a call so this option remains in the client-side WebService framework.

Tip:

It is not well known that the Microsoft Internet Explorer (IE) allows to copy the content of an alert box into the clipboard by using Ctrl+C.

ajax.Cancel()

This method cancels the execution of the currently running action. If a timeout value is specified in the action options this method is called automatically.

ajax.CancelAll()

This method cancels the execution of the currently running and all the pending actions.

Samstag, Juli 16, 2005

The AJAX prime factors sample

The first sample that shows how to use the AJAX engine is in the files CalcFactorsAJAX.htm (Client) and CalcService.asmx (Server). With this sample the principle steps can be analyzed easily.

The connection to the already known WebService is done by using the proxy generator:

<script type="text/javascript" src="GetJavaScriptProxy.aspx?service=CalcService.asmx"></script>

The HTML code contains 2 input elements that are used for the communication with the user.

The import element with the id inputField is editable and used to enter a number that should be split into the prime factors. The event onkeyup was chosen for triggering the AJAX action.

This event is not only triggered by entering characters but by the special keys like backspace, delete or Ctrl+C for pasting a new value.

With IE, there is also the event onpropertychange available that suits better our needs here but the FireFox browser doesn’t implement this and there is no standard event defined for being triggered immediately on any value changes.

The field with id outputField is deactivated and is used to show the calculated prime factors.

...
  <td><input id="inputField" onkeyup="ajax.Start(action1)"></td>
...
  <td><input id="outputField" size="60" disabled="disabled"></td>
...

The AJAX action is declared inside the JavaScript block and there is no other programming necessary except this.

You can see within the methods prepare and finish how to exchange the values with HTML Elements.

The call method is setup by linking to the local method of the generated proxy and exceptions are displayed by using a simple alert box.

The delay parameter is set to 200 msec. This time was chosen after some empirical timing measurements (using myself) and was found being appropriate. When one of the testing people entered a number this time wasn’t exceeded between entering the digits and the action was indeed executed at the end of entering the whole number.

If the action was stared already by entering a digit and when another digit was entered before the delay time was over then the first action was removed from the queue, the second identical action was entered into the queue and the timer was started again.

// declare an AJAX action
var action1 = {
  delay: 200,
  prepare: function() { return (document.getElementById("inputField").value); },
  call: proxies.CalcService.CalcPrimeFactors,
  finish: function (p) { document.getElementById("outputField").value = p; },
  onException: proxies.alertException
} // action1

Looking at this script you can imagine the actual flow of the action. This is a big advantage for everyone that needs to analyze, extend or fix a broken implementation, because all the functionality is not spread over the source code into several methods, callback functions and timer events but kept together in this JavaScript object.

You can find all the samples on http://www.mathertel.de/AJAXEngine/.

Montag, Juli 11, 2005

Handling Exceptions

Also in AJAX architectures failures in the communication and in the execution may raise errors. Fortunately when using a WebServices based framework these cases are also defines in the SOAP communication protocol.

The answer to a call to a WebService in the SOAP format will under normal conditions return the result of the method:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <CalcPrimeFactorsResponse xmlns="http://www.mathertel.de/CalcFactorsService/">
      <CalcPrimeFactorsResult>2 2</CalcPrimeFactorsResult>
    </CalcPrimeFactorsResponse>
  </soap:Body>
</soap:Envelope>

In the case of an error the information about the failure of the server-side execution will be passed back to the client.

In the simplest case this information is shown to the user but also other reactions may be appropriate like reloading the whole page.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <soap:Fault>
    <faultcode>soap:Server</faultcode>
    <faultstring>Server was unable to process request.
---> Input string was not in a correct format.</faultstring>
    <detail />
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

The client-side implementation allows the handling of the exceptions that occur at the level of the WebService proxies an on the level of the AJAX Actions.

In both cases there is an onException event available and a specialized method handling these exceptions can be plugged in. This method gets passed the thrown exception as a parameter and can organize the further functionality of the page.

There is usable method defined in ajax.js that can be used for showing exceptions:

proxies.alertException(ex):

This method shows the exception object in a readable format using an alert box. This method can be used in proxies.service.method.onException as well as in action.onException.

Mittwoch, Juli 06, 2005

AJAX Actions

The fundamental parts of an AJAX engine that handle all the asynchrony calling of the server-side functionality using JavaScript and the XMLHTTP object are available using the WebService proxies. To make realization easier some more layering is needed above this: AJAX Actions.

2 examples of AJAX actions are already published on the examples Website at http://mathertel.devhost1.centron.net/CalcFactors/.

The actual code to implement an AJAX action is located in the two files CalcFactorsAJAX.htm and OrteLookup.htm. Each sample consists of only some lines of code. The reminding work is covered by the implementation of the engine in the file ajax.js.

As you can see in these samples the logical steps of the actions are written in the source code step by step as they will be executed even if there are timers and callback methods used to implement it behind the scene.

This makes it easy to follow the idea of each action.

The AJAX engine layers upon the WebService proxies shown before.

Every action on the page is described with the assistance of an object that holds all information together. The properties of this object are:

prepare(): This property defines a function that is used directly before sending the SOAP of package to the server. This function has to return the data that is used as the argument of the call to the server. If this function is not defined then a server-side method without parameters is called.

call(): This property refers to a function that was generated by the proxy generator to a WebService.

finish(): This property defines a function that will retrieve the result of the call. This property may be zero.

onException(): This property defines a function that is called in the case of an exception. This property may be zero.

delay: This property defines the time in milliseconds how long the call should be delayed. This is useful together with events that are triggered very often and in a fast order. The default value of 0 deactivates this functionality and the action starts immediately.

timeout: This property defines the time in seconds how long the call to the server can last before it is canceled on the client. When this time runs off without an answer from the server the http connection is closed. The default value of 0 deactivates this functionality.

A timeout of more than approx. 60 seconds does not work well because http requests can be terminated by the network layer before this time.

With some additional flags you can specify how pending actions are handled.

queueClear: This property can be set to true to specify that the queue with the pending actions is cleared before the new action is entered. An already running action will not be stopped. The default value is false.

queueTop : This property can be set to true to specify that the action is entered into the queue in front of all other pending actions. The default value is false.

queueMultiple: This property can be set to true to specify that an action can be queue more than once. The default value is false.

// declare an AJAX action
var action1 = {
  prepare: function() { return (document.getElementById("inputField").value); },
  call: proxies.CalcService.CalcPrimeFactors,
  finish: function (p) { document.getElementById("outputField").value = p; },
  onException: alertException
} // action1

In the samples you can see that it is not necessary to write functions before assembling them into the action object. The implementation of a function is also possible using inline code.

Important Note: The last property of a definition of a JavaScript object MUST NOT have a trailing comma. The otherwise quite tolerant Microsoft Internet Explorer complains of this error during the Firefox tolerates this. I lost some hours not seeing a comma like this.

Freitag, Juli 01, 2005

Overview of the AJAX engine

As one can see from the last posts, the basic elements for a application using the AJAX technologies JavaScript and XMLHHTP are not difficult to realize. However, the selection from the available technologies as well as a suitable abstraction in using these elements is crucial for the success of the realization of an application.

Building an AJAX engine or an AJAX framework that you can reuse every time you want some asynchronous processing or when you need a smart way to refresh information on the current web page will help a lot.

If you realize a web application with only containing one or a only a few Web services you can stay with the kind of realization that is shown in the preceding examples.

The experiences in my job in contrast are within the range of applications with some hundred sides and Web services with in sum about a thousand methods. With more than few Web methods the developer must have a clear and simple kind of the realization of the Javascript code on the client to avoid errors and to not think about the implementation details. Only by using a simple approach a good quality and maintenance can be achieved.

The main idea of an AJAX engine on the client is the simplification of the implementation of the code, which is needed for a specific function on the Client. Like with the webservice framework of ASP.NET on the server the details of communication over SOAP on the client are completely hidden from the developer and also the recurring code portion is only realized once in a central place. Also all details about the different implementations of the XMLHTTP object in Internet Explorer or the Firefox browsers are hidden from your code.

The blue print of the AJAX engine has the following connected components:

HTML form and elements

The static or dynamically provided HTML of objects e.g. < input > elements become for the interaction with the user used.

Buttons & Events

The buttons and events, which start a AJAX functionality must only call a simple Javascript function. This can be used for example using inline code in a onclick attribute. This starts then the processing of the steps that should be executed.

AJAX actions

For the call of a server-side functionality parameters must be retrieved and the result must be processed on the Client. These elements together form a AJAX action.

AJAX functions

AJAX functions are the basic steps that together form a AJAX functionality which is supported by a slim and efficient JavaScript framework that hides the browser specific details from the implementation.

Web methods and proxies

The proxy framework is used on the client to call the server-side methods.

Ajax engine

The execution of the individual steps of an AJAX functionality using a timer and XMLHTTP objects is coordinated and supervised by the AJAX engine. The methods for the implementation of the AJAX engines are available in ajax.js.

Also the AJAX engine needs only one variable with the name Ajax to be declared in the global namespace to minimize name conflicts.

In many cases it is importantly for the implementation of actions that they occur one after the other by using a queue mechanism. This is also necessary from a network perspective because with HTTP connections only 2 simultaneous requests per server should be made at a time.

Therefore the AJAX engine implements a queue. Using some attributes on the AJAX actions it is possible to control the way how the existing entries are treated when starting of a new action.

There are several examples of AJAX actions are published on my Website at http://www.mathertel.de/AJAXEngine/.

Dienstag, Juni 28, 2005

Proxies for WebServices in JavaScript

If you want to implement a communication from Javascript to WebServices using SOAP it is very important to use an approach with a small amount of code. Complex and long scripts tend to be buggy.

From the languages and programming environments like C, the .NET CLR and Java we are know proxy generation mechanisms based on IDL and RPC for a long time. These generated classes and files enable the programmer to call a server-side method by calling a local method with the same name. The implementation of the network transfer is taken off your application code.

For WebServices there is also a description standard called WSDL http://www.w3.org/TR/wsdl that fully describes a Webservice communication and a WSDL Compiler can generate those proxy classes in Sourcecode or binary format using this information only.

JavaScript objects on the client

Creating proxy objects is also possible using JavaScript so that a local call of a method results in a call of the corresponding method in the WebService on the server using the same parameters and brining the result back to the client.

To create such Proxy Objects we only need one line of code as we will see below.

The implementation of the real communication is implemented in the ajax include file in the webservice region. In this script include the variable proxies is created as an empty Objects. All local service objects and all local methods will be attached to this object. Calling a server-side Methods looks like this:

proxies.CalcService.func = displayFactors; // async result
proxies.CalcService.CalcPrimeFactors(12); // call

Also a synchronous version can be used. The func attribute must be null and the result of the server-side method is directly returned from the client method.

var factors = proxies.CalcService.CalcPrimeFactors(12);

Using this approach proxies ist the only one global variable that we need. Conflicts with other variables are minimized.

All the information that is needed to make the SOAP call is attached to every method object and another object is used to hold the information about the webservice.

Verwendung der Eigenschaften der WebService Objekte
EigenschaftUsage
proxies.service.urlURL of the WebService
proxies.service.nsNamespace of the WebServices
proxies.service.function()Calling a server-side method
proxies.service.function.fnameName of the method
proxies.service.function.actionsoapaction of the method
proxies.service.function.paramsArray with the names of the parameters
proxies.service.function.funcFunction receiving the result
proxies.service.function.onExceptionFunction to handle an exception
proxies.service.function.corefuncDebugging helper function
proxies.service.function.serviceLink back to the service object

In JavaScript this code looks like this:

[in ajax.js:]
var proxies = new Object();

[per WebService]
// JavaScript proxy for webservices
// A WebService for the calculation of prime factors.
proxies.CalcService = {
  url: "http://localhost:1049/CalcFactors/CalcService.asmx",
  ns: "http://www.mathertel.de/CalcFactorsService/"
} // proxies.CalcService

[per WebServiceMethode]
// Add 2 numbers.
proxies.CalcService.AddInteger = function () { return(callSoap(arguments)); }
proxies.CalcService.AddInteger.fname = "AddInteger";
proxies.CalcService.AddInteger.service = proxies.CalcService;
proxies.CalcService.AddInteger.action = "http://www.mathertel.de/CalcFactorsService/AddInteger";
proxies.CalcService.AddInteger.params = new Array("number1", "number2");

If you only have to realize a small application you can easily create this code manually by reading all the information you need from the webservice description. Retrieving such a description is very easy when implementing in ASP.NET. You navigate to the URL of the webservice and use the Link that is available on this page. You can also attach a WSDL Parameter:

See: http://localhost/CalcFactors/CalcService.asmx?WSDL

A Proxy generator for JavaScript

The simplest form for a WSDL to Javascript Compiler to generate tese proxy objects uses a single XSLT transformation that generates Javascript.

The Page GetJavaScriptProxy.aspx implements this by retrieving the WSDL from the WebService and using wsdl.xslt for the transformation.

To get a proxy for a WebService yopu only need to ust one <script> Element with the URL to the GetJavaScriptProxy Page:

<script type="text/javascript" src="GetJavaScriptProxy.aspx?CalcService.asmx"></script>

You do not have to write the script fort he proxy yourself as you can see and you only need one html tag.

The files for the implementation are available on the sample webside (see sidebar).