Samstag, November 15, 2008

Extending the initialization sequence of JavaScript behaviors

This topic was recently discussed in the OpenAjax group and here is the implemented solution for the AjaxEngine framework. The consensus was to solve the initialization problem on the application level and not within the OpenAjax hub.

 

When multiple components resist side by side on the same page the initialization sequence of the components can become critical for the page to work as expected. Therefore the JavaScript behavior mechanism supports 3 phases of initializing the application when a page loads:

  1. The optional init() method is called first for every control that was initialized by LoadBehavior. This method should contain all initialization code that puts the control in a fully working state. Especially the control should register for any interesting OpenAjax event.
  2. The optional initstate() method is called then and allows the control to inform other controls about their existence and publish state information by using OpenAjax events or direct method calls if appropriate.
  3. The optional afterinit() method is called at last to controls can finish the setup where all other controls are also working.

All controls can participate in the initialization phases by implementing the calls. They are all optional. All 3 methods will be called when the onload event is raised for the window object.

The term method

Another method named "term" can be defined in the JavaScript prototypes to implement a method that is called just before a page unloads. There is a real need for implementing code just before all HTML and JavaScript objects are thrown away in Microsoft Internet Explorer, because there is a well known problem with the memory management used by the HTML DOM and JavaScript. Both object libraries do have their own garbage collector implementation and in some cases circular references between objects of both worlds are not properly detected and memory will not get freed and useless memory consumption is the unwanted result.

The best solution against this “design weakness” is to set all references of JavaScript variables to HTML elements to null in this method.

There is also a great tool and some more background information available that helps to detect this kind of memory leak named Drip available at http://outofhanwell.com/ and is a definitive TO-DO when supporting older browser versions of IE.

Montag, Juli 07, 2008

How to set up a web project using the AjaxEngine – Part 1b

Some days ago I posted part 1a - a short instruction about how to set up a minimal project.

The sample I used to demonstrate that the infrastructure works was as simple as possible and is using a RPC style of Ajax calls to the server. Some topics have not been touched so here they come.

How to get the files

The easiest way to get all the files I’ve talked about is to go get them directly from the repository hosted as sourceforge. 

http://sourceforge.net/projects/ajaxengine/ is the projects's home page and you can browse the repository directly by using the url http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/.

Here all the development progress will be available as soon as soon as I write about it.

Another possible way to get the files is to use a subversion client for example http://tortoisesvn.tigris.org/ that includes more functionality like getting a copy of all the current files at once, looking into the change log and comparing different versions of the same file.

From time to time the download archives are updated too. You can find them on my site at http://www.mathertel.de/AjaxEngine/#view=Downloads

Calling web services the right way

I have to mention, that this is not the best way of calling a server because synchronous calls may block or freeze the client during the call and the call time may be very long when the network or the server is used a lot. Using asynchronous calls is the answer to that problem and there is simple but great mechanism inside the ajax.js file that makes asynchronous programming quiet easy. Here is just a brief explanation of how to use it. More of the mechanism and it's options can be found in the book Aspects of Ajax.

The typical AJAX scenario follows the following pattern and can be split into 4 separate problems:

  1. Waiting for an event that will start the Ajax call to the server.
    Sometime that’s an easy thing to do, because there is a button clicked and we just can attach the initializing code to an event. But sometimes events have to be queued up to avoid a race condition and get wrong answers.
  2. Collecting some data on the client side.
    It is often necessary to do this right before you call the server and not in the moment when the call is initiated.
  3. Communication with the server.
    That is done by using the client stub that is generated for each SOAP based web service.
  4. Finally using the result from the server.
    That must be done, when the data is available and is the typical asynchronous functionality of Ajax.

Many grown-up Ajax implementations are using a JavaScript object that binds the JavaScript functions that all together will solve the scenario and so does the AjaxEngine:

// declare an AJAX action var action1 = { // the prepare function collects and returns the data for the server side method.

// It just returns an array with the parameters and marks it with "multi". prepare: function(obj) { var p = []; p[0] = document.getElementById("n1").value; p[1] = document.getElementById("n2").value; p.multi = true; // the hint for the ajax Engine return (p); }, // the call element points to the proxy for the server call as usual call: proxies.CalcService.AddInteger, // the result will be written it into the appropriate html field. finish: function (p) { document.getElementById("outputField").value = p; } } // action1

This action can be used to start an Ajax call by using some inline code like this:

<input id="n1" onkeyup="ajax.Start(action1)" />

Now Ajax starts getting robust enough in a real web application.

The code is from the sample that you can find in the sample at

http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcAJAX.aspx

Sonntag, Juli 06, 2008

Calling WCF and SOAP based webservices from AJAX

The JavaScript proxy that is implemented for the Ajax engine to call SOAP based web services has been used on the ASP.NET platform for a long time and was ported to other platforms like Java. Some derived work can also be found for PHP and the Qooxdoo. It’s pretty stable for a while and that’s a good message.

When working with some specific Java based platforms there was a specific problem with the automatic generated WSDL descriptions, because they use an external schema for defining the structure of the passed data:

<wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation=http://localhost/AJAXEngine/S02_AJAXCoreSamples/CalcFactors.svc?xsd=xsd0

namespace="http://tempuri.org/" /> ... </xsd:schema> </wsdl:types>

The workaround was to write the JSON structure that is used by the JavaScript proxy by hand (and that is still a good idea for high trafic web sites).

When adopting the WCF .svc services this kind of using WSDL and XML schema definitions can be found too.

A solution for this is quiet simple and can now be found in the wsdl.xslt and the GetJavaScriptProxy.aspx files.

wsdl.xslt

The WSDL to JavaScript transformation now looks for import nodes under the wsdl:types and then imports the referenced schema by using the xslt document() function. Then this imported document is searched for the right element and the parameter and return value description is generated through the soapElem template. Here is the added xslt code:

<xsl:when test="/wsdl:definitions/wsdl:types/s:schema/s:import">

<!-- importing an external schema –>

<xsl:variable name="inputElementName" select="substring-after(wsdl:part/@element, ':')" />

<xsl:for-each select="/wsdl:definitions/wsdl:types/s:schema/s:import">

<xsl:variable name="doc" select="document(@schemaLocation)"/>

<xsl:for-each select="$doc/s:schema/s:element[@name=$inputElementName]//s:element">

<xsl:call-template name="soapElem">

<xsl:with-param name="name" select="@name" />

<xsl:with-param name="type" select="@type" />

</xsl:call-template>

<xsl:if test="position()!=last()">,</xsl:if>

</xsl:for-each>

</xsl:for-each>

</xsl:when>

GetJavaScriptProxy

In the .NET environment the document function will not work for security reasons without some special instructions for the xslt transform. When passing a  XmlUrlResolver when loading the xslt file the document() function can retrieve the referenced external document.

XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = CredentialCache.DefaultCredentials;

XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load(Server.MapPath("~/ajaxcore/wsdl.xslt"), XsltSettings.TrustedXslt, resolver);

Implementing a WCF service for Ajax

Implementing a WCF service for Ajax is almost as simple as programming an *.asmx based service but you can also use an external C# class or interface for implementing the service.

You can find a sample source code in:

http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcFactors.svc

The configuration

By default the WCF services use the SOAP 1.2 format but we don’t need the ws-* functionality and the soap basic profile is perfect for using webservice with AJAX solutions. This can be done by using the following configuration in web.config:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="AjaxBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <services>
    <service behaviorConfiguration="AjaxBehavior" name="CalcFactors">
      <endpoint address="" binding="basicHttpBinding" contract="CalcFactors" />
    </service>
  </services>
</system.serviceModel>

Sonntag, Juni 22, 2008

How to setup a new AjaxEngine web project

I was asked how to setup a web project that uses the AjaxEngine so here is step by step tutorial for a minimal Ajax web project that calls a server side web service:

1. Create a new web project (I prefer using c#) or use your existing web project.

I started with a new project and named it "mini". There is nothing special that you have to set up. It even works without a web.config.

2. Copy the ajaxcore folder to your project.

You can find this folder and the files on sourceforge http://sourceforge.net/projects/ajaxengine/
in the subversion repository by using the path https://ajaxengine.svn.sourceforge.net/svnroot/ajaxengine
or in one of the source code downloads like http://www.mathertel.de/Downloads/Start_AJAX_new.aspx.

For this project you only need the following core files
ajax.js: the client side AjaxEngine

GetJavaScriptProxy.aspx: the JavaScript proxy generator
wsdl.xslt: the WSDL to JavaScript transformation

 

That’s all you have to do to prepare the web project to use the core part of the AjaxEngine. I suggest you use the ajaxcore folder

3. Create a folder named "/calc"

This folder will contain the minimal web application by using a web form and a web service.

I guess you don't implement pages in the root folder of your web application so I follow this best practice here too.

4. Implement a service /calc/WebService1.asmx

There is only one method we need so here is some c# code:

using System.ComponentModel;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

namespace mini.calc {
  /// 
  /// Summary description for WebService1
  /// 
  [WebService(Namespace = "http://tempuri.org/")]
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
  // [System.Web.Script.Services.ScriptService]
  public class WebService1 : System.Web.Services.WebService {

    [WebMethod]
    public double Add(double sum1, double sum2) {
      return (sum1 + sum2);
    }
  }
}

5. Create a new page named WebForm1.aspx in the calc folder

I just use the new item wizard from visual Studio to do this so the typical elements are there already.
There is not much code that must be put into this file.

6. include the ajax.js:

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

The ajax.js file reference should be included in the <head> element.

7. include the proxy for the webservice:

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

This script include should also be included in the <head> element and will make the just implemented webservice and webmethod available through the JavaScript object proxies.WebService1.Add.

8. Implement the User interface

A minimalist UI means just 3 fields and some text.
You also have to remove the <form> element because the fields are not used to post data to the server. 

<input id="sum1" type="text" /> + <input id="sum2" type="text" /> = <input id="result" type="text" />

9. Implement the JavaScript code

This is the trickiest part of it, but it's simple too:
A timer is used to call a function every 200 milliseconds that checks for some changed input values.
The web service is called if any value has changed.

<script type="text/javascript">
  var sum1_obj = document.getElementById("sum1");
  var sum2_obj = document.getElementById("sum2");
  var result_obj = document.getElementById("result");
  var sum1_val = "";
  var sum2_val = "";

  window.setInterval(window.checkValues, 200);
  
  function checkValues() {
    if ((sum1_obj.value != sum1_val) || (sum2_obj.value != sum2_val)) {
      sum1_val = sum1_obj.value;
      sum2_val = sum2_obj.value;
      
      result_obj.value = proxies.WebService1.Add(sum1_val, sum2_val);
    } // if
  } // checkValues
</script>

10. And that's all

Start the Web Form and see how it works.

Mittwoch, April 02, 2008

OpenAjax Call-to-Action to Ajax Developers for Browser Wishlist

The OpenAjax Alliance is developing an Ajax industry wishlist for future browsers, using a dedicated wiki for this initiative (http://www.openajax.org/runtime/wiki). The main purpose of the initiative is to inform the browser vendors about what future features are most important to the Ajax community and why. So far, the alliance has interviewed roughly a dozen industry leaders, including representatives from the ASP.NET AJAX, Dojo, Ext JS, Douglas Crockford of JSON fame, jQuery, Spry, and XAP, and recently held a townhall discussion on the feature request list among its members. The members have concluded that the wishlist (~25 items) is ready for public comments.

The alliance is now issuing a call-to-action to Ajax developers to participate in this initiative, which is open to both OpenAjax Alliance members and to non-members. The alliance especially would like participation from Ajax toolkit developers and leading web developers with expertise in using open browser technologies to achieve rich user experiences. To join the effort, create a wiki login for yourself by following the instructions on the wiki home page (http://www.openajax.org/runtime/wiki). After you have a login, you can then add new feature requests or comment on existing feature requests as you see fit. The initiative operates on an honor-system basis.

The moderators have attempted to make it possible that the community can add comments and vote on particular feature requests without large time commitments. For example, it is possible to simply vote for your favorite feature requests by adding a single row to a wiki table. The alliance’s wiki uses the same markup language as wikipedia.

Here is the timeline:

    • April - Phase I review, where participants not only add comments, but also are asked to identify their Top 5 features (i.e., those features that are most critical for inclusion in next-generation browsers).
    • May - The moderators reorganize and possibly trim away feature requests for which little interest was shown.
    • June - Phase II review, where participants will be asked to provide importance ratings for each of the feature requests on a scale of 0.0 to 5.0.
    • July - The moderators will produce a summary report and notify the major browser vendors about the results.

The process is completely open and Wiki-based, so feel free to contribute^.

Samstag, Januar 26, 2008

Data bound fields for Ajax forms

An overview of the Ajax forms implementation of the AjaxEngine framework has already been published some days ago at http://ajaxaspects.blogspot.com/2007/12/using-openajax-events-for-building-data.html.

Here are more details of the concept around binding html elements to Open Ajax events.

 

Client side API for data bound elements

The API for the data controls is unified as far as possible and for all the data controls the following common features are implemented:

element.eventname

If this attribute is set the the element will listen to and possibly publish an OpenAjax hub event to exchange the changed value through the eventing mechanism. If the value of the eventname attribute does not contain a full namespace but only the local name of the event, the eventnamespace attribute of any parent element is used to complete the namespace. This may be in many cases the surrounding DataFormBehavior element.

element.datatype

This attribute can be set to the name of the datatype of the values. This enables some datatype specific behavior implementation within the element for example converting the non-string datatypes to the specific notation. If this attribute is not set then the exchanged data will is used without any special formatting conversions and no other restrictions are applied. Just like a string type.

This attribute should not be changed by JavaScript. Use the setDatatype(type) method in the case you need that.

element.setData(newValue)

This method is available to set the value of the control directly by using JavaScript. This method is also used internally for all cases when the value of the control has to change. This method can be overwritten by other, derived controls.

element.getData()

This method is available to JavaScript implementations that need to access the value of a (input) field directly. Don't use the innerText or value attributes of an HTML element directly because there may be type conversion and/or translations necessary that are executed for your convenience when using this method.

element.setDatatype(newType)

When the datatype of an data item is not known when loading the page and by using the datatype attribute this method can be to pass the new datatype.

All the values that are exchanged between the Ajax form element and the inner data controls are using the format defined by the XML datatypes (here simply called the standard format) . This implies that the inner data controls have to take care about converting the values into some more useful formats and that the Ajax form and more important the server doesn't have to care about these specific formats.

There is also another way how values can be exchanged among different controls that is the OpenAjax event mechanism. Every time the Ajax form gets a new dataset is also published all the values by using the eventnamespace of the Ajax form. OpenAjax events are also used to sync the inner data controls that all deal with the same data item.

name attribute

This attribute of an inner element is not used. Using this attribute is heavily used by the classic HTML form mechanism. This still allows "hybrid" web pages where the user gets some advice and aid by using AJAX calls to the server but where the form.submit functionality is still used for the real processing of the data of the form.

 

Data bound elements and behaviors

DataOutput Controls

If you have data items that come from the server an that will not be changed by the user you can use the DataOutput control. The DataOutput Behavior only registers for the appropriate event that is specified through the eventname attribute and displays all published values inside the control.

The implementation uses a <span> element for displaying the values but other Controls that derive from DataOutput can also use different element eventually by overwriting the setData method. The setData method can also be used to display values when implementing directly with JavaScript.

It also takes care of the datatype attribute. If this attribute is set the given value in the standard format will then be converted into the national language specific notation within the setData method by using the nls object that will be described later.

The reference documentation can be found at

http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataOutput.js

DataInput Controls

The DataInput component is a general purpose JavaScript Behavior based control that implements the functionality for binding a regular <input> element to OpenAjax events for building Ajax forms.

The implementation takes also care of the datatype in a special way by using the implementation of datatype specific functionality that are available through the nls object that will be described in a later article in detail.

  • When a key is pressed the keyCode / charCode of the pressed key is identified and only valid characters are passed. This allows to keep unwanted characters away from the field value in many cases. However it is possible to paste any character by using the clipboard so do not trust this tiny filter. It's only implemented to assist - not to prevent.
  • If a datatype is given, the XML values will be converted into the national language specific notation within the setData method or when an OpenAjax event with the appropriate eventname was published.
  • If a datatype is given, the national language specific notation of the input value will be converted back into the the XML value that is used on the server site within the getData method.
  • It the data is changed and the cursor leaves the field or the <enter> key is pressed, an OpenAjax event will be published using the standard format.

You can build more specific components based on this JavaScript Behavior by deriving from this implementation and adding some special features.

The reference documentation can be found at

http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataInput.js

The DataFade control

The DataFade Behavior implementation inherits from the DataOutput implementation and adds the Fade effect. Every time a new value is set into this element the background becomes yellow and is then smoothly fading to the original background color to attract the users attention.

A sample page for this effect can be found at

http://www.mathertel.de/AJAXEngine/S04_VisualEffects/FadeDemo.aspx.

The reference documentation can be found at

http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataFade.js

Sonntag, Januar 06, 2008

Building menus with OpenAjax events

Implementing menus is often based on publishing events. I personally cannot remember any system that does not.

The web control that is used to implement menubars is therefore a good sample for a html, css and JavaScript based component that is extendable and completely relies on a declarative approach (also a widely used pattern menu system).

HTML

The html code for building a menubar is implemented by using an outer <div> element and on level of inner elements that can implement image-buttons, text-buttons and separators by using <span> and <img> html elements.

The look and feel of all the elements is defined by using CSS rules based on class names.

The class name "VEMenuBar" is used for the outermost element. Buttons are marked by using “VEMenu” and the separators are marked with the class name “VEMenuSeparator”.

Here is a small sample:  

<div class="VEMenuBar" eventnamespace="de.mathertel.datasource"> 
  <span class="VEMenu" eventname="search">Search</span> 
  <img class="VEMenuSeparator" alt="" src="../controls/images/white.gif" /> 
  <img class="VEMenu" alt="show first record" eventname="first" src="../controls/images/first.gif" /> 
</div>
CSS

Based on the class names the design can be specified. Some of the class names are modified when the hover effect is enabled on the page.

.VEMenuBar { background-color:#eeeeee;padding:2px 8px 2px 8px;height:20px;overflow:hidden;}

This defines the background color of the menubar. The padding definition will keep the inner icons away from the border.

.VEMenuBar * { vertical-align:top;}

All elements will be vertically aligned by the top.

.VEMenuBar span {display:-moz-inline-box;display:inline-block;}

<span> elements inside the menubar can be used to create buttons with a text caption. This rule is used to position span elements by using the padding.
The IE will use the inline-block rule and Mozilla/Firefox will use the -moz-inline-box rule. They both don't understand the other syntax and will just ignore it.

.VEMenu { border:0px;padding:2px}

This rule is used for the state of an icon that is not hovered or pushed. In my layout it has no border and is padding the graphic by using 2 pixels on every side.

.VEMenuHover { border-style:solid;border-width:1px;border-color: #acc1e4 #203050 #203050 #acc1e4;padding:1px}

This is the state of an icon when the mouse is over it but is not pushed. In my layout I use 1 pixel of border on every side with some colors that makes the icon look like being raised a little bit. I reduce the padding to 1px to avoid the shifting and flickering of the graphic.

.VEMenuPushed { border-style:solid;border-width:1px;border-color: #203050 #acc1e4 #acc1e4 #203050;padding:1px}

This is the state of a icon when the icon is pushed down. In my layout I use 1 pixel of border on every side but with different colors and I reduce the padding to 1 px to avoid the shifting and flickering of the graphic.

.VEMenuSeparator { display:inline-block;height:20px;width:1px;border-left:solid 1px #203050;}

Separators between groups of symbols are included by using a 1x1 white pixel image with a classname "VEMenuSeparator" that is displayed with a darker border on the left side.

Declaring and publishing events

Event publishing is the duty of this component. All that we need to declare is what event will be published by a inner element and that is done by using attributes of these elements.

eventname

This attribute that is valid on any nested element of the menubar’s outermost <div> element contains the event name that will be published when the element is clicked. This attribute may contain only a local event name or a full qualified eventname including the namespace.

eventnamespace

This attribute that on the menubar’s outermost <div> element and specifies a namespace that is used for any eventnames that are not fully qualified.

(Fully qualified eventnames are determined by the fact that they contain a dot character.)

The menubar behavior (MenubarBehavior)

This behavior implements all the basic functionality for menubars. When bound to a html element it also loops through all the children elements on the first level an sets the hover attribute to true for those elements that have a class name "VEMenu". This allows enabling the hover effect without implementing the hover attribute for every menu item.

If you set the tabindex property on menu items another functionality is enabled. By setting tabindex to a value greater then 0 the element can get the focus either by using the tab key until you reach the right element or by using the menu with the mouse. When pressing the space bar while the focus is on a specific menuitem the onclick method of the menuitem will be called. This allows you to use the keyboard instead of clicking with the mouse and also allows repeating menu commands in an easy way.

When using ASP.NET it is easy to build a menubar by using the available web control:

<ve:MenuBar runat="server" eventnamespace="de.mathertel.edit"> 
  ...
</ve:MenuBar> 

The implementation in JavaScript is available here:

http://www.mathertel.de/AjaxEngine/documentation/ViewDoc.aspx?file=~/controls/menubar.js

A sample page that uses this control is available here:

http://www.mathertel.de/AjaxEngine/S04_VisualEffects/InlineEditDemo.aspx

(see the source code of the page by using the view link in the upper right corner)

Mittwoch, Januar 02, 2008

More OpenAjax compatible components

The PersistCookie control

OpenAjax events are not persistent. The specification is based on the fact that the subscribers are informed just in time when the event was published. But by using cookies the passed values can survive a page refresh or even some days.

In some applications it is important that the values that where published by OpenAjax events and have changed the web application in a specific way are presenting the state of the client. With the PersistCookie control it is possible to save these simple values into cookies and makes them available when the page is reloaded the next time the page loads by publishing a new OpenAjax event. By using this control it is possible to reload a page in the state that was given when the user visited it the last time or when using the refresh button.

Using this functionality is easy by just including a ASP.NET control like this:

<ajax:PersistCookie runat="server" eventnamespace="jcl" eventname="view" />

The control is designed for persisting the values of multiple eventnames of the same eventnamespace and is providing a mechanism for default values in the case of a first time load of the page.

Using Cookies

Cookies do not have a namespace based mechanism as we can see in the OpenAjax hub specification so the names that are used within the cookies will not contain the namespace used by the OpenAjax event but will only use the local eventname.

Another advantage of not using the namespace to build cookie names is a better use of the available storage space of cookies.

If you have to store values by using the same name multiple times in your web application it is important that the part of each used cookie value is more specific than the standard root. The PersistCookie control therefore uses the current url of the page, extracts the folder part of it and uses this as the path to store the cookies. So, in most cases you will not have to specify the path attribute of this control.

eventnamespace

This attribute can be used for specifying the namespace that contain the to be persisted events.

The default namespace is set to "jcl".

eventname

This attribute can contain a list of event names together with the default values. Then event names are separated by semicolons and the default values are appended to the names using the equal sign.

path

This attribute specifies a specific path for the cookie. If this attribute is not set the current url of the page is used to build a path that specifies the current folder. This avoids conflicts with other cookies used on the same web site.

You will have to set this attribute only if you want to share cookies over multiple pages in different folders.

expire

This attribute specifies how long the cookie values should be stored.

If this attribute is not set the values are only kept in memory while the browser remains open.

Samples

<ajax:PersistCookie runat="server" eventnamespace="jcl" eventname="view" />
or
<ajax:PersistCookie runat="server" eventname="kosten=120000;jahre=4;kapital=999" runat="server" expire="2" />

You can find the implementation here:

http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/persistcookie.js