<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7581919</id><updated>2011-12-15T03:50:14.990+01:00</updated><category term='Behaviors'/><category term='webservice'/><category term='AJAXEngine'/><category term='SOAP'/><category term='OpenAjax'/><category term='Back Button Problem'/><category term='WCF'/><category term='documentation'/><category term='controls'/><category term='Visual Effects'/><category term='license'/><category term='components'/><category term='Forms'/><category term='JavaScript'/><category term='Java'/><category term='book'/><category term='Ajax'/><category term='Ebook'/><title type='text'>Aspects of AJAX</title><subtitle type='html'>Ajax programming is an interesting way of bringing real interactivity to web applications by using the proven internet technologies HTML and JavaScript.
In this BLOG I want to share my experiences in this area and light up some interesting aspects with simple and advanced topics.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>93</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7581919.post-4723884146556010487</id><published>2009-12-05T20:22:00.003+01:00</published><updated>2009-12-05T20:29:48.423+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>How to read cookie values in JavaScript</title><content type='html'>&lt;p&gt;I recently had some odd effects with some pages that use cookies to store some local information. The bug seems to be widely spread in many web applications so here are my findings:&lt;/p&gt;  &lt;p&gt;To read the value of a specific cookie that was set previously you have to analyze the string in document.cookie that contains all cookies. It’s a very readable format and looks like: &lt;/p&gt;  &lt;pre class="code"&gt;a=a101; aha=aha101; bob=bob101; b=b101; c01=c0101&lt;/pre&gt;

&lt;p&gt;The trick is to find the right cookie in this string and extract the value.&lt;/p&gt;

&lt;p&gt;I used a JavaScript function, named getCookie() that searched for the position of the cookie name by using&lt;/p&gt;

&lt;pre class="code"&gt;start = document.cookie.indexOf(name + &amp;quot;=&amp;quot;);&lt;/pre&gt;

&lt;p&gt;… and this is wrong in some cases.&lt;/p&gt;

&lt;p&gt;If you search for the cookie named &amp;quot;b&amp;quot; in the sample above you will get a starting-position within the cookie named &amp;quot;bob&amp;quot; because the indexOf function stops at the first occurrence of the text &amp;quot;b=&amp;quot;.&lt;/p&gt;

&lt;p&gt;This seems to be a very common approach and some educational web sites still publish this kind of code that contains the mistake.&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.w3schools.com/js/js_cookies.asp" href="http://www.w3schools.com/js/js_cookies.asp"&gt;http://www.w3schools.com/js/js_cookies.asp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s easy to fix this line by including the space character:&lt;/p&gt;

&lt;pre class="code"&gt;var start = document.cookie.indexOf(&amp;quot; &amp;quot; + name + &amp;quot;=&amp;quot;);
if (start &amp;gt;= 0) {
  start += 1
} else if (document.cookie.indexOf(name + &amp;quot;=&amp;quot;) == 0) {
  start = 0;
} // if&lt;/pre&gt;

&lt;p&gt;But there is a more elegant solution when using regular expressions and even the retrieval of the value gets easier that I found at&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.elated.com/articles/javascript-and-cookies/" href="http://www.elated.com/articles/javascript-and-cookies/"&gt;http://www.elated.com/articles/javascript-and-cookies/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the full function:&lt;/p&gt;

&lt;pre class="code"&gt;function get_cookie (cookie_name)
{
  var results = document.cookie.match('(^;) ?' + cookie_name + '=([^;]*)(;$)');
  if (results)
    return (unescape(results[2]));
  else
    return (null);
}&lt;/pre&gt;

&lt;p&gt;Check your code.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4723884146556010487?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4723884146556010487/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4723884146556010487' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4723884146556010487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4723884146556010487'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2009/12/how-to-read-cookie-values-in-javascript.html' title='How to read cookie values in JavaScript'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-4458196325537255528</id><published>2008-11-15T23:49:00.001+01:00</published><updated>2008-11-16T13:20:05.566+01:00</updated><title type='text'>Extending the initialization sequence of JavaScript behaviors</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The optional &lt;strong&gt;init()&lt;/strong&gt; method is called first for every control that was initialized by LoadBehavior. This method should contain all initialization code that &lt;strong&gt;puts the control in a fully working state&lt;/strong&gt;. Especially the control should register for any interesting OpenAjax event. &lt;/li&gt;    &lt;li&gt;The optional &lt;strong&gt;initstate()&lt;/strong&gt; method is called then and allows the control to &lt;strong&gt;inform other controls &lt;/strong&gt;about their existence and &lt;strong&gt;publish state &lt;/strong&gt;information by using OpenAjax events or direct method calls if appropriate. &lt;/li&gt;    &lt;li&gt;The optional &lt;strong&gt;afterinit()&lt;/strong&gt; method is called at last to controls can finish the setup where all other controls are also working. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;h5&gt;&lt;b&gt;The term method&lt;/b&gt;&lt;/h5&gt;  &lt;p&gt;Another method named &amp;quot;&lt;strong&gt;term&lt;/strong&gt;&amp;quot; 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.&lt;/p&gt;  &lt;p&gt;The best solution against this “design weakness” is to set all references of JavaScript variables to HTML elements to null in this method.&lt;/p&gt;  &lt;p&gt;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 &lt;a href="http://outofhanwell.com/"&gt;http://outofhanwell.com/&lt;/a&gt; and is a definitive TO-DO when supporting older browser versions of IE.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4458196325537255528?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4458196325537255528/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4458196325537255528' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4458196325537255528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4458196325537255528'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/11/extending-initialization-sequence-of.html' title='Extending the initialization sequence of JavaScript behaviors'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-984306672992792736</id><published>2008-07-07T23:56:00.001+02:00</published><updated>2008-07-07T23:56:58.277+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>How to set up a web project using the AjaxEngine – Part 1b</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Some days ago I posted &lt;a href="http://ajaxaspects.blogspot.com/2008/06/how-to-setup-new-ajaxengine-web-project.html"&gt;part 1a&lt;/a&gt; - a short instruction about how to set up a minimal project.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;h3&gt;How to get the files&lt;/h3&gt;  &lt;p&gt;The easiest way to get all the files I’ve talked about is to go get them directly from the repository hosted as sourceforge.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a title="http://sourceforge.net/projects/ajaxengine/" href="http://sourceforge.net/projects/ajaxengine/"&gt;http://sourceforge.net/projects/ajaxengine/&lt;/a&gt; is the projects's home page and you can browse the repository directly by using the url &lt;a title="http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/" href="http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/"&gt;http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Here all the development progress will be available as soon as soon as I write about it.&lt;/p&gt;  &lt;p&gt;Another possible way to get the files is to use a subversion client for example &lt;a title="http://tortoisesvn.tigris.org/" href="http://tortoisesvn.tigris.org/"&gt;http://tortoisesvn.tigris.org/&lt;/a&gt; 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.&lt;/p&gt;  &lt;p&gt;From time to time the download archives are updated too. You can find them on my site at &lt;a title="http://www.mathertel.de/AJAXEngine/#view=Downloads" href="http://www.mathertel.de/AjaxEngine/#view=Downloads"&gt;http://www.mathertel.de/AjaxEngine/#view=Downloads&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Calling web services the right way&lt;/h3&gt;  &lt;p&gt;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 &lt;a href="http://www.mathertel.de/Ajax/AJAXeBook.aspx"&gt;Aspects of Ajax&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The typical AJAX scenario follows the following pattern and can be split into 4 separate problems:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Waiting for an event that will start the Ajax call to the server.      &lt;br /&gt;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. &lt;/li&gt;    &lt;li&gt;Collecting some data on the client side.      &lt;br /&gt;It is often necessary to do this right before you call the server and not in the moment when the call is initiated. &lt;/li&gt;    &lt;li&gt;Communication with the server.      &lt;br /&gt;That is done by using the client stub that is generated for each SOAP based web service. &lt;/li&gt;    &lt;li&gt;Finally using the result from the server.      &lt;br /&gt;That must be done, when the data is available and is the typical asynchronous functionality of Ajax. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;// declare an AJAX action&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; action1 = {
  &lt;span style="color: #008000"&gt;// the prepare function collects and returns the data for the server side method.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;  // It just returns an array with the parameters and marks it with &amp;quot;multi&amp;quot;.&lt;/span&gt;
  prepare: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(obj) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; p = [];
    p[0] = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color: #8b0000"&gt;n1&lt;/span&gt;&amp;quot;).value;
    p[1] = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color: #8b0000"&gt;n2&lt;/span&gt;&amp;quot;).value;
    p.multi = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;span style="color: #008000"&gt;// the hint for the ajax Engine&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (p);
  },

  &lt;span style="color: #008000"&gt;// the call element points to the proxy for the server call as usual&lt;/span&gt;
  call: proxies.CalcService.AddInteger,
  
  &lt;span style="color: #008000"&gt;// the result will be written it into the appropriate html field.&lt;/span&gt;
  finish: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (p) { &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color: #8b0000"&gt;outputField&lt;/span&gt;&amp;quot;).value = p; }
} &lt;span style="color: #008000"&gt;// action1&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;This action can be used to start an Ajax call by using some inline code like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;n1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;onkeyup&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;ajax.Start(action1)&amp;quot; /&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Now Ajax starts getting robust enough in a real web application.&lt;/p&gt;

&lt;p&gt;The code is from the sample that you can find in the sample at&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcAJAX.aspx" href="http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcAJAX.aspx"&gt;http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcAJAX.aspx&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-984306672992792736?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/984306672992792736/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=984306672992792736' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/984306672992792736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/984306672992792736'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/07/how-to-set-up-web-project-using.html' title='How to set up a web project using the AjaxEngine – Part 1b'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-715497410219668552</id><published>2008-07-06T00:15:00.001+02:00</published><updated>2008-07-06T00:15:19.664+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Calling WCF and SOAP based webservices from AJAX</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;wsdl&lt;/span&gt;:&lt;span style="color: #800000"&gt;types&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsd&lt;/span&gt;:&lt;span style="color: #800000"&gt;schema&lt;/span&gt; &lt;span style="color: #ff0000"&gt;targetNamespace&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://tempuri.org/Imports&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsd&lt;/span&gt;:&lt;span style="color: #800000"&gt;import&lt;/span&gt; &lt;span style="color: #ff0000"&gt;schemaLocation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&lt;a href="http://localhost/AJAXEngine/S02_AJAXCoreSamples/CalcFactors.svc?xsd=xsd0"&gt;http://localhost/AJAXEngine/S02_AJAXCoreSamples/CalcFactors.svc?xsd=xsd0&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000"&gt;&lt;font style="background-color: #ffff99" color="#172939"&gt;      &lt;/font&gt;namespace&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://tempuri.org/&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; 
    ... 
  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsd&lt;/span&gt;:&lt;span style="color: #800000"&gt;schema&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;wsdl&lt;/span&gt;:&lt;span style="color: #800000"&gt;types&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;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).&lt;/p&gt;

&lt;p&gt;When adopting the WCF .svc services this kind of using WSDL and XML schema definitions can be found too.&lt;/p&gt;

&lt;p&gt;A solution for this is quiet simple and can now be found in the wsdl.xslt and the GetJavaScriptProxy.aspx files.&lt;/p&gt;

&lt;h3&gt;wsdl.xslt&lt;/h3&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;when&lt;/span&gt; &lt;span style="color: #ff0000"&gt;test&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/wsdl:definitions/wsdl:types/s:schema/s:import&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font style="background-color: #ffff99"&gt;  &lt;/font&gt;&lt;span style="color: #008000"&gt;&amp;lt;!-- importing an external schema –&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;variable&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;inputElementName&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;select&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;substring-after(wsdl:part/@element, ':')&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;  &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;for&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;each&lt;/span&gt; &lt;span style="color: #ff0000"&gt;select&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/wsdl:definitions/wsdl:types/s:schema/s:import&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;variable&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;doc&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;select&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;document(@schemaLocation)&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;for&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;each&lt;/span&gt; &lt;span style="color: #ff0000"&gt;select&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;$doc/s:schema/s:element[@name=$inputElementName]//s:element&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;call&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;template&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;soapElem&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;with&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;name&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;select&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;@name&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;with&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;type&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;select&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;@type&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;/span&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;call&lt;/span&gt;-template&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;/span&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;if&lt;/span&gt; &lt;span style="color: #ff0000"&gt;test&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;position()!=last()&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;,&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;if&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;for&lt;/span&gt;-each&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;for&lt;/span&gt;-each&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;xsl&lt;/span&gt;:&lt;span style="color: #800000"&gt;when&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;h3&gt;GetJavaScriptProxy&lt;/h3&gt;

&lt;p&gt;In the .NET environment the document function will not work for security reasons without some special instructions for the xslt transform. When passing a&amp;#160; XmlUrlResolver when loading the xslt file the document() function can retrieve the referenced external document.&lt;/p&gt;

&lt;pre class="code"&gt;XmlUrlResolver resolver = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; XmlUrlResolver();
resolver.Credentials = CredentialCache.DefaultCredentials;

XslCompiledTransform xsl = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; XslCompiledTransform();
xsl.Load(Server.MapPath(&amp;quot;&lt;span style="color: #8b0000"&gt;~/ajaxcore/wsdl.xslt&lt;/span&gt;&amp;quot;), XsltSettings.TrustedXslt, resolver);&lt;/pre&gt;

&lt;h3&gt;Implementing a WCF service for Ajax&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;You can find a sample source code in: &lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcFactors.svc" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S02_AJAXCoreSamples/CalcFactors.svc"&gt;http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcFactors.svc&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;The configuration&lt;/h3&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;behavior&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;AjaxBehavior&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceMetadata&lt;/span&gt; &lt;span style="color: #ff0000"&gt;httpGetEnabled&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceDebug&lt;/span&gt; &lt;span style="color: #ff0000"&gt;includeExceptionDetailInFaults&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;behavior&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;services&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;service&lt;/span&gt; &lt;span style="color: #ff0000"&gt;behaviorConfiguration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;AjaxBehavior&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;CalcFactors&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;endpoint&lt;/span&gt; &lt;span style="color: #ff0000"&gt;address&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;binding&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;basicHttpBinding&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;contract&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;CalcFactors&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;service&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;services&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-715497410219668552?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/715497410219668552/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=715497410219668552' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/715497410219668552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/715497410219668552'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/07/calling-wcf-and-soap-based-webservices.html' title='Calling WCF and SOAP based webservices from AJAX'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-2856798328569023452</id><published>2008-06-22T20:47:00.001+02:00</published><updated>2008-06-22T20:48:59.845+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>How to setup a new AjaxEngine web project</title><content type='html'>&lt;p&gt;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: &lt;/p&gt;  &lt;h3&gt;1. Create a new web project (I prefer using c#) or use your existing web project.&lt;/h3&gt;  &lt;p&gt;I started with a new project and named it &amp;quot;mini&amp;quot;. There is nothing special that you have to set up. It even works without a web.config.&lt;/p&gt;  &lt;h3&gt;2. Copy the ajaxcore folder to your project.&lt;/h3&gt;  &lt;p&gt;You can find this folder and the files on sourceforge &lt;a href="http://sourceforge.net/projects/ajaxengine/" target="_blank"&gt;http://sourceforge.net/projects/ajaxengine/&lt;/a&gt;     &lt;br /&gt;in the subversion repository by using the path &lt;a href="https://ajaxengine.svn.sourceforge.net/svnroot/ajaxengine" target="_blank"&gt;https://ajaxengine.svn.sourceforge.net/svnroot/ajaxengine&lt;/a&gt;     &lt;br /&gt;or in one of the source code downloads like &lt;a href="http://www.mathertel.de/Downloads/Start_AJAX_new.aspx" target="_blank"&gt;http://www.mathertel.de/Downloads/Start_AJAX_new.aspx&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;For this project you only need the following core files    &lt;br /&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=ajaxcore/ajax.js" target="_blank"&gt;ajax.js&lt;/a&gt;: the client side AjaxEngine&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=ajaxcore/GetJavaScriptProxy.aspx" target="_blank"&gt;GetJavaScriptProxy.aspx&lt;/a&gt;: the JavaScript proxy generator     &lt;br /&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=ajaxcore/wsdl.xslt" target="_blank"&gt;wsdl.xslt&lt;/a&gt;: the WSDL to JavaScript transformation&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;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 &lt;/p&gt;  &lt;h3&gt;3. Create a folder named &amp;quot;/calc&amp;quot; &lt;/h3&gt;  &lt;p&gt;This folder will contain the minimal web application by using a web form and a web service. &lt;/p&gt;  &lt;p&gt;I guess you don't implement pages in the root folder of your web application so I follow this best practice here too. &lt;/p&gt;  &lt;h3&gt;4. Implement a service /calc/WebService1.asmx &lt;/h3&gt;  &lt;p&gt;There is only one method we need so here is some c# code: &lt;/p&gt;  &lt;pre class="code"&gt;using System.ComponentModel;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

namespace mini.calc {
  /// &lt;summary&gt;
  /// Summary description for WebService1
  /// &lt;/summary&gt;
  [WebService(Namespace = &amp;quot;http://tempuri.org/&amp;quot;)]
  [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);
    }
  }
}&lt;/pre&gt;

&lt;h3&gt;5. Create a new page named WebForm1.aspx in the calc folder&lt;/h3&gt;

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

&lt;h3&gt;6. include the ajax.js: &lt;/h3&gt;

&lt;pre class="code"&gt;&amp;lt;script src=&amp;quot;&lt;span style="color: #8b0000"&gt;../ajaxcore/ajax.js&lt;/span&gt;&amp;quot; type=&amp;quot;&lt;span style="color: #8b0000"&gt;text/javascript&lt;/span&gt;&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;The ajax.js file reference should be included in the &amp;lt;head&amp;gt; element.&lt;/p&gt;

&lt;h3&gt;7. include the proxy for the webservice: &lt;/h3&gt;

&lt;pre class="code"&gt;&amp;lt;script src=&amp;quot;&lt;span style="color: #8b0000"&gt;../ajaxcore/GetJavaScriptProxy.aspx?service=/calc/WebService1.asmx&lt;/span&gt;&amp;quot; type=&amp;quot;&lt;span style="color: #8b0000"&gt;text/javascript&lt;/span&gt;&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;This script include should also be included in the &amp;lt;head&amp;gt; element and will make the just implemented webservice and webmethod available through the JavaScript object &lt;em&gt;proxies.WebService1.Add&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;8. Implement the User interface&lt;/h3&gt;

&lt;p&gt;A minimalist UI means just 3 fields and some text. 
  &lt;br /&gt;You also have to remove the &amp;lt;form&amp;gt; element because the fields are not used to post data to the server.&amp;#160; &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;sum1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; + &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;sum2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;result&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;9. Implement the JavaScript code &lt;/h3&gt;

&lt;p&gt;This is the trickiest part of it, but it's simple too: 
  &lt;br /&gt;A timer is used to call a function every 200 milliseconds that checks for some changed input values. 

  &lt;br /&gt;The web service is called if any value has changed. &lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;script type=&amp;quot;&lt;span style="color: #8b0000"&gt;text/javascript&lt;/span&gt;&amp;quot;&amp;gt;
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sum1_obj = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color: #8b0000"&gt;sum1&lt;/span&gt;&amp;quot;);
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sum2_obj = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color: #8b0000"&gt;sum2&lt;/span&gt;&amp;quot;);
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; result_obj = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color: #8b0000"&gt;result&lt;/span&gt;&amp;quot;);
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sum1_val = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sum2_val = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;

  &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.&lt;span style="color: #0000ff"&gt;setInterval&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.checkValues, 200);
  
  &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; checkValues() {
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((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);
    } &lt;span style="color: #008000"&gt;// if&lt;/span&gt;
  } &lt;span style="color: #008000"&gt;// checkValues&lt;/span&gt;
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;h3&gt;10. And that's all&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://www.mathertel.de/AJAX/images/miniproject01.png" /&gt; &lt;/p&gt;

&lt;p&gt;Start the Web Form and see how it works. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-2856798328569023452?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/2856798328569023452/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=2856798328569023452' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2856798328569023452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2856798328569023452'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/06/how-to-setup-new-ajaxengine-web-project.html' title='How to setup a new AjaxEngine web project'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-2087170301623734719</id><published>2008-04-02T22:11:00.001+02:00</published><updated>2008-04-02T22:11:58.414+02:00</updated><title type='text'>OpenAjax Call-to-Action to Ajax Developers for Browser Wishlist</title><content type='html'>&lt;p&gt;The &lt;a href="http://www.openajax.org/"&gt;OpenAjax Alliance&lt;/a&gt; is developing an Ajax industry wishlist for future browsers, using a &lt;a href="http://www.openajax.org/runtime/wiki"&gt;dedicated wiki&lt;/a&gt; for this initiative (&lt;a href="http://www.openajax.org/runtime/wiki"&gt;http://www.openajax.org/runtime/wiki&lt;/a&gt;). 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. &lt;p&gt;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 &lt;a href="http://www.openajax.org/runtime/wiki"&gt;wiki home page (http://www.openajax.org/runtime/wiki)&lt;/a&gt;. 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. &lt;p&gt;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. &lt;p&gt;Here is the timeline: &lt;ul&gt; &lt;ul&gt; &lt;li&gt;April - &lt;b&gt;Phase I review&lt;/b&gt;, where participants not only add comments, but also are asked to identify their &lt;b&gt;Top 5 features&lt;/b&gt; (i.e., those features that are most critical for inclusion in next-generation browsers). &lt;li&gt;May - The moderators reorganize and possibly trim away feature requests for which little interest was shown. &lt;li&gt;June - &lt;b&gt;Phase II review&lt;/b&gt;, where participants will be asked to provide &lt;b&gt;importance ratings&lt;/b&gt; for each of the feature requests &lt;b&gt;on a scale of 0.0 to 5.0&lt;/b&gt;. &lt;li&gt;July - The moderators will produce a summary report and notify the major browser vendors about the results.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;p&gt;The process is completely open and Wiki-based, so feel free to contribute^.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-2087170301623734719?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/2087170301623734719/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=2087170301623734719' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2087170301623734719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2087170301623734719'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/04/openajax-call-to-action-to-ajax.html' title='OpenAjax Call-to-Action to Ajax Developers for Browser Wishlist'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-4509249773444100924</id><published>2008-01-26T20:57:00.001+01:00</published><updated>2008-01-26T20:57:37.611+01:00</updated><title type='text'>Data bound fields for Ajax forms</title><content type='html'>&lt;p&gt;An overview of the Ajax forms implementation of the AjaxEngine framework has already been published some days ago at &lt;a title="http://ajaxaspects.blogspot.com/2007/12/using-openajax-events-for-building-data.html" href="http://ajaxaspects.blogspot.com/2007/12/using-openajax-events-for-building-data.html"&gt;http://ajaxaspects.blogspot.com/2007/12/using-openajax-events-for-building-data.html&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Here are more details of the concept around binding html elements to Open Ajax events.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Client side API for data bound elements&lt;/h2&gt; &lt;p&gt;The API for the data controls is unified as far as possible and for all the data controls the following common features are implemented:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;element.eventname&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;strong&gt;element&lt;/strong&gt;.datatype&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;This attribute should not be changed by JavaScript. Use the setDatatype(type) method in the case you need that.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;strong&gt;element&lt;/strong&gt;.setData(newValue)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;strong&gt;element&lt;/strong&gt;.getData()&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;strong&gt;element&lt;/strong&gt;.setDatatype(newType)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;name attribute&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This attribute of an inner element is &lt;strong&gt;not &lt;/strong&gt;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.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Data bound elements and behaviors&lt;/h2&gt; &lt;h3&gt;DataOutput Controls&lt;/h3&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;The implementation uses a &amp;lt;span&amp;gt; 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.&lt;/p&gt; &lt;p&gt;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 &lt;strong&gt;nls&lt;/strong&gt; object that will be described later.&lt;/p&gt; &lt;p&gt;The reference documentation can be found at&lt;/p&gt; &lt;p&gt;&lt;a title="http://localhost:50959/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataFade.js" href="http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataOutput.js"&gt;http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataOutput.js&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;DataInput Controls&lt;/h3&gt; &lt;p&gt;The DataInput component is a general purpose JavaScript Behavior based control that implements the functionality for binding a regular &amp;lt;input&amp;gt; element to OpenAjax events for building Ajax forms.&lt;/p&gt; &lt;p&gt;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 &lt;strong&gt;nls&lt;/strong&gt; object that will be described in a later article in detail.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;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.  &lt;li&gt;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.  &lt;li&gt;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.  &lt;li&gt;It the data is changed and the cursor leaves the field or the &amp;lt;enter&amp;gt; key is pressed, an OpenAjax event will be published using the standard format.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;You can build more specific components based on this JavaScript Behavior by deriving from this implementation and adding some special features.&lt;/p&gt; &lt;p&gt;The reference documentation can be found at&lt;/p&gt; &lt;p&gt;&lt;a title="http://localhost:50959/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataFade.js" href="http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataInput.js"&gt;http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataInput.js&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;The DataFade control&lt;/h3&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;A sample page for this effect can be found at&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/FadeDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/FadeDemo.aspx&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;The reference documentation can be found at&lt;/p&gt; &lt;p&gt;&lt;a title="http://localhost:50959/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataFade.js" href="http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataFade.js"&gt;http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/DataFade.js&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4509249773444100924?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4509249773444100924/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4509249773444100924' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4509249773444100924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4509249773444100924'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/01/data-bound-fields-for-ajax-forms.html' title='Data bound fields for Ajax forms'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-1021056879897739360</id><published>2008-01-06T22:18:00.001+01:00</published><updated>2008-01-06T22:18:16.951+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><title type='text'>Building menus with OpenAjax events</title><content type='html'>&lt;p&gt;Implementing menus is often based on publishing events. I personally cannot remember any system that does not.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.mathertel.de/Ajax/images/menubarsample.png"&gt;  &lt;p&gt;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 &lt;b&gt;declarative approach&lt;/b&gt; (also a widely used pattern menu system).  &lt;h5&gt;&lt;a name="_Toc187384790"&gt;&lt;b&gt;HTML&lt;/b&gt;&lt;/a&gt;&lt;/h5&gt; &lt;p&gt;The html code for building a menubar is implemented by using an outer &amp;lt;div&amp;gt; element and on level of inner elements that can implement image-buttons, text-buttons and separators by using &amp;lt;span&amp;gt; and &amp;lt;img&amp;gt; html elements.  &lt;p&gt;The look and feel of all the elements is defined by using CSS rules based on class names.  &lt;p&gt;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”.  &lt;p&gt;Here is a small sample:&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenuBar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;eventnamespace&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"de.mathertel.datasource"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;span&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenu"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;eventname&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"search"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Search&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;span&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;img&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenuSeparator"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;""&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"../controls/images/white.gif"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; 
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;img&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenu"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"show first record"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;eventname&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"first"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"../controls/images/first.gif"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;a name="_Toc187384791"&gt;&lt;/a&gt;&lt;b&gt;CSS&lt;/b&gt;&lt;/h5&gt;
&lt;p&gt;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. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuBar&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;background-color&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;#eeeeee&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;padding&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;2px 8px 2px 8px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;height&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;20px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;overflow&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;hidden&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;This defines the background color of the menubar. The padding definition will keep the inner icons away from the border. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuBar&lt;/span&gt; * { &lt;span style="color: #ff0000"&gt;vertical-align&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;top&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;All elements will be vertically aligned by the top. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuBar&lt;/span&gt; &lt;span style="color: #800000"&gt;span&lt;/span&gt; {&lt;span style="color: #ff0000"&gt;display&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;-moz-inline-box&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;display&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;inline-block&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;&amp;lt;span&amp;gt; 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.&lt;br&gt;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. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenu&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;border&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;0px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;padding&lt;/span&gt;:2px}&lt;/pre&gt;
&lt;p&gt;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. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuHover&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;border-style&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;solid&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;border-width&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;1px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;border-color&lt;/span&gt;: &lt;span style="color: #0000ff"&gt;#acc1e4 #203050 #203050 #acc1e4&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;padding&lt;/span&gt;:1px}&lt;/pre&gt;
&lt;p&gt;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. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuPushed&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;border-style&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;solid&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;border-width&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;1px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;border-color&lt;/span&gt;: &lt;span style="color: #0000ff"&gt;#203050 #acc1e4 #acc1e4 #203050&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;padding&lt;/span&gt;:1px}&lt;/pre&gt;
&lt;p&gt;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. &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuSeparator&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;display&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;inline-block&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;height&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;20px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;width&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;1px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;border-left&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;solid 1px #203050&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;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. 
&lt;h5&gt;&lt;a name="_Toc187384792"&gt;&lt;b&gt;Declaring and publishing events&lt;/b&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;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. 
&lt;p&gt;&lt;b&gt;eventname&lt;/b&gt; 
&lt;p&gt;This attribute that is valid on any nested element of the menubar’s outermost &amp;lt;div&amp;gt; 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. 
&lt;p&gt;&lt;b&gt;eventnamespace&lt;/b&gt; 
&lt;p&gt;This attribute that on the menubar’s outermost &amp;lt;div&amp;gt; element and specifies a namespace that is used for any eventnames that are not fully qualified. 
&lt;p&gt;(Fully qualified eventnames are determined by the fact that they contain a dot character.) 
&lt;h5&gt;&lt;a name="_Toc187384793"&gt;&lt;b&gt;The menubar behavior (MenubarBehavior)&lt;/b&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;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 &lt;b&gt;hover&lt;/b&gt; 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. 
&lt;p&gt;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. 
&lt;p&gt;When using ASP.NET it is easy to build a menubar by using the available web control: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;ve&lt;/span&gt;:&lt;span style="color: #800000"&gt;MenuBar&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"server"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;eventnamespace&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"de.mathertel.edit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
  ...
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;ve&lt;/span&gt;:&lt;span style="color: #800000"&gt;MenuBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
&lt;/pre&gt;
&lt;p&gt;The implementation in JavaScript is available here: 
&lt;p&gt;&lt;a href="http://www.mathertel.de/AjaxEngine/documentation/ViewDoc.aspx?file=~/controls/menubar.js"&gt;http://www.mathertel.de/AjaxEngine/documentation/ViewDoc.aspx?file=~/controls/menubar.js&lt;/a&gt; 
&lt;p&gt;A sample page that uses this control is available here: 
&lt;p&gt;&lt;a href="http://www.mathertel.de/AjaxEngine/S04_VisualEffects/InlineEditDemo.aspx"&gt;http://www.mathertel.de/AjaxEngine/S04_VisualEffects/InlineEditDemo.aspx&lt;/a&gt; 
&lt;p&gt;(see the source code of the page by using the view link in the upper right corner)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-1021056879897739360?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/1021056879897739360/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=1021056879897739360' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/1021056879897739360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/1021056879897739360'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/01/building-menus-with-openajax-events.html' title='Building menus with OpenAjax events'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-6883827648763189594</id><published>2008-01-02T19:26:00.001+01:00</published><updated>2008-01-02T19:26:46.970+01:00</updated><title type='text'>More OpenAjax compatible components</title><content type='html'>&lt;h3&gt;The PersistCookie control&lt;/h3&gt; &lt;p&gt;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. &lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;Using this functionality is easy by just including a ASP.NET control like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;ajax&lt;/span&gt;:&lt;span style="color: #800000"&gt;PersistCookie&lt;/span&gt; &lt;font color="#ff0000"&gt;runat&lt;/font&gt;=&lt;font color="#0000ff"&gt;"server"&lt;/font&gt; &lt;span style="color: #ff0000"&gt;eventnamespace&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"jcl"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;eventname&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"view"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using Cookies &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Another advantage of not using the namespace to build cookie names is a better use of the available storage space of cookies.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;eventnamespace&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This attribute can be used for specifying the namespace that contain the to be persisted events.&lt;/p&gt;
&lt;p&gt;The default namespace is set to "jcl".&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;eventname&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;path&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;You will have to set this attribute only if you want to share cookies over multiple pages in different folders.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;expire&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This attribute specifies how long the cookie values should be stored.&lt;/p&gt;
&lt;p&gt;If this attribute is not set the values are only kept in memory while the browser remains open.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Samples&lt;/strong&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;ajax&lt;/span&gt;:&lt;span style="color: #800000"&gt;PersistCookie&lt;/span&gt; &lt;font color="#ff0000"&gt;runat&lt;/font&gt;=&lt;font color="#0000ff"&gt;"server"&lt;/font&gt; &lt;span style="color: #ff0000"&gt;eventnamespace&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"jcl"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;eventname&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"view"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;or&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;ajax&lt;/span&gt;:&lt;span style="color: #800000"&gt;PersistCookie&lt;/span&gt; &lt;font color="#ff0000"&gt;runat&lt;/font&gt;=&lt;font color="#0000ff"&gt;"server"&lt;/font&gt; &lt;span style="color: #ff0000"&gt;eventname&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"kosten=120000;jahre=4;kapital=999"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"server"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;expire&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"2"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;You can find the implementation here:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/persistcookie.js" href="http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/persistcookie.js"&gt;http://www.mathertel.de/AJAXEngine/documentation/ViewDoc.aspx?file=~/controls/persistcookie.js&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-6883827648763189594?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/6883827648763189594/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=6883827648763189594' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/6883827648763189594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/6883827648763189594'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2008/01/more-openajax-compatible-components.html' title='More OpenAjax compatible components'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-2522198905168561343</id><published>2007-12-27T14:59:00.001+01:00</published><updated>2007-12-27T14:59:11.897+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Useful OpenAjax Event Logger</title><content type='html'>&lt;p&gt;While working on further adopting the OpenAjax event mechanism I wrote this small JavaScript include file that helps inspecting the current OpenAjax events.&lt;/p&gt; &lt;p&gt;It is implemented by using a single JavaScript include file that can be found at &lt;a href="http://www.mathertel.de/AjaxEngine/controls/OpenAjaxEventLog.js"&gt;http://www.mathertel.de/AjaxEngine/controls/OpenAjaxEventLog.js&lt;/a&gt; (&lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/OpenAjaxEventLog.js" target="_blank"&gt;view source&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;It is easy to include this file into ANY web page by using a small JavaScript link (a.k.a. bookmarklet) that you can type into the address bar or save as a link in your favorites:&lt;/p&gt; &lt;p&gt;Create any Link in your favorites, or the link bar and name it for example like this:&lt;/p&gt; &lt;p&gt;&lt;a title="javascript:void(document.body.appendChild(document.createElement('script')).src='http://www.mathertel.de/AjaxEngine/controls/OpenAjaxEventLog.js')" href="http://www.mathertel.de/AjaxEngine/controls/OpenAjaxEventLog.js')"&gt;&lt;img src="http://www.mathertel.de/Ajax/images/OpenAjaxLogLink.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here is the url that you can paste into the url field in the property dialog of the link.&lt;/p&gt;&lt;pre class="code"&gt;javascript:&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.body.appendChild(&lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.createElement('script')).src='http:&lt;span style="color: #008000"&gt;//www.mathertel.de/AjaxEngine/controls/OpenAjaxEventLog.js')&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;There will be one dialog that warns you about the fact that the url is using JavaScript (an unregistered program - what means that ?) and that this may be unwanted. But in this case it is what we need.&lt;/p&gt;
&lt;p&gt;You can open any of the sample pages from the &lt;a title="http://www.openajax.org/member/wiki/InteropFest_1.0" href="http://www.openajax.org/member/wiki/InteropFest_1.0"&gt;http://www.openajax.org/member/wiki/InteropFest_1.0&lt;/a&gt; and try it.&lt;/p&gt;
&lt;p&gt;If you click on the link you just created a extra area will be appended at the bottom of the page and all OpenAjax events will be shown in there.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you like to know more about bookmarklets you can google this term and you will find a lot more tricks.&lt;/p&gt;
&lt;p&gt;My favorite is:&lt;/p&gt;&lt;pre class="code"&gt;javascript:'&amp;lt;xmp&amp;gt;'+&lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.documentElement.outerHTML+'&amp;lt;/xmp&amp;gt;'&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-2522198905168561343?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/2522198905168561343/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=2522198905168561343' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2522198905168561343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2522198905168561343'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/12/useful-openajax-event-logger.html' title='Useful OpenAjax Event Logger'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-2393709146200658472</id><published>2007-12-19T21:04:00.001+01:00</published><updated>2007-12-19T21:04:54.624+01:00</updated><title type='text'>Passing values around with OpenAjax events</title><content type='html'>&lt;p&gt;When publishing and receiving OpenAjax events there is the built-in mechanism of passing a payload a.k.a publisherData around together with the event. When implementing applications based on OpenAjax events there are some more things you should care about when using the publisherData feature. In the specifications you can also find some guidelines.&lt;/p&gt; &lt;p&gt;&lt;b&gt;1. Don’t change the publisherData when handling an event.&lt;/b&gt; &lt;p&gt;That’s already said in the specification. Another and not so explicit mentioned argument for not doing so is the fact that there may be multiple subscribers to the same event. Because the sequence of the elements that receive the event is not determined you do not know whether a control gets the original or the modified publisherData. Anyway these situations are hard to debug – another reason to avoid them. &lt;p&gt;&lt;b&gt;2. Don’t use objects – use strings instead&lt;/b&gt; &lt;p&gt;Right now the OpenAjax hub implementation is client side only but you can expect that events can also be spread other windows on inner iframes. In both cases direct object references are a problem because they cannot pass completely. If you need more than simple values consider using a proprietary format like "29.0016;18.5337", a JSON or an XML string. &lt;p&gt;And don’t assume when passing a numeric value that the subscribers get them as a JavaScript Number object. &lt;p&gt;It seems that strings are fine. :-) &lt;p&gt;&lt;b&gt;3. Don’t use language specific formats&lt;/b&gt; &lt;p&gt;Users like to enter values into fields by using their culture or national language specific notations. Most keyboards here in Germany have a comma in the numeric keypad and a many people would not agree in typing dots when filling out fields for example with prices. &lt;p&gt;If you pass a "1.777,88" around you must assume that all subscribers can understand this specific notation. You can’t assume that if you like to live in meshup scenarios where the connected components come from different world wide vendors or sites. You even can’t assume that when writing a web application for the German speaking market: the Swiss people like the format: "1'777.88". &lt;p&gt;A good idea is to pass the values as defined by JSON and make them directly useable by scripting. &lt;p&gt;&lt;b&gt;4. Don’t pass date values&lt;/b&gt; &lt;p&gt;Passing date values is somewhat problematic because there is no JavaScript constant definition (a.k.a. JSON) for that datatype. :-( &lt;p&gt;I recommend using the XML notation that is based on ISO 8601 date and time formats: "2007-12-24T18:00:02", but I must admit that that's my personal preference based on the fact that I prefer XML and SOAP.   &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-2393709146200658472?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/2393709146200658472/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=2393709146200658472' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2393709146200658472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2393709146200658472'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/12/passing-values-around-with-openajax.html' title='Passing values around with OpenAjax events'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-296626509400443031</id><published>2007-12-12T21:39:00.001+01:00</published><updated>2007-12-12T21:39:18.271+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Forms'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Using OpenAjax events for building data-centric and forms based AJAX applications</title><content type='html'>&lt;p&gt;Most of the business web applications on the Internet are HTML forms based applications where html elements are bound to data is the core functionality. I am talking about registration forms, dialogs and pages to display and modify records of a server side relational database system like in ERP or CRM systems.  &lt;p&gt;Usually there is not a lot of drag &amp;amp; drop activity or popping visual effects here but the most active elements deal with data that comes from databases or other data sources. We need to display, edit and control records from a company's database and implement transactions on these entities.  &lt;p&gt;Here is an approach to use the OpenAjax event mechanism to implement this kind of web applications. The beauty of it and the reason why I implemented this for the AjaxEngine open source project is that using events and namespaces is a far more open approach then the mechanism that I introduced some time ago and has a neat extensibility model.  &lt;p&gt;&lt;b&gt;Typical data-centric web pages&lt;/b&gt;  &lt;p&gt;&lt;a href="http://www.mathertel.de/ajax/images/ajaxformbindings.png"&gt;&lt;img alt="Using OpenAjax events for building data-centric and forms based AJAX applications" src="http://www.mathertel.de/ajax/images/ajaxformbindings.png" border="0"&gt;&lt;/a&gt;  &lt;p&gt;From a high level viewpoint onto pages that implement data-centric applications you see that the elements on the page can be categorized into the following cases:  &lt;ul&gt; &lt;li&gt;Fields and other elements where values are shown and edited by the users (Input fields, checkboxes, ...)  &lt;li&gt;Buttons that help editing these values (calendar popup, drop-down lists, ...)  &lt;li&gt;Foreign key Lookup mechanisms (checking against a list of countries, ...)  &lt;li&gt;Buttons that offer a way of navigation through huge data sources (|&amp;lt; first, next &amp;gt;&amp;gt;, ...)  &lt;li&gt;Buttons that commit a current state to the backend system ([Update])  &lt;li&gt;Buttons that trigger special transactions or back-end calculations&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Forms in this kind of scenario are just a collection of html elements that together can be used to display or edit a single record of a given schema.  &lt;h5&gt;Where to use OpenAjax events&lt;/h5&gt; &lt;p&gt;Events can help in these situations where a direct connection between components is not desired or otherwise problematic:  &lt;p&gt;&lt;b&gt;1. events on the field-level&lt;/b&gt;  &lt;p&gt;On the field-level (inside the form) data is passed around when the value of a field or another data control is changed. This happens either by a user interaction with a field or another data control or as part of a situation on the record level for example when a new record is displayed.  &lt;p&gt;If a field exists it can subscribe to the appropriate event and can display the value passed around. On the other side it can also publish a new event if the user changes the value.  &lt;p&gt;It doesn’t matter if a real field is used or a slider, a calendar popup or a 3d spin control. Even multiple controls that subscribe to the same event can coexist side by side without knowing from each other.  &lt;p&gt;Conclusion 1: Using OpenAjax events gives us the advantage of having a simple plugin mechanism that is extendable.  &lt;p&gt;&lt;b&gt;2. events from the menubar&lt;/b&gt;  &lt;p&gt;Clicking a button already publishes the HTML built-in onclick event. However this event is only passed to those elements that are clicked directly or are part of the control hierarchy of the html object model. The menubar catches these events and transfers them into OpenAjax events that are passed to all elements that are interested because they have subscribed them. These events in contrary to the html DOM events are carrying a semantic by using the full eventname and eventually by carrying some data with them.  &lt;p&gt;Conclusion 2: Using OpenAjax events can add semantic statements to events.  &lt;p&gt;Conclusion 3: OpenAjax events are independent from the html DOM layout and therefore can help separating the UI model from the event model.  &lt;p&gt;These 2 scenarios fit well into the OpenAjax event standard.  &lt;h5&gt;Antipatterns to OpenAjax events&lt;/h5&gt; &lt;p&gt;&lt;b&gt;1. events between tight coupled components&lt;/b&gt;  &lt;p&gt;The datasource controller and the form element are 2 components that share some information flow. However every situation in this scenario is started by the datasource controller. The case where a user wants to “update” the datasource controller has to request the current form data from the form. Using is not practical because the form element that would receive the event will not be able to “attach” the current form data. A direct connection is more adequate approach by sharing a common interface like the 3 methods.  &lt;p&gt;Conclusion 4: Using OpenAjax events to retrieve information is not a practical solution. Tight coupled components are still an option.  &lt;p&gt;Note: Maybe some other control is interested in the fact that new data is available in the form which is done through a write() call. This can be the reason for publishing an event by the datasource controller that expresses that.  &lt;p&gt;&lt;b&gt;2. events between passed between client and server&lt;/b&gt;  &lt;p&gt;The datasource controller also has to exchange data with the server. This is a direct end to end communication that happens every time a record is fetched from the server or a record should be updated. OpenAjax events can’t cross this boundary (yet) and again there is return data that is not available immediately when using asynchronous calls (I hope you do for reasons of robustness).  &lt;p&gt;Conclusion 5: Remote Procedure Calls situations should be implemented by using a high level AJAX protocol.  &lt;h5&gt;Using attributes on controls to define the event names&lt;/h5&gt; &lt;p&gt;One design convention that is used within the DataControls is that the eventnames that are used by controls can be split into 2 parts: the namespace and the local name.  &lt;p&gt;The event “de.mathertel.datasource.search” that is used by the search button in the menubar has the namespace “de.mathertel.datasource” and the local name “search”. The eventname can be specified on the button itself ion 2 ways.  &lt;ol&gt; &lt;li&gt;When the eventname attribute contains a dot character it is assumed that the value already contains a full qualified event name.  &lt;li&gt;When the eventname attribute contains no dot character the parent elements are scanned for a “eventnamespace” attribute ant the effective event name is built by combining them.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Here is the sample of the html code:&lt;pre&gt;&amp;lt;div id="datamenubar" class="VEMenuBar" eventnamespace="de.mathertel.datasource"&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp; &amp;lt;span hover="true" class="VEMenu" tabindex="1" eventname="search"&amp;gt;Search&amp;lt;/span&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp; ...&lt;/pre&gt;&lt;pre&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;p&gt;This convention helps writing short html attributes and allows an easy changing of the namespace that is used for a collection of controls. 
&lt;p&gt;Currently the menubar control and the ajax form control both use this mechanism for building the full qualified even names from the eventname / eventnamespace attributes. 
&lt;p&gt;That’s the blue print of the current changes that took place in the AjaxEngine project. The even simplified the way Ajax Forms can be implemented and helps minimizing the code that we usually need to connect all the elements in a typical data-centric web application.&lt;/p&gt;
&lt;p&gt;Have a look at the sample: &lt;a title="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx" href="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx"&gt;http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx&lt;/a&gt;. If you scroll down the page you can also see a region with a protocol of the raised events.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-296626509400443031?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/296626509400443031/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=296626509400443031' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/296626509400443031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/296626509400443031'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/12/using-openajax-events-for-building-data.html' title='Using OpenAjax events for building data-centric and forms based AJAX applications'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-1259499465891844695</id><published>2007-11-20T22:34:00.001+01:00</published><updated>2007-11-20T22:34:46.307+01:00</updated><title type='text'>AjaxEngine is now full based on the OpenAjax specification</title><content type='html'>&lt;p&gt;During the last weeks a lot of work was done to remove the old DataConnection implementations in the Ajax Engine open source project. Now it's done. You can find a first version of it in the repository on&amp;nbsp; Sourceforge: &lt;a title="http://sourceforge.net/svn/?group_id=200182" href="http://sourceforge.net/svn/?group_id=200182"&gt;http://sourceforge.net/svn/?group_id=200182&lt;/a&gt;&lt;/p&gt; &lt;p&gt;and the sample web site &lt;a title="http://www.mathertel.de/AJAXEngine" href="http://www.mathertel.de/AJAXEngine"&gt;http://www.mathertel.de/AJAXEngine&lt;/a&gt; was also published with this version today.&lt;/p&gt; &lt;p&gt;The current version will be tagged 1.5.nnnn.beta1 and a donwloadable zip file will also be available soon.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The OpenAjax hub specifications seems to be almost finished so not much work will be left until a final full compatible version.&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-1259499465891844695?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/1259499465891844695/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=1259499465891844695' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/1259499465891844695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/1259499465891844695'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/11/ajaxengine-is-now-full-based-on.html' title='AjaxEngine is now full based on the OpenAjax specification'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-8259199891036134135</id><published>2007-11-09T20:20:00.001+01:00</published><updated>2007-11-09T20:20:53.894+01:00</updated><title type='text'>A alternative to JSON is available: web services</title><content type='html'>&lt;p&gt;The discussions about the security concerns of JSON coming up again. Are you looking for alternatives ?&lt;/p&gt; &lt;p&gt;I am not used to advertise for my web site but there is an alternative cross browser solution available since 2005. It's robust code and it's running inside many web applications on Java and ASP.NET.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;standard web services on the server.  &lt;li&gt;SOAP (XML) used on the network.  &lt;li&gt;JavaScript proxies on the client to allow RPC style calling of the server.  &lt;li&gt;AJAXEngine layer that solves the typical timing problems.  &lt;li&gt;No eval() !!! - no evil from eval !!! &lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;One approach for multiple platforms.&lt;/h3&gt; &lt;p&gt;By using the standard protocol on the server side you don't need to incorporate any special new interfaces for you AJAX solutions and take the full advantage to the stable and secured server ports.&lt;/p&gt; &lt;p&gt;On the client all the coding is plain JavaScript. That's why the communication part of this project works on Java as well as on ASP.NET ad PHP should not be a problem too.&lt;/p&gt; &lt;p&gt;Have a look at &lt;a href="http://www.mathertel.de/AjaxEngine/"&gt;http://www.mathertel.de/AjaxEngine/&lt;/a&gt; &lt;/p&gt; &lt;p&gt;It's Open Source using a BSD style license and available on &lt;a href="http://sourceforge.net/projects/ajaxengine/"&gt;http://sourceforge.net/projects/ajaxengine/&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-8259199891036134135?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/8259199891036134135/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=8259199891036134135' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/8259199891036134135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/8259199891036134135'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/11/alternative-to-json-is-available-web.html' title='A alternative to JSON is available: web services'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-3445070116046326498</id><published>2007-10-13T14:37:00.001+02:00</published><updated>2007-10-13T14:37:33.840+02:00</updated><title type='text'>Calling web services with structured parameters from JavaScript</title><content type='html'>&lt;p&gt;In many situations it is better to use structured parameters when calling SOAP based web services then using a long list of simple parameters. The proxy layer of the AjaxEngine now also supports these parameters by converting JavaScript Objects to the XML notation used in the transferred SOAP message.&lt;/p&gt; &lt;h3&gt;Parameters&lt;/h3&gt; &lt;p&gt;Using methods with structured parameters using JavaScript Objects is directly supported, just pass them with the right properties.&lt;br&gt;Here is a partial sample for a web service definition in C#: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// Define a point in the 3D space. public class Point3D {&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; x, y, z;
} &lt;span style="color: #008000"&gt;// Point3D&lt;/span&gt;

[WebMethod(Description = "&lt;span style="color: #8b0000"&gt;Calculate the distance of 2 points in the 3D space.&lt;/span&gt;")]
&lt;span style="color: #008000"&gt;// Test function passing structured objects.&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; CalcDistance3D(Point3D p1, Point3D p2) {
  Point3D v = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Point3D();
  v.x = p2.x - p1.x;
  v.y = p2.y - p1.y;
  v.z = p2.z - p1.z;
  &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; dist = Math.Sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (dist);
} &lt;span style="color: #008000"&gt;// CalcDistance3D &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Calling this method from JavaScript by using the generated proxy method is easy by using JavaScript Objects:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; p1 = {x:3, y:2, z:-4};
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; p2 = {x:1, y:1, z:1};
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; dist = proxies._types.CalcDistance3D(p1, p2);&lt;/pre&gt;
&lt;p&gt;If you like to use XmlDocuments ???&lt;/p&gt;
&lt;h3&gt;Structured return values&lt;/h3&gt;
&lt;p&gt;Methods of web services may also return structured values. Here is a sample of a method for calculating a vector in the 3D space:&lt;/p&gt;&lt;pre class="code"&gt;[WebMethod(Description = "&lt;span style="color: #8b0000"&gt;Calculate the vector between 2 points in the 3D space.&lt;/span&gt;")]
&lt;span style="color: #008000"&gt;// Test function returning a complex object.&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Point3D CalcVector3D(Point3D p1, Point3D p2) {
  Point3D v = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Point3D();
  v.x = p2.x - p1.x;
  v.y = p2.y - p1.y;
  v.z = p2.z - p1.z;
  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (v);
} &lt;span style="color: #008000"&gt;// CalcVector3D&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Structured values that are returned by methods are available as XmlDocuments when you call a method like this. If you prefer to have the value as an JavaScript Object there is a function available in the proxies namespace that you can use: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; p1 = {x:3, y:2, z:-4};
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; p2 = {x:1, y:1, z:1};

&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; xmlVector = proxies._types.CalcVector3D(p1, p2);
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; v = proxies.xml2json(xmlVector);
&lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;(v.x + "&lt;span style="color: #8b0000"&gt;/&lt;/span&gt;" + v.y + "&lt;span style="color: #8b0000"&gt;/&lt;/span&gt;" + v.z);&lt;/pre&gt;
&lt;h3&gt;Limitations&lt;/h3&gt;
&lt;p&gt;Objects used as parameters cannot be too complex. JavaScript Objects that have native values&lt;br&gt;(not Arrays nor Objects) are supported.&lt;br&gt;The data must be available in the format that can be de-serialized on the server&lt;br&gt;so take care of decimal points and date values. 
&lt;p&gt;Up to now the only way to use complex parameters with SOAP methods &lt;br&gt;was to use a server side XmlDocument Object and to extract the given values by using the appropriate methods. 
&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;This addition was done in the current version under development. Because ajax.js is almost independent from the other current changes you can download it to existing projects from the sourceforge repository at &lt;a title="http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/ajaxcore/" href="http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/ajaxcore/"&gt;http://ajaxengine.svn.sourceforge.net/viewvc/ajaxengine/trunk/ajaxcore/&lt;/a&gt; or from the website &lt;a title="http://www.mathertel.de/AJAXEngine/ajaxcore/ajax.js" href="http://www.mathertel.de/AJAXEngine/ajaxcore/ajax.js"&gt;http://www.mathertel.de/AJAXEngine/ajaxcore/ajax.js&lt;/a&gt;.
 &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-3445070116046326498?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/3445070116046326498/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=3445070116046326498' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/3445070116046326498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/3445070116046326498'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/10/calling-web-services-with-structured.html' title='Calling web services with structured parameters from JavaScript'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-4254101422729576056</id><published>2007-09-03T21:04:00.001+02:00</published><updated>2007-09-03T21:04:53.247+02:00</updated><title type='text'>The plan for Q3/2007</title><content type='html'>&lt;p&gt;I've got some mails that have asked about the future of the AjaxEngine framework and here are some statements on that topic:&lt;/p&gt; &lt;p&gt;I will support and extend the framework in the future so companies and other open source projects that reuse it will have the support I can give. Some of the current topics that I'll hope to finish this month are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;OpenAjax compatibility for all controls including a InterOp fest compatibility test case.  &lt;li&gt;Extending the functionality and the documentation of the Ajax form and the data controls.  &lt;li&gt;Writing some more input helpers.  &lt;li&gt;Writing about all of it...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I will make a beta version then and have some weeks to get the new functionality stable before publishing a new version.&lt;/p&gt; &lt;p&gt;You can always see the current implementation state in the svn based OpenSource repository at Sourceforge:&amp;nbsp;&lt;a title="http://sourceforge.net/svn/?group_id=200182" href="http://sourceforge.net/svn/?group_id=200182"&gt;http://sourceforge.net/svn/?group_id=200182&lt;/a&gt;&lt;/p&gt; &lt;p&gt;as well as the demo site that will also be based on the current version under development.&lt;/p&gt; &lt;p&gt;If anyone wants to add&amp;nbsp;some core directly to the project instead of sending me mails let me know.&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4254101422729576056?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4254101422729576056/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4254101422729576056' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4254101422729576056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4254101422729576056'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/09/plan-for-q32007.html' title='The plan for Q3/2007'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-2346477243866184949</id><published>2007-08-14T00:00:00.001+02:00</published><updated>2007-08-14T20:06:52.682+02:00</updated><title type='text'>Extending the OpenAjax hub</title><content type='html'>&lt;p&gt;Extending events over the network by using an OpenAjax hub compatible approach.&lt;/p&gt; &lt;p&gt;The current version of the OpenAjax hub implementation (Hub 1.0) is focusing on a client-side solution for integrating components into a web application. But it doesn't address any needs that might come with the scenarios where events have to cross the boundaries of the current client side window.  &lt;p&gt;However the hub specification does not explicit exclude these scenarios and is extendible without changing the API itself by introducing a OpenAjax compatible extender component.&lt;/p&gt; &lt;p&gt;Another approach is currently discussed in the OpenAjax member wiki&amp;nbsp;at &lt;a title="OpenAjax_Hub_1.1_Roadmap" href="http://www.openajax.org/member/wiki/OpenAjax_Hub_1.1_Roadmap"&gt;http://www.openajax.org/member/wiki/OpenAjax_Hub_1.1_Roadmap&lt;/a&gt;&amp;nbsp;that is designed by extending the API of the hub itself.  &lt;h3&gt;Building an OpenAjax hub extender&lt;/h3&gt; &lt;p&gt;The idea behind building an extender is to capture the events in one window and pass it over to other windows.  &lt;p&gt;When the windows exists in the same frameset and share a common top window the message just needs to cross the boundaries. If the window is on another computer the client has to capture the event, and pass it to a server where other clients can then attach and retrieve the events.  &lt;p&gt;&lt;strong&gt;1. capturing events&lt;/strong&gt;  &lt;p&gt;For the local hub implementation the part of the hub extender that captures the local events is just another subscriber. It can register to any local events or can just listen to some of the events that come around. The attribute "capture" is used to specify what events are sent to the server by specifying a semicolon separated list of namespaces using the same syntax as the subscribe method.  &lt;p&gt;The other attribute that we need is the name of the service where the events can be send to using the server site publish method.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// registering for the local event.&lt;/span&gt;
OpenAjax.hub.subscribe(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.capture, "&lt;span style="color: #8b0000"&gt;_catchLocalEvents&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);

&lt;span style="color: #008000"&gt;// this function is called whenever a local event was published&lt;/span&gt;
_catchLocalEvents: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventName, eventData) {
  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (! &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._replay) {
    &lt;span style="color: #008000"&gt;// it's a real local event so publish it.&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; a = [eventName, eventData];
    a.multi = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.lastLocalAction = eventName + "&lt;span style="color: #8b0000"&gt;:&lt;/span&gt;" + eventData;
    ajax.Start(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.sendAction, a);
  } &lt;span style="color: #008000"&gt;// if&lt;/span&gt;
}, &lt;span style="color: #008000"&gt;// _catchLocalEvents&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The _replay flag is taking care about the fact that the events that are coming from the server should not be repeated back to the server. 
&lt;p&gt;The sendAction is the description how the server should be called.&amp;nbsp;The call should be started&amp;nbsp;at once and&amp;nbsp;multiple calls for publishing an event to the server can be queued. There is no return value in this case.&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// The Ajax action to send an event to the server&lt;/span&gt;
sendAction: {
  delay:0,
  queueMultiple:&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
  prepare: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (a) { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;(a); },
  call: "proxies.OpenAjaxChat.Publish",
  finish: &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
  onException: proxies.alertException
}, &lt;span style="color: #008000"&gt;// sendAction&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. listening to events&lt;/strong&gt; 
&lt;p&gt;Listening to events that come from the server is somewhat more complicated because the normal http interaction schema for web applications is client side initiated. The server just has no chance to send messages to "all" or "specific" clients but has to wait until a client asks for an update. 
&lt;p&gt;So the client loops by using another Ajax action that is specified with a small delay and calls the server to retrieve new events. The server will return all newer events that have been recorded since the last call of this client that is determined by using a marking counter that can be passed from the client.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// this function is called after retrieving all the events from the server.&lt;/span&gt;
_republish: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(events) {
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._replay = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; aList = events.split('\n');
  &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; n = 0; n &amp;lt; aList.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt; - 1; n++) {
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (aList[n] != &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.lastLocalAction) {
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; a = aList[n].split(':');
      OpenAjax.hub.publish(a[0], a[1]);
    }
  } &lt;span style="color: #008000"&gt;// for&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._replay = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;

  &lt;span style="color: #008000"&gt;// remember the current marker&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.marker = aList[aList.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt;-1];

  &lt;span style="color: #008000"&gt;// start another pollAction&lt;/span&gt;
  ajax.Start(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.pollAction, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
},&lt;/pre&gt;
&lt;p&gt;The action is calling the serer by passing the current marker of the client and the asynchronous result will be passed to the _republish method.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// The Ajax action that polls the events from the server&lt;/span&gt;
pollAction: {
  delay:200, &lt;span style="color: #008000"&gt;// wait 200 msec before calling the server (just to be smart).&lt;/span&gt;
  prepare: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (obj) { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;(obj.marker); },
  call: &lt;span style="color: #0000ff"&gt;"proxies.OpenAjaxChat.PullEvents"&lt;/span&gt;,
  finish: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (ret, obj) { obj._republish(ret); },
  onException: proxies.alertException
} &lt;span style="color: #008000"&gt;// pollAction&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The action and the _republish method will be called repetitive to poll the server. 
&lt;p&gt;One thing is left to do in the implementation of this action is the fact that local events already have been published on the client and should not be republished when the server returns them again. To stop publishing an event twice the hub extender records the last event that has been captured locally and sorts this event out. 
&lt;h3&gt;The&amp;nbsp;Server API &lt;/h3&gt;
&lt;p&gt;Calling the server for publishing and retrieving the latest events is implemented by using a real SOAP based webservice with the 2 methods Publish and PullEvents. 
&lt;p&gt;The communication layer is not as complex as the one defined with Bayeux from the Dojo Foundation but it helps in most scenarios. It is restricted in some way because complex objects cannot be used by the eventData. 
&lt;p&gt;The return value of pullevents method is complex object that contains an array of eventname and eventdata and the value of the current marker that is transported using a string too by using the following format: 
&lt;blockquote&gt;
&lt;p&gt;[namespace.eventname:data\n]* 
&lt;p&gt;marker&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;A sample application &lt;/h3&gt;
&lt;p&gt;A small sample is showing how all together can be used. It is a kind of chat application where anyone can participate in the same conversation by just opening the url: &lt;a href="http://www.mathertel.de/AjaxEngine/S06_AJAXForms/OpenAjaxChat.aspx"&gt;http://www.mathertel.de/AjaxEngine/S06_AJAXForms/OpenAjaxChat.aspx&lt;/a&gt; 
&lt;p&gt;You can change your current alias in the configuration section of the page. The large textarea is used to display all the events as the arise and the small textfield beneath can be used by you to type some text. Feel free top open another window and see that your written text also appears on the other side and maybe you can see others typing too. (I suggest talking about animals).&lt;br&gt;The data itself is a combination of the user's name and the typed text. 
&lt;p&gt;The first component is the one that is used for entering a new message and it publishes the event de.mathertel.chatsample.message whenever a line is finished by using the return key. The implementation is quite simple: &lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;fieldset style="&lt;span style="color: #8b0000"&gt;width: 424px&lt;/span&gt;"&amp;gt;&amp;lt;legend&amp;gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; message:&amp;lt;/legend&amp;gt;
  &amp;lt;input id="&lt;span style="color: #8b0000"&gt;newmessage&lt;/span&gt;" style="&lt;span style="color: #8b0000"&gt;width: 390px;&lt;/span&gt;" /&amp;gt;
&amp;lt;/fieldset&amp;gt;

&lt;span style="color: #008000"&gt;// the functionality of the new message field.&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; newmessageBehavior = {
  onkeypress: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(evt) {
    evt = evt || &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.event;
    &lt;span style="color: #008000"&gt;// send the message when pressing &amp;lt;enter&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (evt.keyCode == 13) {
      OpenAjax.hub.publish("&lt;span style="color: #8b0000"&gt;de.mathertel.chatsample.message&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById("&lt;span style="color: #8b0000"&gt;username&lt;/span&gt;").value
        + "&lt;span style="color: #8b0000"&gt; - &lt;/span&gt;" + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value);
      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value = "&lt;span style="color: #8b0000"&gt;&lt;/span&gt;";
    }
  } &lt;span style="color: #008000"&gt;// onkeypress&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// newmessageBehavior&lt;/span&gt;
OpenAjax.hub.registerLibrary("&lt;span style="color: #8b0000"&gt;newmessageBehavior&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;http://www.mathertel.de/OpenAjax/newmessageBehavior&lt;/span&gt;");
jcl.LoadBehaviour("&lt;span style="color: #8b0000"&gt;newmessage&lt;/span&gt;", newmessageBehavior);&lt;/pre&gt;
&lt;p&gt;The next component implemented is the larger textarea where the all the events will be logged: &lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;fieldset style="&lt;span style="color: #8b0000"&gt;width: 424px&lt;/span&gt;"&amp;gt;&amp;lt;legend&amp;gt;Chat log:&amp;lt;/legend&amp;gt;
  &amp;lt;textarea rows="&lt;span style="color: #8b0000"&gt;10&lt;/span&gt;" cols="&lt;span style="color: #8b0000"&gt;50&lt;/span&gt;" id="&lt;span style="color: #8b0000"&gt;chatlog&lt;/span&gt;" disabled="&lt;span style="color: #8b0000"&gt;disabled&lt;/span&gt;"&amp;gt;
  &amp;lt;textarea /&amp;gt;
&amp;lt;/fieldset&amp;gt;


&lt;span style="color: #008000"&gt;// the functionality of the chat log area.&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; chatlogBehavior = {
  &lt;span style="color: #008000"&gt;// registering for the event.&lt;/span&gt;
  init: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; () {
    OpenAjax.hub.subscribe("&lt;span style="color: #8b0000"&gt;de.mathertel.chatsample.**&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;_log&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
  }, &lt;span style="color: #008000"&gt;// init&lt;/span&gt;

  &lt;span style="color: #008000"&gt;// append another line to the log text and cut the first one if there are too many.&lt;/span&gt;
  _log: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventName, eventData) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; txt = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value.split('\n');
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (txt.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt; &amp;gt; 9)
      txt = txt.slice(-9);
    txt.push(eventData);
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value = txt.join('\n');  
  } &lt;span style="color: #008000"&gt;// _log&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// chatlogBehavior&lt;/span&gt;
OpenAjax.hub.registerLibrary("&lt;span style="color: #8b0000"&gt;chatlogBehavior&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;http://www.mathertel.de/OpenAjax/chatlogBehavior&lt;/span&gt;");
jcl.LoadBehaviour("&lt;span style="color: #8b0000"&gt;chatlog&lt;/span&gt;", chatlogBehavior);&lt;/pre&gt;
&lt;p&gt;Implementing these 2 components a "local" chat applications ready to run. 
&lt;p&gt;The third component is the hub extender that is invisible and is introduced above. The complete source code of the page can be seen here: 
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S06_AJAXForms/OpenAjaxChat.aspx" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S06_AJAXForms/OpenAjaxChat.aspx"&gt;http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S06_AJAXForms/OpenAjaxChat.aspx&lt;/a&gt; 
&lt;p&gt;and you can see the sample live at: 
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/OpenAjaxChat.aspx" href="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/OpenAjaxChat.aspx"&gt;http://www.mathertel.de/AJAXEngine/S06_AJAXForms/OpenAjaxChat.aspx&lt;/a&gt; 
&lt;p&gt;&amp;nbsp; 
&lt;p&gt;If you are interested in the web service implementation the source is available here: 
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S06_AJAXForms/OpenAjaxChat.asmx" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S06_AJAXForms/OpenAjaxChat.asmx"&gt;http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=S06_AJAXForms/OpenAjaxChat.asmx&lt;/a&gt; 
&lt;h3&gt;Discussion &lt;/h3&gt;
&lt;p&gt;The sample above shows how easy it is to extend a hub into other browser windows by not extending the API but by adding a component that does the job.&lt;br&gt;The huge advantage with this approach is that the additional functionality is strictly separated from the core implementation is and encapsulated into it's own JavaScript file. Therefore it is an optional component and will be not part of the download if not needed in a specific application. 
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-2346477243866184949?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/2346477243866184949/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=2346477243866184949' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2346477243866184949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2346477243866184949'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/08/extending-openajax-hub.html' title='Extending the OpenAjax hub'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-6032849254855411014</id><published>2007-08-05T23:13:00.001+02:00</published><updated>2007-08-20T20:35:05.461+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><title type='text'>Using the OpenAjax hub</title><content type='html'>&lt;h3&gt;What's the problem ? &lt;/h3&gt; &lt;p&gt;On the client side it is a common scenario that multiple independent developed&amp;nbsp;controls have to be linked together.&lt;/p&gt; &lt;p&gt;Let's think about a web application that consists of several pages that all should share some common functionality, let's say a button that pops up a calendar to pick up a date.&lt;br&gt;Its a good idea to separate this kind of functionality into a separate JavaScript include file and a web control or tag library to make it reusable. &lt;/p&gt; &lt;p&gt;Well it's not always the same implementation we need because sometimes the field, that holds the that is named "shipping day", "birthday", "reply until" or any other and sometime there is more than one field on the same page.&lt;br&gt;Coding the name of the field into the common files seems not to be a good idea.&lt;br&gt;And it can be worse if there is not only a calendar button and a single field that needs to be connected but there might be also other fields foe example showing the duration between the 2 dates or even some validation functionality. All these "components" need to be linked together.  &lt;h3&gt;How links components ? &lt;/h3&gt; &lt;p&gt;Hard-coding the IDs of the html elements into the JavaScript code is a bad idea that you can see often in JavaScript . A better idea (for the first sight) is to use attributes on the html elements that contain the IDs of the other elements. For example you can add a "targetControlID" to the calendar popUp and set it to the id of the field.&lt;br&gt;Sounds good, but it's still limited to be used for the scenario where more than one&amp;nbsp;component needs to be attached to another.&lt;/p&gt; &lt;p&gt;Another idea is to link these components together by using a global available eventing mechanism where it is possible to publish events with values and to register for events on the other side.&lt;/p&gt; &lt;p&gt;Firing events means that one component that has detected a new situation or data constellation can make this available to all other listening&amp;nbsp;components but without knowing if there are any. This results in scripts that are really independent of each other and can be reused in other pages where other constellations are present. Every component that is part of a specific use case can plug itself into the scenario.&lt;/p&gt; &lt;p&gt;That's the idea of the OpenAjax hub specification. &lt;/p&gt; &lt;h3&gt;Using the OpenAjax hub to loosely couple components&lt;/h3&gt; &lt;p&gt;The 2 main methods the hub specification offers are publish and subscribe -- simple but powerful. (The third defined method is unsubscribe).&lt;br&gt;Publishing is just as easy than calling a method of another component and the result is that all components (if there are any) that are interested in the event will be called.&lt;br&gt;To separate different events from each other and to specify the meaning of an event, each event needs a unique identifier that is build by using a namespace and local name.&lt;/p&gt;&lt;pre class="code"&gt;OpenAjax.hub.publish("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.startdate&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;2007.08.05&lt;/span&gt;");
OpenAjax.hub.publish("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.enddate&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;2007.08.12&lt;/span&gt;");&lt;/pre&gt;
&lt;p&gt;These samples will tell all subscribers that the values have been changed. The new values are sent together with the event notifications. &lt;/p&gt;&lt;pre class="code"&gt;OpenAjax.hub.subscribe("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.*&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;calc&lt;/span&gt;", document.getElementById("&lt;span style="color: #8b0000"&gt;duration&lt;/span&gt;"));&lt;/pre&gt;
&lt;p&gt;Using the subscribe method this way will cause that the calc method of the duration field will be called each time a event of the namespace de.mathertel.openajax.tasksample is published. 
&lt;p&gt;This sample only shows some main aspects about the OpenAjax hub only. You can find the complete specification on the OpenAjax web site (see links below). 
&lt;h3&gt;Implementing a sample page&lt;/h3&gt;
&lt;p&gt;To show how to work with the OpenAjax hub implementation a sample page with a hypothetic task definition is used. The only aspects we have a look at are the start and end dates of this task and some more components around.&lt;br&gt;To keep the sample as simple as possible only one date notation is allowed: "yyyy.mm.dd". Keep that in mind, if you play around with the sample. 
&lt;p&gt;First of course we need a OpenAjax hub implementation. You can get the one from the reference implementation (see links below) or use the smaller one that comes with the JavaScript Common behavior library of the AjaxEngine Open source project. This one is also used in the samples implementation you can try out at&amp;nbsp; &lt;br&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/TaskSample1.aspx"&gt;http://www.mathertel.de/AJAXEngine/S06_AJAXForms/TaskSample1.aspx&lt;/a&gt; 
&lt;p&gt;Here is the include statement: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"../controls/jcl.js"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The sample also contains 2 fields (startdate and enddate).&lt;br&gt;Another readonly field (duration) is used to display the duration of the hypothetic task.&lt;br&gt;A third and invisible component is also included in the page and this component will take care of the fact that the start date cannot be in the past. 
&lt;h3&gt;Implementing the input fields &lt;/h3&gt;
&lt;p&gt;The fields we use here are just regular input fields that are extended by some JavaScript: &lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; fieldBehavior = {
&lt;span style="color: #008000"&gt;  // after loading the page the other components should know about the current value.&lt;/span&gt;
&amp;nbsp; afterinit: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; () {
&amp;nbsp;&amp;nbsp;&amp;nbsp; OpenAjax.hub.publish("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.&lt;/span&gt;" + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.id, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value);
&amp;nbsp; }, &lt;span style="color: #008000"&gt;// init &lt;/span&gt;
&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;  // when leaving the field the new, changed value must be published.&lt;/span&gt;
  onchange: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (evt) {
    OpenAjax.hub.publish("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.&lt;/span&gt;" + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.id, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value);
  }, &lt;span style="color: #008000"&gt;// onchange&lt;/span&gt;
&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;} &lt;span style="color: #008000"&gt;// fieldBehavior&lt;/span&gt;
jcl.LoadBehaviour("&lt;span style="color: #8b0000"&gt;startdate&lt;/span&gt;", fieldBehavior);
jcl.LoadBehaviour("&lt;span style="color: #8b0000"&gt;enddate&lt;/span&gt;", fieldBehavior); &lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;After the page and all components have been loaded the current value of each field is published around so all other components know about it. When the value is changed through editing the event is published again.&lt;br&gt;I hope it is understandable what how the script works. &lt;br&gt;The way the script is bound the the 2 fields is part of the JavaScript Behavior mechanism that is not part of the OpenAjax specification. You can find how it works in some older posts on this block. 
&lt;h3&gt;Implementing the duration field &lt;/h3&gt;
&lt;p&gt;Again a regular input field is used to display the duration of the hypothetic task. The script for this field is a little bit different and also uses the OpenAjax hub mechanism. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; durationBehavior = {
  _startDate: &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
  _endDate: &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
    
  init: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    OpenAjax.hub.subscribe("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.*&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;calc&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
  }, &lt;span style="color: #008000"&gt;// init&lt;/span&gt;
    
  calc: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (propName, propData, regData) {
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (propName == "&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.startdate&lt;/span&gt;")
      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._startDate = propData;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (propName == "&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.enddate&lt;/span&gt;")
      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._endDate = propData;

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._startDate != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._endDate != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)) {
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; da = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._startDate.split('.');
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sd = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;(da[0], da[1], da[2]);
      da = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._endDate.split('.');
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; ed = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;(da[0], da[1], da[2]);
      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.value = (ed - sd) / (60*60*24*1000);
    }
  } &lt;span style="color: #008000"&gt;// calc&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// durationBehavior&lt;/span&gt;
jcl.LoadBehaviour("&lt;span style="color: #8b0000"&gt;duration&lt;/span&gt;", durationBehavior);&lt;/pre&gt;
&lt;p&gt;The init method subscribes to all events that are published in the namespace I use in this sample. In this case the specific name of an event&amp;nbsp;must be analyzed within the subscription method and because of that is passed as a parameter too.&amp;nbsp;&amp;nbsp; 
&lt;h3&gt;Implementing the validation &lt;/h3&gt;
&lt;p&gt;The validation code is just registering the for startdate event and is checking the date value. If it's not a date an alert box is shown - that's all. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// a validator function to the startdate&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; validate(propName, propData, regData) {
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; da;
  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (propData != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
    da = propData.split('.');
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (da.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt; != 3) {
      &lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;(propData + "&lt;span style="color: #8b0000"&gt; is not a date value formatted yyyy.mm.dd&lt;/span&gt;");
    } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; d = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;(da[0], da[1], da[2]);
      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (d.&lt;span style="color: #0000ff"&gt;valueOf&lt;/span&gt;() &amp;lt; (&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;()).&lt;span style="color: #0000ff"&gt;valueOf&lt;/span&gt;())
        &lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;(propData + "&lt;span style="color: #8b0000"&gt; is not a date in the past.&lt;/span&gt;");
    } &lt;span style="color: #008000"&gt;// if&lt;/span&gt;
  } &lt;span style="color: #008000"&gt;// if&lt;/span&gt;
}; &lt;span style="color: #008000"&gt;// validate&lt;/span&gt;
OpenAjax.hub.subscribe("&lt;span style="color: #8b0000"&gt;de.mathertel.openajax.tasksample.startdate&lt;/span&gt;", validate);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 
&lt;h3&gt;Extending the OpenAjax hub &lt;/h3&gt;
&lt;p&gt;As you've seen the mechanism of the OpenAjax hub is really powerful and helps connecting components on a page without hard-coding the ids into the JavaScript code.&lt;br&gt;But there are still some minor topics undone. 
&lt;p&gt;&lt;strong&gt;1. initial events&lt;/strong&gt; 
&lt;p&gt;After loading the page every component might have to publish the initial value to all the other components to make them know about the value. This cannot be done in an onload script because then it will depend on the initialization order of the components what components will receive the event. 
&lt;p&gt;The current OpenAjax hub specifications seems to have the understanding that events are used after the page has been loaded. I think the mechanism is also good to be used in the phase of the page loading but there is no suitable specification for this right now. The init and afterinit methods in the JavaScript Behavior implementation can help on this. 
&lt;p&gt;&lt;strong&gt;2. saving&amp;nbsp;latest values&lt;/strong&gt; 
&lt;p&gt;When events are published a component that needs to know about the values of several other events and has to combine them always has to collect this information on its own as you can see in the implementation of the duration field. 
&lt;p&gt;I think that this is a common scenario and can be supported in a general way too. 
&lt;p&gt;&lt;strong&gt;3. nesting events&lt;/strong&gt; 
&lt;p&gt;The third issue I see is that the code that is started by a published event should not start another event.&lt;br&gt;Think about the validation functionality above. If a start date in the past is detected it would be easy to publish the current date as a substitute. The problem then is that other components will get the event once with the older value and once with the newer value. The order of these events is not deterministic and it might occur that the older value will be published to a component after the newer value. 
&lt;h3&gt;Links: &lt;/h3&gt;
&lt;p&gt;&lt;a href="http://sourceforge.net/projects/ajaxengine"&gt;http://sourceforge.net/projects/ajaxengine&lt;/a&gt;&lt;br&gt;&amp;nbsp; The open source AjaxEngine project, including a public subversion repository. 
&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;http://www.mathertel.de/AJAXEngine/&lt;/a&gt; 
&lt;p&gt;&amp;nbsp; The AjaxEngine project live with samples and documentation. 
&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/controls/jcl.js"&gt;http://www.mathertel.de/AJAXEngine/controls/jcl.js&lt;/a&gt;&lt;br&gt;&amp;nbsp; The JavaScript Common behaviors library containing a second source OpenAjax implementation. 
&lt;p&gt;&lt;a href="http://www.openajax.org"&gt;http://www.openajax.org&lt;/a&gt;&lt;br&gt;&amp;nbsp; Here you can find all the white papers and the specifications. 
&lt;p&gt;&lt;a href="http://sourceforge.net/projects/openajaxallianc"&gt;http://sourceforge.net/projects/openajaxallianc&lt;/a&gt;&lt;br&gt;&amp;nbsp; Here you can find the reference implementation of the hub.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-6032849254855411014?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/6032849254855411014/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=6032849254855411014' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/6032849254855411014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/6032849254855411014'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/08/using-openajax-hub.html' title='Using the OpenAjax hub'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-3682677196188946122</id><published>2007-07-26T23:04:00.001+02:00</published><updated>2007-07-26T23:04:56.966+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Tree view Ajax control update</title><content type='html'>&lt;p&gt;The tree view control was introduced some time ago and some details of its implementation can be found at &lt;a title="http://ajaxaspects.blogspot.com/2006/01/tree-view-ajax-control.html" href="http://ajaxaspects.blogspot.com/2006/01/tree-view-ajax-control.html"&gt;http://ajaxaspects.blogspot.com/2006/01/tree-view-ajax-control.html&lt;/a&gt;&amp;nbsp;or in the book at &lt;a title="Aspects of Ajax book" href="http://www.mathertel.de/AJAXEngine/documentation/AJAXeBook.aspx"&gt;http://www.mathertel.de/AJAXEngine/documentation/AJAXeBook.aspx&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Now there is an update available and also a step by step sample how to use this control inside your web application.&lt;/p&gt; &lt;p&gt;The sample page can be found at: &lt;a title="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx" href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx&lt;/a&gt;.&lt;/p&gt; &lt;h3&gt;1. Building a web service&lt;/h3&gt; &lt;p&gt;Using Ajax with a tree view control is based on the idea that the full data that builds a complete tree might have a size that cannot be downloaded to the browser in one time. The server therefore has to offer a method that enables downloading&amp;nbsp;fragments of&amp;nbsp;a hierarchic data structure exactly in that moment when the user opens a new sub tree.&lt;/p&gt; &lt;p&gt;The tree view Ajax control binds to a webservice with only one function &lt;strong&gt;GetSubNodes&lt;/strong&gt;(string &lt;strong&gt;path&lt;/strong&gt;) that has to be built for your specific solution. If you like you can also use a different name for the method.&lt;/p&gt; &lt;p&gt;The structure of the XML node that must be returned by this method looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&amp;lt;tree&amp;gt;
  &amp;lt;folder name="AK" title="Alaska"&amp;gt;&lt;br&gt;  &amp;lt;file title="Aguila" name="ZIP85320" link="http://weather.aol.com/main.adp?location=USAZ0001"/&amp;gt;
  &amp;lt;file title="Ajo" name="ZIP85920" /&amp;gt;&lt;br&gt;  &amp;lt;file name="Redmond" img="redfile" /&amp;gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;  &amp;lt;file name="Alpine" /&amp;gt;
  &amp;lt;file name="Yuma" /&amp;gt;
&amp;lt;/tree&amp;gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;The outer element must be a &amp;lt;tree&amp;gt; node that contains &amp;lt;folder&amp;gt; and &amp;lt;file&amp;gt; nodes.&lt;/p&gt;
&lt;p&gt;As you can see the &lt;strong&gt;name &lt;/strong&gt;attributes do have a special&amp;nbsp;purpose in this structure&amp;nbsp;because the values of these nodes together and separated by slashes&amp;nbsp;will build a &lt;strong&gt;path&lt;/strong&gt; to each available element for example "/AZ/Ash Fork".&lt;/p&gt;
&lt;p&gt;When clicking onto folders and files this path will be used for loading&amp;nbsp;a subtree or for the events that are published when a final &amp;lt;file&amp;gt; node is clicked.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;title &lt;/strong&gt;attribute is optional. Its text will be displayed behind the icon. If it's not present the name will be used instead.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;link &lt;/strong&gt;attribute can be used when a click on a final node should just open a regular hyperlink.&lt;/p&gt;
&lt;p&gt;When there is no link present on&amp;nbsp;a file node an &lt;strong&gt;OpenAjax event&amp;nbsp;&lt;/strong&gt;"de.mathertel.treeview.click" with the path of the node in the data is published. You can register to this event for catch all clicks if no navigation is required.&lt;/p&gt;
&lt;p&gt;You can find a webservice implementation &lt;a href="http://localhost:1490/AJAXEngine/ViewSrc.aspx?file=~/S03_AJAXControls/TreeView.asmx"&gt;here&lt;/a&gt;&amp;nbsp;and &lt;a href="http://localhost:1490/AJAXEngine/ViewSrc.aspx?file=~/S03_AJAXControls/BibleData.asmx"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Having built such a web service most of the work is done. 
&lt;h3&gt;2. importing the webservice&lt;/h3&gt;
&lt;p&gt;The webservice must be made available on the page containing the Ajax tree view control by using a simple JavaScript include: &lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"text/javascript"&lt;/span&gt;&lt;br&gt;&lt;font style="background-color: #ffff99"&gt;   &lt;/font&gt;&lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"../ajaxcore/GetJavaScriptProxy.aspx?service=../S03_AJAXControls/TreeView.asmx"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;Now the webservice is available through the proxies.TreeView object and the GetSubNodes method can be&amp;nbsp;called by using the generated proxies.TreeView.GetSubNodes() function.&lt;/p&gt;
&lt;h3&gt;3. embedding the Ajax tree view control&lt;/h3&gt;
&lt;p&gt;The control is implemented as a user control in the file ~/controls/TreeView.ascx. If you use Visual Studio 2005 you can drag this file onto a page and the control will be registered for this page or you can register the control by using a @Register tag at the beginning of the page:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;%@ Register Src="../controls/TreeView.ascx" TagName="TreeView" TagPrefix="ajax" %&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The other way to register a user control is putting an option into the web.config file. This is the better solution if you want to reuse the control on multiple pages and like to use the same prefix all over the web application.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;pages&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;controls&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"~/controls/TreeView.ascx"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;tagName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"TreeView"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;tagPrefix&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ajax"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The control itself can be used now:&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;ajax&lt;/span&gt;:&lt;span style="color: #800000"&gt;TreeView&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"TreeView1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"server"&lt;/span&gt; &lt;br&gt;&amp;nbsp; &lt;span style="color: #ff0000"&gt;service&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"proxies.TreeView.GetSubNodes"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;title&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Cities in the USA"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;You can see&amp;nbsp;the complete source of the page by using this link: [&lt;a title="View Source" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/S03_AJAXControls/TreeView.aspx"&gt;view source of TreeView.aspx&lt;/a&gt;].&lt;/p&gt;
&lt;h3&gt;4. CSS and&amp;nbsp;specific icons&lt;/h3&gt;
&lt;p&gt;Some tree view might not only&amp;nbsp;use folders and files so there is a special feature for that too. 
&lt;p&gt;The CSS code that is used by the tree view control is shown here:&lt;/p&gt;&lt;pre class="code"&gt;div.TreeView .du {height:18px;overflow:hidden;cursor:hand; &lt;br&gt;&amp;nbsp; background-image:url(controls/images/dc.png);background-repeat:no-repeat}
div.TreeView .do {height:18px;overflow:hidden;cursor:hand;&lt;br&gt;&amp;nbsp; background-image:url(controls/images/do.png);background-repeat:no-repeat}
div.TreeView .dc {height:18px;overflow:hidden;cursor:hand;&lt;br&gt;&amp;nbsp; background-image:url(controls/images/dc.png);background-repeat:no-repeat}
div.TreeView .de {height:18px;overflow:hidden;&lt;br&gt;  background-image:url(controls/images/de.png);background-repeat:no-repeat}
div.TreeView .fl {height:18px;overflow:hidden;&lt;br&gt;  background-image:url(controls/images/file.png);background-repeat:no-repeat}
div.TreeView .ft {padding-left:40px}
div.TreeView .subframe {margin-left:18px;}&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Using these short classnames for attaching the style results in small html code fragments and you can link to the right images just by modifying the style rules. I put this baseline definition into the main css include file of the web application.&lt;/p&gt;
&lt;p&gt;By specifying the img attribute on a file node in the data that is returned from the server another classname can be included&amp;nbsp;for the ft-class elements. To avoid individual image tags in the tree view this classname extension also is handled by using a style rule that you can add:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;.&lt;span style="color: #800000"&gt;TreeView&lt;/span&gt; .&lt;span style="color: #800000"&gt;fl&lt;/span&gt;.&lt;span style="color: #800000"&gt;redfile&lt;/span&gt; {&lt;span style="color: #ff0000"&gt;background-image&lt;/span&gt;:url(../controls/images/redfile.png)}&lt;/pre&gt;
&lt;p&gt;This definition can be found in the sample page itself but you can also put it into the mail css include file if you like. Search for Redmond(WA) to see it work.&lt;/p&gt;
&lt;h3&gt;5. handling the events&lt;/h3&gt;
&lt;p&gt;If you just like to show information in a tree fashion and like to use hyperlinks on the&amp;nbsp;file nodes&amp;nbsp;you don't need to have a look at the eventing system that is also built in.&lt;/p&gt;
&lt;p&gt;When clicking a&amp;nbsp;file node and if there is no hyperlink set then the tree view controls publishes an event that event handlers can catch. The eventing system that is used here is the &lt;a href="http://www.openajax.org/"&gt;OpenAjax&lt;/a&gt;&amp;nbsp;compatible event hub. You can find the documentation about it on the &lt;a href="http://www.OpenAjax.org"&gt;http://www.OpenAjax.org&lt;/a&gt; site and the implementation is part of the ~/controls/jcl.js file that is included automatically.&lt;/p&gt;
&lt;p&gt;To register for such an event you need a little bit of JavaScript code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// a function that will catch the tree events by listening to de.mathertel.treeview.**.&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; showTreeEvent(&lt;span style="color: #0000ff"&gt;name&lt;/span&gt;, data) {
  &lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;("&lt;span style="color: #8b0000"&gt;click on &lt;/span&gt;" + data);
} &lt;span style="color: #008000"&gt;// showTreeEvent&lt;/span&gt;

OpenAjax.hub.subscribe("&lt;span style="color: #8b0000"&gt;de.mathertel.treeview.**&lt;/span&gt;", showTreeEvent);&lt;/pre&gt;
&lt;p&gt;The OpenAjax.hub.subscribe is registering the showTreeEvent function and this function will be passed the name of the event and the path in the data payload.&lt;/p&gt;
&lt;h3&gt;About the updated features&lt;/h3&gt;
&lt;p&gt;New to the current implementation is the support for the link attribute in the &amp;lt;file&amp;gt; elements and the publishing of events when clicking final nodes.&lt;/p&gt;
&lt;p&gt;If you want to see&amp;nbsp;more features or want to have more supported scenarios then let me know by using the&amp;nbsp;feature request function on &lt;a title="http://sourceforge.net/projects/ajaxengine/" href="http://sourceforge.net/projects/ajaxengine/"&gt;http://sourceforge.net/projects/ajaxengine/&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-3682677196188946122?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/3682677196188946122/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=3682677196188946122' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/3682677196188946122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/3682677196188946122'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/07/tree-view-ajax-control-update.html' title='Tree view Ajax control update'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-8622255036504084260</id><published>2007-07-07T22:33:00.001+02:00</published><updated>2007-07-07T22:37:02.430+02:00</updated><title type='text'>AjaxEngine is now on sourceforge.net</title><content type='html'>&lt;p&gt;You can now find a repository with the current version of the AjaxEngine, including the samples on &lt;/p&gt; &lt;p&gt;sourceforge at &amp;nbsp;&lt;a title="http://sourceforge.net/projects/ajaxengine/" href="http://sourceforge.net/projects/ajaxengine/"&gt;http://sourceforge.net/projects/ajaxengine/&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;There are some real great advantages by using a public community site:&lt;/p&gt; &lt;h3&gt;discussions and bug tracking&lt;/h3&gt; &lt;p&gt;I plan to use the bug tracking and forum tools and hope you'll find this helpful too.&lt;/p&gt; &lt;h3&gt;repository&lt;/h3&gt; &lt;p&gt;I was using subversion all over the last years on my local site so it was easy to switch to a public server.&lt;/p&gt; &lt;p&gt;You can now find the latest stable version (1.2) and the current work in progress also there:&lt;/p&gt; &lt;p&gt;&lt;a title="Link to the subversion repository by using the Tortoise client" href="tsvn:https://ajaxengine.svn.sourceforge.net/svnroot/ajaxengine"&gt;tsvn:https://ajaxengine.svn.sourceforge.net/svnroot/ajaxengine&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;collaboration&lt;/h3&gt; &lt;p&gt;Another big advantage of an open community platform is that it makes working together really easy.&lt;/p&gt; &lt;p&gt;New Developers for the project are welcome !&lt;/p&gt; &lt;p&gt;Of course the existing web site &lt;a href="http://www.mathertel.de/AJAXEngine"&gt;http://www.mathertel.de/AJAXEngine&lt;/a&gt; will remain active so you still can see all the samples live there.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-8622255036504084260?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/8622255036504084260/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=8622255036504084260' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/8622255036504084260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/8622255036504084260'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/07/ajaxengine-is-now-on-sourceforgenet.html' title='AjaxEngine is now on sourceforge.net'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-4115148618557626927</id><published>2007-06-29T22:58:00.001+02:00</published><updated>2007-06-29T22:58:50.000+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Forms'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><title type='text'>The fade effect and the DataFade control</title><content type='html'>&lt;p&gt;Here is a nice visual effect for data fields:&lt;/p&gt; &lt;p&gt;When&amp;nbsp;a&amp;nbsp;page&amp;nbsp;contains multiple values that might change from time to time it is&amp;nbsp;a good idea to&amp;nbsp;bring the users attention&amp;nbsp;to the&amp;nbsp;updated value. The DataFade implements this by&amp;nbsp;changing the background color of a field and fading it from yellow to the original background color that defined by the regular style.&lt;/p&gt; &lt;p&gt;The fading effect takes about a second and this is enough time for a human reader to focus the new field and reading the new value. The effect even seems to work if there are more values that are changed at the same time and it seems that the eyes can remember for some short time what fields have changed.&lt;/p&gt; &lt;p&gt;Here is a simple implementation using a horizontal scrollbar and a simple field.&lt;/p&gt; &lt;p&gt;&lt;a title="Fade Demo" href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/FadeDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/FadeDemo.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When the DataFade control is initialized the actual background color is detected and stored in the local orgcolor field.&lt;/p&gt; &lt;p&gt;If the DataFade control detects that the value has changed it sets the background color to yellow and by starting a timer the background color is changed by smoothly adopting the red, green and blue to the original color that was found when the control was initialized. &lt;/p&gt; &lt;p&gt;The DataFade control is implemented using a JavaScript Behavior so it can be used inside AjaxForms&amp;nbsp;for displaying, but not entering values. This is because it is inheriting the DataOutput Behaviour it implements&amp;nbsp;a setData(newValue)&amp;nbsp;method that is detected by the ajaxForms implementation and is used for setting the new value.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4115148618557626927?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4115148618557626927/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4115148618557626927' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4115148618557626927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4115148618557626927'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/06/fade-effect-and-datafade-control.html' title='The fade effect and the DataFade control'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-6256357662286926098</id><published>2007-06-19T23:19:00.001+02:00</published><updated>2007-10-15T21:11:58.911+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Aspects of OpenAjax</title><content type='html'>&lt;p&gt;You know I like standards.&lt;/p&gt; &lt;p&gt;Even if it is some kind of more complex to implement a solution based on a standard than using a direct and efficient but proprietary way, there are benefits on the long way that I just don't want to miss: the ideas and thoughts of others materialized in APIs, specifications and best practices.&lt;/p&gt; &lt;p&gt;That's why I use the SOAP standard webservice protocol for my Ajax implementations.&lt;/p&gt; &lt;h3&gt;OpenAjax&lt;/h3&gt; &lt;p&gt;Now &lt;a href="http://www.openajax.org/" target="_blank"&gt;OpenAjax Alliance&lt;/a&gt; is another try of a group of about 75 companies and organizations to define standards in the Ajax hemisphere. There are a lot of ideas and some good ideas too in the current discussions. We all know that it is hard to define a standard specification that gets agreed by the majority of the members. And it can take a long time until a standard proposal is adopted.&lt;/p&gt; &lt;p&gt;Right now a version 1.0 of the specifications are on their way and they contain some good stuff that I like to bring into the Aspects of Ajax framework and support an probably upcoming standard this way.&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification" href="http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification"&gt;http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Libraries and Namespaces&lt;/h3&gt; &lt;p&gt;There is only one world we live in and there is only one global namespace in JavaScript. The problem is that multiple frameworks when used simultaneously in one page MUST use different global variable names, different namespaces when implementing XHTML and different prefixes and aliases for the namespaces. Especially the global names might cause a lot of problems.&lt;/p&gt; &lt;p&gt;Did you try to use 2 libraries that both register the $() function but implement it differently?&lt;/p&gt; &lt;p&gt;The OpenAjax registerLibrary and unregisterLibrary methods that can be used to help mastering this problem space.&lt;/p&gt; &lt;p&gt;The &lt;strong&gt;ajax, &lt;/strong&gt;the &lt;strong&gt;proxies&lt;/strong&gt; and the &lt;strong&gt;jcl&lt;/strong&gt; prefix will be used by the Aspects of Ajax framework because these are the names of the global variables I use (beside minor important stuff). I hope and pray that nobody else will use this prefix in any other AJAX framework. (I am the first - I won! :-)&lt;/p&gt; &lt;p&gt;No, and seriously: I don't like the global ajax variable being registered by any framework and right now I am not happy about this early (2005) decision any more.&lt;/p&gt; &lt;p&gt;The namespace used by the Aspects of Ajax frameworks will be &lt;strong&gt;de.mathertel&lt;/strong&gt; because &lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;http://www.mathertel.de/AJAXEngine/&lt;/a&gt; is the URL where the documentation and the samples can be found on the web.&lt;/p&gt; &lt;p&gt;... but maybe it's time to register a product name related web address :-)&lt;/p&gt; &lt;p&gt;When implementing a standalone AJAX framework you do not have to care about these problems. Being compatible (and friendly to other frameworks) can open a wide space in combining functionality from different sources.&lt;/p&gt; &lt;h3&gt;Events - inter controls connections&lt;/h3&gt; &lt;p&gt;Connecting multiple controls on a page by using JavaScript can be a nightmare because many little scripts will have to know about the existing other elements on the page. If you want to reuse generalized controls this situation becomes worse and if you like to reuse components of different manufacturers ... &lt;/p&gt; &lt;p&gt;So it's a good thing to define a common functionality that does the job and that controls can use to talk to each other using the well known subscribe and publish pattern and the idea of events.&lt;/p&gt; &lt;p&gt;The Aspects of Ajax framework has a small implementation since almost 2 years (see &lt;a href="http://ajaxaspects.blogspot.com/2005/09/connecting-controls.html"&gt;http://ajaxaspects.blogspot.com/2005/09/connecting-controls.html&lt;/a&gt;) called "page properties" or data connections that also allows this kind of connectivity through the DataConnections object but compared with the event system of the OpenAjax hub specification there are some pros and cons.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The OpenAjax hub has defined an idea of namespaces and namespace notation like the namespace ideas known from .NET, Java and other environments. Events that are published are prefixed by a namespace so different providers of the same event name can be distinguished. The page properties of the Aspects of Ajax framework only had one global namespace (the page).  &lt;li&gt;Using the OpenAjax hub specifications it is possible to subscribe to specific events by specifying the long name of the event and by using a wildcards for registering to multiple events. In the Aspects of Ajax framework it was possible to subscribe to all events.  &lt;li&gt;The Aspects of Ajax framework has a mechanism that allows to poll for a current value of a prior published property change / event. The OpenAjax hub has no such methods defined but it is easy to implement an invisible control that logs all changes and offers some methods for getting the latest values.  &lt;li&gt;The Aspects of Ajax framework has some specific controls that helped while developing. One of them is a log of all events and the new values. Beside the changed implementation they also have a new parameter to specify what specific namespace they should watch.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Overall the OpenAjax implementation has some big advantages over the older DataConnections and the additional functionality can be added.&lt;/p&gt; &lt;h3&gt;Implementation&lt;/h3&gt; &lt;p&gt;The OpenAjax Alliance provides a &lt;a href="http://openajaxallianc.sourceforge.net/" target="_blank"&gt;reference implementation&lt;/a&gt; is available in an early version and other implementations of the specification are welcome. After reading the available specs and noticing that it is "just" better then my prior codings I decided to implement the specific details on my own and make them available in a standalone JavaScript file. Some requirements are implemented different than in the reference implementation and maybe you find the time to have a look at the difference if you like.&lt;/p&gt; &lt;h3&gt;The size of the implementation&lt;/h3&gt; &lt;p&gt;As of this writing the (unfinished) reference implementation is about 2801 bytes. The (current) implementation available on my side at &lt;a title="http://www.mathertel.de/OpenAjax" href="http://www.mathertel.de/OpenAjax"&gt;http://www.mathertel.de/OpenAjax&lt;/a&gt; is about 1300 bytes. Maybe my implementation is a little bit slower because I rely on regular expressions but I have not done any detailed measures yet. Both sizes are calculated by comparing a shrinked version using the tool from the dojo framework that is available online at &lt;a title="http://alex.dojotoolkit.org/shrinksafe/" href="http://alex.dojotoolkit.org/shrinksafe/"&gt;http://alex.dojotoolkit.org/shrinksafe/&lt;/a&gt;. This is because I don't want to compare the comment lines or different programming styles.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The same implementation is also embedded into the &lt;a title="~/controls/jcl.js" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/jcl.js" target="_blank"&gt;jcl.js&lt;/a&gt; implementation that also implements the JavaScript Behavior mechanism.&lt;/p&gt; &lt;h3&gt;Future planning&lt;/h3&gt; &lt;p&gt;I will have a look for the specification of the OpenAjax Alliance hub and I will post a compatible version. It is just good to have a second source.&lt;/p&gt; &lt;p&gt;The Aspects of Ajax framework. including the SOAP client for web services in JavaScript will register itself and will use the hub implementation as a substitution of the older DataConnections implementation that will be removed completely.&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-6256357662286926098?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/6256357662286926098/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=6256357662286926098' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/6256357662286926098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/6256357662286926098'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/06/aspects-of-openajax.html' title='Aspects of OpenAjax'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-4505038519586869373</id><published>2007-06-17T21:43:00.001+02:00</published><updated>2007-06-17T21:43:39.008+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenAjax'/><category scheme='http://www.blogger.com/atom/ns#' term='Forms'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>A simple page for displaying a record</title><content type='html'>&lt;p&gt;Building a page with a form to display and change a record is a common scenario and it should be easy to implement. Some of the basic ideas where already published last week and here is a concrete implementation. The page that can be found at &lt;a title="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx" href="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx"&gt;http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx&lt;/a&gt;&amp;nbsp;is&amp;nbsp; built by a combination of the 3 components:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;a&gt;Form&lt;/a&gt;&amp;nbsp;contains &lt;a&gt;DataInput&lt;/a&gt; fields and other Data Contol elements that are used to display the values.  &lt;li&gt;The &lt;a&gt;Menubar&lt;/a&gt; is used to offer the typical buttons for searching and navigating through the dataset.  &lt;li&gt;The &lt;a&gt;DataSource&lt;/a&gt; control controls the binding between these controls and the server side web methods.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;img src="http://www.mathertel.de/AJAX/images/AjaxFormControls.png"&gt;&lt;/p&gt; &lt;h3&gt;The Form element&lt;/h3&gt; &lt;p&gt;Many web applications need to display and modify relational data by using&amp;nbsp;a form and a offering a single record at each time. The form itself contains input fields to display the columns of the record and other html elements like labels or other static text around them.&lt;/p&gt; &lt;p&gt;All these elements together are held together by using a html container element that is called the form element. Because we handle all data mechanisms by using AJAX functionality we do not need a real &amp;lt;form&amp;gt; element but use a &amp;lt;div&amp;gt; element instead.&lt;/p&gt; &lt;p&gt;The functionality that is attached to&amp;nbsp;the form (the &amp;lt;div&amp;gt; element) of the page handles getting and setting values by respecting the correct formats for several datatypes and converting them to&amp;nbsp;regular xml data formats.&lt;/p&gt; &lt;p&gt;The great benefit from this approach is, that the server has to support only the standard xml format for the known datatypes and not any country or language specific formats. More on that in another post.&lt;/p&gt; &lt;p&gt;The functionality of the form element is implemented by using&amp;nbsp;the&amp;nbsp;&lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/DataForm.js" target="_blank"&gt;DataForm JavaScript Behavior&lt;/a&gt;&amp;nbsp;that is built reusing the functionality that was built in the early days in ajaxForms.js. By using a behavior the code was simplified and reduced.&lt;/p&gt; &lt;h3&gt;The Menubar element&lt;/h3&gt; &lt;p&gt;This element contains the typical buttons that enable the navigation through a set of records.&lt;/p&gt; &lt;p&gt;These buttons and icons will trigger&amp;nbsp;the corresponding methods of the datasource control by publishing events.&amp;nbsp;&lt;/p&gt; &lt;h3&gt;The DataSource control&lt;/h3&gt; &lt;p&gt;This element is not visible to the end user and is containing the main functionality to transfer the data from the server to the form element. It also contains a client side cursor model that help keeping state information away from the server.&lt;/p&gt; &lt;p&gt;The&amp;nbsp;following commands are available:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;clear&lt;/strong&gt;: This command will just clear all the values inside the form.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;search&lt;/strong&gt;: A call to the server is&amp;nbsp;started to retrieve the keys of the found records. The current values of the form before the search is started are used as a template so you can easily find a specific record or a set of records. The retrieved keys are used to form the cursor.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;first&lt;/strong&gt;: The first record in the cursor is retrieved from the server and is displayed inside the form.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;next&lt;/strong&gt;: The next record in the cursor is retrieved from the server and is displayed inside the form.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;previous&lt;/strong&gt;: The previous record in the cursor is retrieved from the server and is displayed inside the form.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;last&lt;/strong&gt;: The last record in the cursor is retrieved from the server and is displayed inside the form.&lt;/p&gt; &lt;p&gt;(future extensions: add, update, delete, ...)&lt;/p&gt; &lt;p&gt;The DataSource element also publishes an event when the data of the form was changed to inform other elements on the page that a new situation is existing.&lt;/p&gt; &lt;h3&gt;Searching&amp;nbsp;and the AJAX calls in the background&lt;/h3&gt; &lt;p&gt;The "search" button in the menubar must be used first to build the dataset. This is done on the server by searching for all the records that match the criteria given by the current values in the form fields. This is done by using the SearchAction that is passed to the AJAXEngine to call the search method of the webservice. This method is returning a list of unique keys, each one representing a record.  &lt;p&gt;Here is a sample how to search:  &lt;p&gt;You can write "UK" into the country field and press "search" to search all records that have "UK" in the country colum. The database provider also offers the possibility to search using wildcards. If you enter "U%" into the country field you will find all the records with a country starting with "U".  &lt;p&gt;After finding some data the dataset control automatically will fetch the first found record and will display in in the given form fields. This is done by using the DisplayAction that is passed to the AJAXEngine to call the fetch method of the webservice and passing the retrieved record data to the form.  &lt;p&gt;Using the arrow buttons you can step through the dataset. The clear button will clear the form without freeing the dataset but by loosing the current cursor position.  &lt;h3&gt;Events between the controls&lt;/h3&gt; &lt;p&gt;Connecting elements on the page might be done by using scripts&amp;nbsp;in one element that direct address the other element or by using events.  &lt;p&gt;Events like onclick and onload are already well known in the web development but they are limited to those events that are built into the DOM (Document Object Model). It is not possible to reuse this mechanism for other, self-built&amp;nbsp;events and another mechanism is needed for tasks&amp;nbsp;like this.  &lt;p&gt;The &lt;a href="http://www.openajax.org/" target="_blank"&gt;OpenAjax Alliance&lt;/a&gt;&amp;nbsp;is targeting this problem&amp;nbsp;with the &lt;a href="http://www.openajax.org/OpenAjax%20Hub.html" target="_blank"&gt;hub implementation&lt;/a&gt; that is&amp;nbsp;still under development for version 1.0.  &lt;p&gt;Inside jcl.js&amp;nbsp;(&lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/jcl.js" target="_blank"&gt;view source&lt;/a&gt;) you can now find a (almost) compatible version of the OpenAjax&amp;nbsp;specification that has only about 1300 bytes of real code. When the specification is finished I will release a compatible version and will follow the idea of a common functionality and compatibility of the Ajax frameworks. More on that in another post...&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4505038519586869373?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4505038519586869373/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4505038519586869373' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4505038519586869373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4505038519586869373'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/06/simple-page-for-displaying-record.html' title='A simple page for displaying a record'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-1039269385602072208</id><published>2007-06-11T19:39:00.001+02:00</published><updated>2007-06-11T19:39:26.464+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Forms'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Building data-centric and forms based AJAX applications</title><content type='html'>&lt;p&gt;Most of the business web applications on the Internet are HTML forms based applications where data, bound to html elements, is the core functionality. I am talking about registration forms, dialogs and pages to display and modify records of a server side relational database system, ERP or CRM systems. There&amp;nbsp;are not&amp;nbsp;a lot of drag &amp;amp; drop elements or popping visual effects here but most active elements deal with data that comes from databases or other data sources.&lt;/p&gt; &lt;p&gt;Many developers do not build&amp;nbsp;E-Mail applications, portal&amp;nbsp;frameworks, maps or mashups but we need to display, edit and control records from a company's database and implement transactions on these entities.&lt;/p&gt; &lt;p&gt;This part of the framework and the upcoming posts&amp;nbsp;are about the aspects and &lt;strong&gt;coding the client side&lt;/strong&gt; of this kind of web applications and&amp;nbsp;here is my blueprint of the ongoing work that will extend and consolidate the framework in this direction.&lt;/p&gt; &lt;p&gt;The server side is kept minimal for now and you can adopt any data binding layer on the server you like as long as you implement the small ITableDataService interface on the web service that handles the AJAX calls.&lt;/p&gt; &lt;p&gt;Inside the archive file &lt;a title="Ajax_new.zip" href="http://www.mathertel.de/Downloads/Start_AJAX_new.aspx"&gt;Ajax_new.zip&lt;/a&gt;&amp;nbsp;download you can follow the development of this part of the framework in the &lt;a href="http://www.mathertel.de/AJAXEngine/S06_AJAXForms/default.aspx"&gt;S06_AJAXForms&lt;/a&gt; folder.&lt;/p&gt; &lt;h3&gt;Typical data-centric web pages&lt;/h3&gt; &lt;p&gt;From a high level viewpoint onto pages that implement data-centric applications you see that the elements on the page can be categorized into the following cases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fields and other elements where values are shown and edited by the users (Input fields, checkboxes, ...)  &lt;li&gt;Buttons that help editing these values (calendar popup, drop-down lists, ...)  &lt;li&gt;Foreign key Lookup mechanisms [check against a list of countries]  &lt;li&gt;Buttons that offer a way of navigation through huge data sources&amp;nbsp; (|&amp;lt; first, next &amp;gt;&amp;gt;, ...)  &lt;li&gt;Buttons that commit a current state to the backend system ([Update])  &lt;li&gt;Buttons that trigger special transactions or back-end calculations  &lt;li&gt;Tables that display mass data by paging or scrolling  &lt;li&gt;Tree Views that display hierarchical (mass-) data &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Some of these features where already shown here on the blog but it's time to rearrange these features a little bit and make them working together. Here are some&amp;nbsp;aspects about the major features. &lt;/p&gt; &lt;h3&gt;Forms and binding data&lt;/h3&gt; &lt;p&gt;A core functionality of this kind of business application is a data binding functionality that connects elements of the form to the corresponding data source. Because we want to keep the page loaded while navigating through many records coming from the server we need a client-side mechanism for&amp;nbsp;moving data into html elements and back. The core of this mechanism was introduced in an early post using the ajaxForms.js include file. This mechanism&amp;nbsp;will be extended and tuned a little bit.&lt;/p&gt; &lt;h3&gt;Supporting national language specific notations&lt;/h3&gt; &lt;p&gt;Of course we need some functionality to convert non-text datatypes to a string representation that can be read by the user and this frameworks goes further by converting values to human readable strings with the typical national language specific notations in decimal numbers and date values.&lt;/p&gt; &lt;p&gt;Because this is done on the client we need no conversion on the server and therefor have a server that must not care about the specific formats out there in the world. Supporting these notations is done by using a plugable mechanism that delivers the right conversion routines to the client based on the language settings of the browser.&lt;/p&gt; &lt;h3&gt;Input Helpers&lt;/h3&gt; &lt;p&gt;These elements are bound to a standard input field. They are built to help entering some specific datatypes by offering an alternative input method . This might be small dialogs like a calendar popup, drop-down buttons that open a list of possible values&amp;nbsp;or sliders that can be used to adjust a value.&lt;/p&gt; &lt;p&gt;Some of these controls do already exist in the controls collection of this framework but again they have to be adjusted and extended a little bit.&lt;/p&gt; &lt;h3&gt;Navigating through table data&lt;/h3&gt; &lt;p&gt;In many cases the data comes from a data source on the server that stores many records in a&amp;nbsp;table format. On the client we will need some elements that help us navigating through this kind of data. The most common used user interface elements are buttons that allow positioning to the first, previous, next and last record and support searching and modifying the current record.&lt;/p&gt; &lt;p&gt;By implementing a webservice on the server that implements a common interface and a set of controls on the client that use this webservice there will a set of basic functionality available without the need for scripting on the client.&lt;/p&gt; &lt;h3&gt;Tree Data&lt;/h3&gt; &lt;p&gt;A data bound tree sample has already been published at &lt;a title="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx" href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;but we will see how to integrate it into the scenario by reusing the same web service interface for the Ajax call.&lt;/p&gt; &lt;h3&gt;Common data interface on the server&lt;/h3&gt; &lt;p&gt;Serving data from the server and some more functions is provided to the client by using several methods of a webservice. This webservice has to support several simple methods that will bring the databinding to the client through ajax calls. To support an easy development of these web services the ITableDataService interface is defined&amp;nbsp;with the minimal set of methods.&lt;/p&gt; &lt;h3&gt;AJAX Controls for AJAX forms&lt;/h3&gt; &lt;p&gt;AJAX Form Controls are very similar to the PropXXX controls I had introduced some time ago. AJAX Form Controls are made to bind data from an external data provider and from web services using elements on a html page. The AJAX Form Controls are AJAX Controls that implement the Data Interface functions.&lt;/p&gt; &lt;p&gt;(The PropXXX Controls are using primarily the Page Properties storage mechanism and are used to control the state of the view of the page. This is typically something different than the data, but we will see some changes in this scenario too in some time to make it OpenAJAX compatible).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:da13211a-6f70-438d-a06a-c572cb5761a4" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/AJAX" rel="tag"&gt;AJAX&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Forms" rel="tag"&gt;Forms&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Controls" rel="tag"&gt;Controls&lt;/a&gt;, &lt;a href="http://technorati.com/tags/JavaScript" rel="tag"&gt;JavaScript&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-1039269385602072208?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/1039269385602072208/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=1039269385602072208' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/1039269385602072208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/1039269385602072208'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/06/building-data-centric-and-forms-based.html' title='Building data-centric and forms based AJAX applications'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-649112012101302065</id><published>2007-06-03T23:07:00.001+02:00</published><updated>2007-06-09T11:38:08.466+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>A simple menubar</title><content type='html'>&lt;p&gt;By using the hover&amp;nbsp;effect it is possible to realize a simple menubar that will be used by an upcoming control that allows rich text editing.&amp;nbsp;Here I focus on the implementation of the menubar that is implemented as a separate control and can also be used with small changes for other purposes.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.mathertel.de/AJAX/Images/menubarsample.png"&gt;&lt;/p&gt; &lt;h3&gt;Building the html code for the menubar&lt;/h3&gt; &lt;p&gt;The html code for building a menubar is implemented by using an outer &amp;lt;div&amp;gt; element with a classname "VEMenuBar". This element is used as the wrapper for all parts of the menubar and is displayed in the background.&lt;/p&gt; &lt;p&gt;The inner elements and menu items can be implemented using &amp;lt;img&amp;gt; images or &amp;lt;span&amp;gt; elements with text content.&lt;/p&gt; &lt;p&gt;The third type of an inner element is a vertical line or separator that can be used to group elements.&lt;/p&gt; &lt;p&gt;Here is a small sample:&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenuBar"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;span&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenu"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;tabindex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"datasource.search();"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Search&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;span&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;img&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenuSeparator"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;""&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"../controls/images/white.gif"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;img&lt;/span&gt; &lt;span style="color: #ff0000"&gt;class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"VEMenu"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"show first record"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;tabindex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"../controls/images/first.gif"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;The hover effect&lt;/h3&gt;
&lt;p&gt;When positioning the mouse over any enabled item of the menubar the individual item for starting a specific command is highlighted.&amp;nbsp;For implementing this effect&amp;nbsp;the already known &lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/MouseHoverDemo.aspx"&gt;hover behavior&lt;/a&gt; is reused. All that we need to implement it is to include the hover.js include file in the head of the page and setting the hover attribute on every element.&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;script type="&lt;span style="color: #8b0000"&gt;text/javascript&lt;/span&gt;" src="&lt;span style="color: #8b0000"&gt;../controls/Hover.js&lt;/span&gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;h3&gt;The menubar behavior (MenubarBehavior)&lt;/h3&gt;
&lt;p&gt;This behavior implements all the basic functionality for menubars. When bound to a html element it also loops through all the children of the outer element an sets the hover attribute to true for those elements that have a classname "VEMenu". This allows to enable the hover effect without implementing the hover attribute for every menu item.&lt;/p&gt;
&lt;p&gt;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. 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.&lt;/p&gt;
&lt;h3&gt;The HTML elements that build the menubar&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;First of all&amp;nbsp;the outermost&amp;nbsp;element of the menubar that will get attached the behavior is a div element with a classname "VEMenuBar". This element is used as the wrapper for all parts of the menubar and is displayed in the background.&lt;/p&gt;
&lt;p&gt;The icons or other images are placed in the menu by using &amp;lt;img&amp;gt; elements as children inside the VEMenuBar element&lt;/p&gt;
&lt;p&gt;and will&amp;nbsp;have a classname "VEMenu". They will automatically get an attribute hover="true" to enable the hover effect.&lt;/p&gt;
&lt;h3&gt;CSS definitions&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;Some&amp;nbsp;classnames need to be defined: &lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuBar&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;background-color&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;#eeeeee&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;padding&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;2px 8px 2px 8px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;height&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;20px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;overflow&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;hidden&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;This defines the background color of the menubar. The padding definition will keep the inner icons away from the border.&lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuBar&lt;/span&gt; * { &lt;span style="color: #ff0000"&gt;vertical-align&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;top&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;All elements will be vertically aligned by the top.&lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuBar&lt;/span&gt; &lt;span style="color: #800000"&gt;span&lt;/span&gt; {&lt;span style="color: #ff0000"&gt;display&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;-moz-inline-box&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;display&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;inline-block&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;&amp;lt;span&amp;gt; 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.&lt;br&gt;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.&lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenu&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;border&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;0px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;padding&lt;/span&gt;:2px}&lt;/pre&gt;
&lt;p&gt;This rule is used for the state of a 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.&lt;/p&gt;
&lt;p&gt;.VEMenuHover { border-style:solid;border-width:1px;border-color: #acc1e4 #203050 #203050 #acc1e4;padding:1px}&lt;br&gt;This is the state of a 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 1 px to avoid the shifting and flickering of the graphic.&lt;/p&gt;
&lt;p&gt;.VEMenuPushed { border-style:solid;border-width:1px;border-color: #203050 #acc1e4 #acc1e4 #203050;padding:1px}&lt;br&gt;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.&lt;/p&gt;&lt;pre class="code"&gt;.&lt;span style="color: #800000"&gt;VEMenuSeparator&lt;/span&gt; { &lt;span style="color: #ff0000"&gt;display&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;inline-block&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;height&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;20px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;width&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;1px&lt;/span&gt;;&lt;span style="color: #ff0000"&gt;border-left&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;solid 1px #203050&lt;/span&gt;;}&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Attaching functionality&lt;/h3&gt;
&lt;p&gt;The MenubarBehavior implementation has no special implementation for the onclick event on VEMenu items. The functionality of the menubar item should attached by using the onclick events directly.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can find the state of the current implementation here:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx" href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx" target="_blank"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(see the page source by using the view link in the upper right corner)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Download the current version under development&lt;/h3&gt;
&lt;p&gt;I've added another downloadable archive file to the site : &lt;a title="Ajax_new.zip" href="http://www.mathertel.de/Downloads/Start_AJAX_new.aspx"&gt;Ajax_new.zip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This Zip-File contains the current version of the ASP.NET 2.0 web project that builds this side.&lt;br&gt;The complete AJAX Engine and all samples and also unfinished samples and componente are included.&lt;br&gt;Use this download If you want to experiment with the Engine or if you want to have a look for the newest additions and features.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-649112012101302065?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/649112012101302065/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=649112012101302065' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/649112012101302065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/649112012101302065'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/06/simple-menubar.html' title='A simple menubar'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-7776369667963926290</id><published>2007-05-21T21:19:00.001+02:00</published><updated>2007-06-09T11:39:23.132+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>Using webservice calls with multiple parameters</title><content type='html'>&lt;p&gt;The restriction that the AJAXEngine supported only methods with one parameter had been a&amp;nbsp;topic to &lt;a href="http://ajaxaspects.blogspot.com/2006_02_01_archive.html"&gt;some postings&lt;/a&gt; in the blog and also to some good comments with &lt;a href="https://www.blogger.com/comment.g?blogID=7581919&amp;amp;postID=114036017230506348"&gt;good solutions&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;Because the problem was only restricted by the AJAX Engine itself and not by the underlying &lt;a href="http://www.mathertel.de/AJAX/JavaScriptSOAPClient.aspx"&gt;JavaScript proxy layer&lt;/a&gt;&amp;nbsp;I looked for a small and neat solution and finally found that the often overlooked Javascript method &lt;a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply"&gt;apply&lt;/a&gt; &lt;/p&gt; &lt;p&gt;helps here.&lt;/p&gt; &lt;p&gt;The implemented way of passing more than one parameter is (like suggested) to use an Array as a return value of the prepare function. Because arrays are also supported as a parameter to the called&amp;nbsp;method itself&amp;nbsp;a extra hint is used to distinguish these 2 scenarios. &lt;/p&gt; &lt;p&gt;Here is how to implement the prepare method for this case:&lt;/p&gt;&lt;pre class="code"&gt;prepare: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (ds) { 
  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; p = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Array&lt;/span&gt;();
  p[0] = ajaxForms.getData(ds.form);
  p[1] = "&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;";
  p.multi = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;span style="color: #008000"&gt;// the hint for the ajax Engine&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;(p);
},&lt;/pre&gt;
&lt;p&gt;The changes in the AJAX Engine layer is only a condition check and a call using the apply method:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// start the call&lt;/span&gt;
ca.call.func = ajax.Finish;
ca.call.onException = ajax.Exception;
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((data.&lt;span style="color: #0000ff"&gt;constructor&lt;/span&gt; == &lt;span style="color: #0000ff"&gt;Array&lt;/span&gt;) &amp;amp;&amp;amp; (data.multi != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)) &lt;span style="color: #008000"&gt;// 19.05.2007&lt;/span&gt;
  ca.call.apply(ca, data);
&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
  ca.call(data);&lt;/pre&gt;
&lt;p&gt;If you want to use this feature, you can download the &lt;a href="http://www.mathertel.de/AJAXEngine/ajaxcore/ajax.js"&gt;ajax.js&lt;/a&gt; file directly. A complete version will be available some day soon including new samples and features.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-7776369667963926290?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/7776369667963926290/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=7776369667963926290' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/7776369667963926290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/7776369667963926290'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/05/using-webservice-calls-with-multiple.html' title='Using webservice calls with multiple parameters'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-8922242508599867136</id><published>2007-05-14T21:59:00.001+02:00</published><updated>2007-06-09T11:38:39.844+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Accordion menu</title><content type='html'>&lt;p&gt;&lt;img style="float: right" src="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/AccordionDemo.png"&gt; I added another visual effect for HTML that is called an accordion menu by using a JavaScript Behavior.&lt;/p&gt; &lt;p&gt;An&amp;nbsp;accordion menu is a collection of multiple, stacked panels.&lt;/p&gt; &lt;p&gt;Only one of them is visible and another can be opened by clicking the header of a closed one using a smooth transition of the heights of the content area of the panels.&lt;/p&gt; &lt;p&gt;Have a look at: &lt;a title="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/AccordionDemo.aspx" href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/AccordionDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/AccordionDemo.aspx&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-8922242508599867136?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/8922242508599867136/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=8922242508599867136' title='7 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/8922242508599867136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/8922242508599867136'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/05/accordion-menu.html' title='Accordion menu'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-3576389881634596336</id><published>2007-05-02T21:35:00.001+02:00</published><updated>2007-06-28T20:41:19.745+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ebook'/><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>A new version of the book "Aspects of AJAX" is online</title><content type='html'>&lt;p&gt;Beside writing some more pages it also contains some corrections and the new posts on this blog where added also.&lt;/p&gt;&lt;p&gt;You can get it for free from 
&lt;a href="http://www.mathertel.de/Ajax/AJAXeBook.aspx"&gt;http://www.mathertel.de/Ajax/AJAXeBook.aspx.&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-3576389881634596336?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/3576389881634596336/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=3576389881634596336' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/3576389881634596336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/3576389881634596336'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/05/new-version-of-book-of-ajax-is-online.html' title='A new version of the book &amp;quot;Aspects of AJAX&amp;quot; is online'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-4587465800082276982</id><published>2007-04-05T21:25:00.001+02:00</published><updated>2007-05-01T19:13:18.652+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><title type='text'>Using Inheritance in JavaScript Behaviors</title><content type='html'>&lt;p&gt;While working on some samples using (different) menubar, I found it helpful to inherit a JavaScript Behavior from a more general JavaScript Behavior. This would give me the chance to implement the common general Javascript methods only once and leave specific functionality in the derived Behavior.&lt;/p&gt; &lt;p&gt;Here is the sample:&lt;/p&gt; &lt;p&gt;&lt;img height="24" src="http://www.mathertel.de/AJAX/Images/menubarsample.png"&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;// this is a basic behavior definition for menubars&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; MenubarBehavior = {
&amp;nbsp; init: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; () {
&lt;span style="color: #008000"&gt;    // activate the hover effect on all menu items&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; allitems = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.getElementsByTagName("&lt;span style="color: #8b0000"&gt;*&lt;/span&gt;");
&lt;span style="color: #0000ff"&gt;    for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; o &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; allitems)
&lt;span style="color: #0000ff"&gt;      if&lt;/span&gt; (allitems[o].className == "&lt;span style="color: #8b0000"&gt;VEMenu&lt;/span&gt;") {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; allitems[o].hover = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;},&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;  onkeypress: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(evt) {
    evt = evt || &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.event;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; kc = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.fromCharCode(evt.keyCode);
&lt;span style="color: #0000ff"&gt;    if&lt;/span&gt; ((&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._attachedBehaviour.onclick != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p&gt;      &amp;amp;&amp;amp; (evt != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; ((kc == "&lt;span style="color: #8b0000"&gt; &lt;/span&gt;") || (kc == "&lt;span style="color: #8b0000"&gt;\r&lt;/span&gt;"))) {
&lt;span style="color: #0000ff"&gt;      this&lt;/span&gt;._attachedBehaviour.onclick.call(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, evt);
    } &lt;span style="color: #008000"&gt;// if&lt;/span&gt;
  } &lt;span style="color: #008000"&gt;// onkeypressed&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// MenubarBehavior&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;This is a basic implemenation that enables the hover effect for all VEMenu items found inside the menubar and to simulate a click event if the spacebar or return key is used while the focus is on a menuitem.&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;// this is a basic behavior definition for menubars&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; EditMenubarBehavior = {
&amp;nbsp; inheritFrom: MenubarBehavior,&lt;/p&gt;&lt;p&gt; 
&amp;nbsp; init: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp; MenubarBehavior.init.call(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
&amp;nbsp; },&lt;/p&gt;&lt;p&gt; 
  onclick: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(evt) {
    evt = evt || &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.event;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; src = evt.srcElement;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; cmd = src.&lt;span style="color: #0000ff"&gt;name&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    if&lt;/span&gt; (cmd != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
      cmd = cmd.split(';');
      HtmlEditBehaviour.Command(cmd[0], cmd[1]);
    }
  } &lt;span style="color: #008000"&gt;// onclick&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// EditMenubarBehavior&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;This is the implementation of the derived Behavior definition.&lt;/p&gt;
&lt;p&gt;If you ask why I do not use the JavaScript inheritance mechanism, then you have a good question - i tried.&lt;/p&gt;
&lt;p&gt;Using the new operator and the prototype mechanism does not work here because we attach methods to HTML elements and some other problems came up too.&lt;/p&gt;
&lt;p&gt;The article of Nicholas C. Zakas at: &lt;a title="http://www.sitepoint.com/article/javascript-objects" href="http://www.sitepoint.com/article/javascript-objects" target="_blank"&gt;http://www.sitepoint.com/article/javascript-objects&lt;/a&gt;&amp;nbsp;also describes the topic.&lt;/p&gt;
&lt;p&gt;You can find the state of the current implementation here:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx" href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx" target="_blank"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(see the page source by using the view link in the upper right corner)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The only code I had to add to the LoadBehaviour method (that does something very similar to the extends method of Zakas) are these 3 lines of code to recursively bind the Behaviors starting with the base class.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (behaviour.inheritFrom != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.LoadBehaviour(obj, behaviour.inheritFrom);
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.List.pop();&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;See controls/jcl.js (&lt;a title="jcl.js source code" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=controls/jcl.js" target="_blank"&gt;view source&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(I'll publish a new version of the framework as a zip &lt;a href="http://www.mathertel.de/Downloads/Start_AJAX.aspx" target="_blank"&gt;here&lt;/a&gt; file when this sample is finished).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-4587465800082276982?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/4587465800082276982/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=4587465800082276982' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4587465800082276982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/4587465800082276982'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/04/using-inheritance-in-javascript.html' title='Using Inheritance in JavaScript Behaviors'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-2279835600492286646</id><published>2007-02-24T23:22:00.001+01:00</published><updated>2007-06-10T16:58:27.698+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><title type='text'>JavaScript Behavior Tutorial</title><content type='html'>&lt;p&gt;The complete Tutorial is now online.&lt;/p&gt;&lt;p&gt;If you worry about too much JavaScript fragments in too many places you need a concept of reusing client side functionality on a component level.&lt;/p&gt;&lt;p&gt;This is a step by step instruction for building a new client side component by using the JavaScript behavior mechanism. It is first implemented without using any server side help by only implementing JavaScript in a plain html file. Later it is evolved into an ASP.NET user control.&lt;/p&gt;&lt;p&gt;See how to implement JavaScript behaviors from the scratch.&lt;/p&gt;&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S05_JSB/default.aspx" href="http://www.mathertel.de/AJAXEngine/S05_JSB/default.aspx"&gt;http://www.mathertel.de/AJAXEngine/S05_JSB/default.aspx&lt;/a&gt;&lt;/p&gt;&lt;h2&gt; &lt;/h2&gt;&lt;h2&gt;New release of the framework and samples &lt;/h2&gt;&lt;p&gt;The zip files with the complete framework and samples have also been updated today:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.mathertel.de/Downloads/Start_AJAX.aspx"&gt;Ajax.zip&lt;/a&gt; (1.367 kByte)
This Zip-File contains the ASP.NET 2.0 web project that builds this side. The complete AJAX Engine and all samples are included. Use this project when you want to start building your AJAX web application.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.mathertel.de/Downloads/Start_AJAXEngine.aspx"&gt;AJAXEngine.zip&lt;/a&gt; (159 kByte)
This Zip-File contains the core files of the AJAX engine and the AJAX controls. You can use this if you want to update your project with the updated core files.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-2279835600492286646?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/2279835600492286646/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=2279835600492286646' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2279835600492286646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/2279835600492286646'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/02/javascript-behavior-tutorial.html' title='JavaScript Behavior Tutorial'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-116914912965646820</id><published>2007-01-18T20:38:00.000+01:00</published><updated>2007-06-10T17:00:35.675+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Building JavaScript Behaviors - 3</title><content type='html'>&lt;h3&gt;Methods for event handling&lt;/h3&gt;&lt;p&gt;The methods that are used to handle events from the mouse, keyboard or system are identified by their name prefix "on".  When the behavior is bound to the HTML element these methods are not just copied over from the JavaScript behavior declaration to the html element but are wrapped by a special function that looks like&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;() {
  &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; method.apply(htmlElement, &lt;span style="color:#0000ff;"&gt;arguments&lt;/span&gt;);
}&lt;/pre&gt;
&lt;p&gt;This wrapper is generated automatically for all on__ methods to ensure that the JavaScript "this" pointer is pointing to the htmlElement the method belongs to. This really simplifies writing event code.&lt;/p&gt;
&lt;h3&gt;Simple Events&lt;/h3&gt;
&lt;p&gt;The first sample already used an event (onclick) and registered a method to calculate a new random number for the dice. &lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;// classical event handler implementation&lt;/p&gt;&lt;p&gt;onclick: &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;(evt) {
  evt = evt  &lt;span style="color:#0000ff;"&gt;window&lt;/span&gt;.event;
  &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; src = evt.srcElement;

  src.rolling = 50;
  src.count = 0;
  src.rollNext();
}&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;Because the this pointer is adjusted to the htmlElement we can use it instead of finding the right element through the event property srcElement:&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;// simpler event handler implementation&lt;/p&gt;&lt;p&gt;onclick: &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;(evt) {
  &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.rolling = 50;
  &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.count = 0;
  &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.rollNext();
}&lt;/p&gt;&lt;/pre&gt;
&lt;h3&gt;Global Events&lt;/h3&gt;
&lt;p&gt;Sometimes it is not possible to implement an event code by using this simple on__ naming scheme because the event that the behavior needs is not thrown to the htmlElement of the behavior.&lt;/p&gt;
&lt;p&gt;If you are interested in global events you need to attach a method by using the AttachEvent method that is available through the jcl object. Don't use the on___ naming scheme for this method:&lt;/p&gt;&lt;pre class="code"&gt;jcl.AttachEvent(&lt;span style="color:#0000ff;"&gt;document&lt;/span&gt;, "&lt;span style="color:#8b0000;"&gt;onmousedown&lt;/span&gt;", &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._onmousemove);&lt;/pre&gt;
&lt;p&gt;If you are not interested in these events all the time the handler can be detached by calling:&lt;/p&gt;&lt;pre class="code"&gt;jcl.DetachEvent(&lt;span style="color:#0000ff;"&gt;document&lt;/span&gt;, "&lt;span style="color:#8b0000;"&gt;onmousemove&lt;/span&gt;", &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._onmousemove);&lt;/pre&gt;
&lt;h3&gt;Mouse Events&lt;/h3&gt;
&lt;p&gt;Mouse events are a little bit special when implementing a drag&amp;drop scenario. The onmousedown will always be raised on the element that will be dragged around but the other 2 events mousemove (while dragging) and onmouseup (when dragging ends and the drop occours) may be raised on any other elent on the page or even on the document object itself. Because the event "bubbles up" we can get all the events by attaichg these 2 methods to the document object.&lt;/p&gt;
&lt;p&gt;The sample at &lt;a href="http://www.mathertel.de/AJAXEngine/S05_JSB/VBoxDemo.aspx"&gt;VBoxDemo.aspx&lt;/a&gt; is using the &lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/vbox.js"&gt;VBox.js&lt;/a&gt; behavior that allows changing the width of the vertical separation by dragging the line between the left and right content.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;You can download the updated files from &lt;a title="JSBTutorial zip file" href="http://www.mathertel.de/Downloads/Start_JSBTutorial.aspx"&gt;http://www.mathertel.de/Downloads/Start_JSBTutorial.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:d319d7e2-148a-43ac-8a42-b74a78a20fb1" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;del.icio.us tags: &lt;a href="http://del.icio.us/popular/JavaScript" rel="tag"&gt;JavaScript&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/behaviour" rel="tag"&gt;behaviour&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/usercontrols" rel="tag"&gt;usercontrols&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-116914912965646820?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/116914912965646820/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=116914912965646820' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116914912965646820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116914912965646820'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/01/building-javascript-behaviors-3.html' title='Building JavaScript Behaviors - 3'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-116827238210634461</id><published>2007-01-08T17:06:00.000+01:00</published><updated>2007-06-10T17:00:18.639+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Building JavaScript Behaviors - 2</title><content type='html'>&lt;p&gt;The sample from the last post about building JavaScript Behaviors is not very realistic, because it is not configurable and missing parameters.&lt;/p&gt;&lt;h3&gt;Properties, Attributes and Parameters&lt;/h3&gt;&lt;p&gt;The way parameters are passed to the behavior implementation is some kind of tricky:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;you write down a parameter into the *.aspx source file. &lt;li&gt;when the page is called from the server the parameter is passed to the server side control. &lt;li&gt;the parameter is then written out into the response (html) stream and send to the client. &lt;li&gt;when the behavior is attached to the html element it is made available to javascript. &lt;li&gt;the behavior implementation is using the parameter by using this.&lt;em&gt;parameter.&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are some traps and tricks on the way.&lt;/p&gt;&lt;p&gt;Take care of uppercase characters in the parameter name. Parameters with uppercase characters work fine on the server but using them on the client breaks the xhtml format spec. You can use lowercase parameters on the server and the client and you don't get confused when writing code for the server platform and the client platform the same time. &lt;/p&gt;&lt;p&gt;If you want to make a parameter available to the server control you have to add a public property or a public field to the class.&lt;/p&gt;&lt;p&gt;Using public fields is working fine but Visual Studio will not help with intellisense then so I prefer using a encapsulated private field using a public property:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; _datatype = String.Empty;

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; datatype {
  &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _datatype; }
  &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; { _datatype = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }
} &lt;span style="color:#008000;"&gt;// datatype&lt;/span&gt;

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; working_but_no_intellisense = String.Empty;&lt;/pre&gt;
&lt;p&gt;Passing null through a parameter just doesn't work because you cannot specify an attribute for a xml or html tag with a null value. I am using empty strings instead.&lt;/p&gt;
&lt;p&gt;If no attribute value is specified in the source code you need to define a default value. The easiest is to assign the default value to the private server field declaration and always render the attribute into the response stream.&lt;/p&gt;
&lt;p&gt;The firefox browser makes a big difference between attributes of a html element and a property of an object so when attaching a behavior to a html element all the attributes are copied into object properties.&lt;/p&gt;
&lt;p&gt;Don't use any reserved words you know from C#, VB.NET, JAVA, JavaScript, HTML or the DOM specification as a name and don't start a name with "on" because this naming convention is used for identifying event handlers.&lt;/p&gt;
&lt;h3&gt;1. Adding a parameter to the dice sample server control&lt;/h3&gt;
&lt;p&gt;The sample up to now is only showing random numbers from 1 to 6. A new parameter named "maxnumber" should make it possible to get random numbers between 1 and any positive number greater than 2.:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; _maxnumber = 6;

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; maxnumber {
  &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _maxnumber; }
  &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; { _maxnumber = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }
} &lt;span style="color:#008000;"&gt;// maxnumber&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;This parameter is not needed on the server side and we just pass it to the client through a html attribute:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"&amp;lt;%=this.ClientID %&amp;gt;"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"Wuerfel"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;maxnumber&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"&amp;lt;%=this.maxnumber %&amp;gt;"&lt;/span&gt;
  &lt;span style="color:#ff0000;"&gt;unselectable&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"on"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;click&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;You can find this implementation in &lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/S05_JSB/wuerfel2.ascx"&gt;wuerfel2.ascx&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;2. Adding a parameter to the behavior&lt;/h3&gt;
&lt;p&gt;On the client side we need to declare tha parameter as well. The given assignment will always be overwritten be the attribute the server adds to the html element.&lt;/p&gt;
&lt;p&gt;And then we must use.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#008000;"&gt;// parameter to set the maximum number&lt;/span&gt;
maxnumber : 6,

&lt;span style="color:#008000;"&gt;// find a random number&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; n = &lt;span style="color:#0000ff;"&gt;Math&lt;/span&gt;.floor(&lt;span style="color:#0000ff;"&gt;Math&lt;/span&gt;.random()*(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.maxnumber-1))+1;&lt;/pre&gt;
&lt;p&gt;You can find this implementation in &lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/S05_JSB/wuerfel2.js"&gt;wuerfel2.js&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;3. Using the new feature&lt;/h3&gt;
&lt;p&gt;Now the new parameter can be used on any wuerfel2 tag:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;uc1&lt;/span&gt;:&lt;span style="color:#ff0000;"&gt;Wuerfel2&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;ID&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"Wuerfel2"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;maxnumber&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"42"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;runat&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"server"&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;You can find it in &lt;a href="http://www.mathertel.de/AJAXEngine/S05_JSB/Wuerfel_05.aspx"&gt;Wuerfel_05.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;You can download the updated files from &lt;a title="JSBTutorial zip file" href="http://www.mathertel.de/Downloads/Start_JSBTutorial.aspx"&gt;http://www.mathertel.de/Downloads/Start_JSBTutorial.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:afc9b2cf-7a08-44b6-9cfd-3b2c0707b50e" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;del.icio.us tags: &lt;a href="http://del.icio.us/popular/JavaScript" rel="tag"&gt;JavaScript&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/behaviour" rel="tag"&gt;behaviour&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/usercontrols" rel="tag"&gt;usercontrols&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-116827238210634461?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/116827238210634461/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=116827238210634461' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116827238210634461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116827238210634461'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/01/building-javascript-behaviors-2.html' title='Building JavaScript Behaviors - 2'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-116800290968458166</id><published>2007-01-05T14:15:00.000+01:00</published><updated>2007-06-10T17:04:40.230+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='license'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>AJAX Aspects is now available under the BSD license</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;p&gt;After some discussions and some reading I decided to change the license of my public software available from &lt;a href="http://www.mathertel.de"&gt;http://www.mathertel.de&lt;/a&gt; to a BSD style license. It's a better license for software projects then the previously used &lt;a href="http://creativecommons.org/licenses/by/2.0/de/"&gt;Creative Commons Attribution 2.0 Germany License&lt;/a&gt;. &lt;p&gt;The new license text is available at &lt;a title="http://www.mathertel.de/License.aspx" href="http://www.mathertel.de/License.aspx"&gt;http://www.mathertel.de/License.aspx&lt;/a&gt;. The source code comments pointing to the license will be adjusted in the next days.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-116800290968458166?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/116800290968458166/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=116800290968458166' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116800290968458166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116800290968458166'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2007/01/ajax-aspects-is-now-available-under.html' title='AJAX Aspects is now available under the BSD license'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-116560486815164264</id><published>2006-12-08T20:07:00.000+01:00</published><updated>2007-06-10T16:59:34.255+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Building JavaScript Behaviors</title><content type='html'>&lt;p&gt;During the last months I got some good feedback from readers and friends that point me to some missing topics in my AJAX book. I will continue to publish new content here before bringing a new version of the book.&lt;/p&gt;&lt;p&gt;This is a step by step instruction for building a new ASP.NET Control with a rich client side functionality by using JavaScript and a Behavior mechanism.&lt;/p&gt;&lt;p&gt;The sample functionality I use to show this is a simple dice (German: Würfel). It's a sample that I also used in my session at the "AJAX in Action" Conference in Germany some weeks ago.&lt;/p&gt;&lt;p&gt;You can download all files from &lt;a title="JSBTutorial zip file" href="http://www.mathertel.de/Downloads/Start_JSBTutorial.aspx"&gt;http://www.mathertel.de/Downloads/Start_JSBTutorial.aspx&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;1. Coding it all in one place&lt;/h3&gt;&lt;p&gt;The best place for writing a new control is inside a single HTML file that contains all the fragments that you will separate later into different locations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;a HTML object structure that will be used for rendering the new control. This should be a single outer element that may contain complex inner HTML elements. Give it  a unique id that can be used to identify the first prototype. &lt;li&gt;a CSS section inside the &amp;lt;head&amp;gt; element that will hold all the style rules that we will later move out into the common css file. You can code all the css rules into the html elements first if you like. Later you should not include any CSS code inside the rendered html elements mo make some personalization and style adoption easier. &lt;li&gt;a &amp;lt;script type="text/javascript"&amp;gt; element that will contain the JavaScript behavior definition using a object notation in the JSON coding style and the statement for binding the JavaScript behavior object to the HTML element. &lt;li&gt;include the common behavior loading mechanism &amp;lt;script type="&lt;span style="color:#8b0000;"&gt;text/javascript&lt;/span&gt;" src="&lt;span style="color:#8b0000;"&gt;../controls/jcl.js&lt;/span&gt;"&amp;gt;&amp;lt;/script&amp;gt; in the &amp;lt;head&amp;gt; element. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The advantage of using this intermediate development state is that you can hit F5 in the browser and can be sure that all your code will reload as expected. You also will not have any timing problems that may happen when JavaScript or CSS files are cached locally. You need no server side functionality so a *.htm file is fine for now.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN"&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;html&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;xmlns&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;

&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;head&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;title&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Ein Wuerfel&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;title&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"text/javascript"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;src&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"jcl.js"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;

  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;style&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"text/css"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    .Wuerfel {
      border: solid 2px green; width:40px; height:40px; overflow:hidden;
      cursor: pointer; background-color:#EEFFEE;
      font-size: 30px; padding:20px; text-align: center;
    }
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;

  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    var WuerfelBehaviour = {
      onclick: function(evt) {
        Wuerfel1.innerText = Math.floor(Math.random()*6)+1;
      }
    } // WuerfelBehaviour
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;head&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;

&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;body&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"Wuerfel1"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"Wuerfel"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;unselectable&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"on"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;click&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
 
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;defer&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"defer"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    jcl.LoadBehaviour("Wuerfel1", WuerfelBehaviour);
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;body&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;html&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The file &lt;a title="dice sample step 1" href="http://www.mathertel.de/AJAXEngine/S05_JSB/Wuerfel_01.aspx"&gt;wuerfel_01.htm&lt;/a&gt; contains an implementation in this state. &lt;/p&gt;
&lt;h3&gt;2. replacing all hard-coded references&lt;/h3&gt;
&lt;p&gt;If you want to make it possible to use the same control multiple times on the same page then you must avoid using hard coded ids or names. The only place where you should find the id of the outer HTML element is inside the first parameter of the jcl.LoadBehaviour function call.&lt;/p&gt;
&lt;p&gt;All the other references should be replaced by using the "this" reference.&lt;/p&gt;
&lt;p&gt;The other thing you should take care too are the parameters / attributes that you want to use together with the new control. You should define the as attributes in the outer HTML element and as properties of the JavaScript behavior definition. There should not be any constants inside the JSON object.&lt;/p&gt;
&lt;p&gt;If everything is well done you can make a second copy of the outer HTML element with a new id and can bind the same behavior definition to it. Both elements should now work as expected independently. Check also if the parameters work as expected.&lt;/p&gt;
&lt;p&gt;The file &lt;a title="dice sample step 2" href="http://www.mathertel.de/AJAXEngine/S05_JSB/Wuerfel_02.aspx"&gt;wuerfel_02.htm&lt;/a&gt; contains an implementation in this state.&lt;/p&gt;
&lt;h3&gt;3. separating the behavior code&lt;/h3&gt;
&lt;p&gt;The next step is to extract the core of the behavior into a new *.js file and reference this file by using a new &amp;lt;script type="&lt;span style="color:#8b0000;"&gt;text/javascript&lt;/span&gt;" src="&lt;span style="color:#8b0000;"&gt;wuerfel.js&lt;/span&gt;"&amp;gt;&amp;lt;/script&amp;gt; in the &amp;lt;head&amp;gt; element.&lt;/p&gt;
&lt;p&gt;The advantage of a separate file for the behavior definition is that the implementation can be cached by the browser independently from the individual use and If the control is reused in different pages you can see dramatic performance improvements.&lt;/p&gt;
&lt;p&gt;The file &lt;a title="dice sample step 3" href="http://www.mathertel.de/AJAXEngine/S05_JSB/Wuerfel_03.aspx"&gt;wuerfel_03.htm&lt;/a&gt; and &lt;a title="dice javascript behavior script file" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/S05_JSB/wuerfel.js"&gt;wuerfel.js&lt;/a&gt; file contain an implementation in this state and wuerfel.js ??? has also got some more functionality.&lt;/p&gt;
&lt;h3&gt;4. separating the CSS style definitions&lt;/h3&gt;
&lt;p&gt;The style of the new control should not be coded inline into the html code but should be separated into some css statements. So I use a classname for the top element of the control by using the name of the behavior. If you have special inner elements they can be prefixed by the same name or you might use css selectors by specifying the outer and inner class names. Sample:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;.&lt;span style="color:#800000;"&gt;TreeView&lt;/span&gt; .&lt;span style="color:#800000;"&gt;do&lt;/span&gt; {&lt;span style="color:#ff0000;"&gt; ... &lt;/span&gt;}
&lt;span style="color:#800000;"&gt;div&lt;/span&gt;.&lt;span style="color:#800000;"&gt;TreeView&lt;/span&gt; .&lt;span style="color:#800000;"&gt;dc&lt;/span&gt; {&lt;span style="color:#ff0000;"&gt; ... &lt;/span&gt;}&lt;/pre&gt;
&lt;p&gt;Because the css statements are usually much smaller then the JavaScript code for a control I do not extract the css statements into separate files but include them all in a single css file for all the controls I've done. The *.css files are cached by the browser so loading them from the server doesn't occur too often.&lt;/p&gt;
&lt;h3&gt;5. converting to a ASP.NET User Control (*.ascx)&lt;/h3&gt;
&lt;p&gt;Now it's time to switch from a *.htm file to a *.aspx file because you will need some server side functionality now.&lt;/p&gt;
&lt;p&gt;Rename the file and add a &amp;lt;%@ Page Language="C#" %&amp;gt; statement at the top of the page. In Visual Studio you will have to close the file and reopen it to get the full editor support for the right server side languages.&lt;/p&gt;
&lt;p&gt;The html code and the javascript statement that binds the JavaScript Behavior of the new control is copied into the new User Control file &lt;a title="dice ASP.NET user control" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/S05_JSB/wuerfel.ascx"&gt;wuerfel.ascx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The id attribute that is rendered for the client should not be hardcoded to a static value. The UniqueID can be used and will produce the given id if one is specified in the *.aspx page. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"&amp;lt;%=this.ClientID
    %&amp;gt;"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"Wuerfel"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;unselectable&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"on"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;click&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;defer&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"defer"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  jcl.LoadBehaviour("&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%=this.ClientID %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;", WuerfelBehaviour);
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;script&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now it is easy to include the new control into the page by dragging the wuerfel.ascx file into a blank page while using the Design mode. The code will look like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;uc1&lt;/span&gt;:&lt;span style="color:#ff0000;"&gt;Wuerfel&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;ID&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"Wuerfel1"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;runat&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;"server"&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;and a reference to the used control will also be generated:&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;%@ Register Src="Wuerfel.ascx" TagName="Wuerfel" TagPrefix="uc1" %&amp;gt;&lt;/pre&gt;
&lt;p&gt;Open this file by using the browser and have a look to the source code that is delivered to the client - it will look very similar to what you had before. Again you can check whether everything is fine by pasting the &amp;lt;uc1:Wuerfel...&amp;gt; element several times. Visual Studio will automatically generate different ids so all elements work independent.&lt;/p&gt;
&lt;h3&gt;6. using the script including mechanism&lt;/h3&gt;
&lt;p&gt;You still have to take care of including the right JavaScript include in the &amp;lt;head&amp;gt; of your page. Now we also get this work done automatically. The advantage is that you do not have to take care of using the right include files and you will never forget to remove them when a control is removed from the page.&lt;/p&gt;
&lt;p&gt;In the *.aspx page the &amp;lt;head&amp;gt; element must be marked with runat="server"&lt;/p&gt;
&lt;p&gt;In the *.ascx file some server side programming is needed inside a &amp;lt;script runat="server"&amp;gt; tag:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnPreRender(EventArgs e) {
  &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.OnPreRender(e);

  &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (Page.Header == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
    &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Exception("&lt;span style="color:#8b0000;"&gt;The &amp;lt;head&amp;gt; element of this page is not marked with
      runat='server'.&lt;/span&gt;");

  &lt;span style="color:#008000;"&gt;// register the JavaScripts includes without need for
    a Form.&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!Page.ClientScript.IsClientScriptBlockRegistered(Page.GetType(), "&lt;span style="color:#8b0000;"&gt;CommonBehaviour&lt;/span&gt;")) {
    Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "&lt;span style="color:#8b0000;"&gt;CommonBehaviour&lt;/span&gt;", String.Empty);
    ((HtmlHead)Page.Header).Controls.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; LiteralControl("&lt;span style="color:#8b0000;"&gt;&amp;lt;script type='text/javascript' src='&lt;/span&gt;"
      + Page.ResolveUrl("&lt;span style="color:#8b0000;"&gt;jcl.js&lt;/span&gt;")
      + "&lt;span style="color:#8b0000;"&gt;'&amp;gt;&amp;lt;&lt;/span&gt;" + "&lt;span style="color:#8b0000;"&gt;/script&amp;gt;\n&lt;/span&gt;"));
  } &lt;span style="color:#008000;"&gt;// if&lt;/span&gt;

  &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!Page.ClientScript.IsClientScriptBlockRegistered(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetType(), "&lt;span style="color:#8b0000;"&gt;MyBehaviour&lt;/span&gt;")) {
    Page.ClientScript.RegisterClientScriptBlock(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetType(), "&lt;span style="color:#8b0000;"&gt;MyBehaviour&lt;/span&gt;", String.Empty);
    ((HtmlHead)Page.Header).Controls.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; LiteralControl("&lt;span style="color:#8b0000;"&gt;&amp;lt;script type='text/javascript' src='&lt;/span&gt;"
      + Page.ResolveUrl("&lt;span style="color:#8b0000;"&gt;Wuerfel.js&lt;/span&gt;")
      + "&lt;span style="color:#8b0000;"&gt;'&amp;gt;&amp;lt;&lt;/span&gt;" + "&lt;span style="color:#8b0000;"&gt;/script&amp;gt;\n&lt;/span&gt;"));
  } &lt;span style="color:#008000;"&gt;// if&lt;/span&gt;
} &lt;span style="color:#008000;"&gt;// OnPreRender&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Have a look at the files &lt;a href="http://www.mathertel.de/AJAXEngine/S05_JSB/Wuerfel_04.aspx"&gt;wuerfel_04.aspx&lt;/a&gt; and &lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/S05_JSB/wuerfel.ascx"&gt;wuerfel.ascx&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;7. using a global registration for the control&lt;/h3&gt;
&lt;p&gt;When dragging a User Control onto a page the UserControl is registered for this page by using a server site Register tag. &lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;%@ Register Src="Wuerfel.ascx" TagName="Wuerfel" TagPrefix="uc1" %&amp;gt;&lt;/pre&gt;
&lt;p&gt;There is no real problem with that automatic stuff but if you copy HTML code around from one page to another you always have to take care of copying these Register tags as well.&lt;/p&gt;
&lt;p&gt;Fortunately there is another solution that registers User Contols globally in the web.config file and needs no Register tags.&lt;/p&gt;
&lt;p&gt;Open the web.config file you can find in the root of your web application and locate the &amp;lt;configuration&amp;gt;&amp;lt;system.web&amp;gt;&amp;lt;pages&amp;gt;&amp;lt;controls&amp;gt; region. Here you can add a add element:&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;add src="~/controls/LightBox.ascx" tagName="LightBox" tagPrefix="ve"/&amp;gt;&lt;/pre&gt;
&lt;p&gt;You can find many samples in the web.config file of the AJAXEngine demo web site project and there is a good post on this topic in Scott Guthrie's blog too at: &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/11/26/tip-trick-how-to-register-user-controls-and-custom-controls-in-web-config.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2006/11/26/tip-trick-how-to-register-user-controls-and-custom-controls-in-web-config.aspx&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;8. converting to a ASP.NET Web Control (*.cs) implementation&lt;/h3&gt;
&lt;p&gt;When writing simple controls without nested other controls there is no need to convert a UserControl into a WebControl. You need this step only when the control will be used as a wrapper to more HTML code that is declared on the web page and not within the control itself. If you download the complete source code of the AJAX Engine project you can find some advanced implementations using ASP.NET Web Controls in the APP_Code folder. Writing WebControls and designers for Web Controls is not covered here.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-116560486815164264?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/116560486815164264/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=116560486815164264' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116560486815164264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116560486815164264'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/12/building-javascript-behaviors.html' title='Building JavaScript Behaviors'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-116396102388080571</id><published>2006-11-19T19:30:00.000+01:00</published><updated>2007-06-10T17:01:10.648+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>Update on the JavaScript client for SOAP based WebServices</title><content type='html'>&lt;p&gt;A core element of the AJAX Engine is a JavaScript based SOAP client that is used by the browser to call methods on the server implmented by regular webservices. &lt;/p&gt;&lt;p&gt;Up to now only document encoding was supported by the WSDL to JavaScript transformation implemented by wsdl.xslt.
I prefer using the document-literal encoding style but while working with some older JAVA implementations I decided to implement the RPC model too.&lt;/p&gt;&lt;p&gt;The only file that I needed to change is the wsdl.xslt file that you can download at &lt;a title="http://www.mathertel.de/AJAXEngine/ajaxcore/wsdl.xslt" href="http://www.mathertel.de/AJAXEngine/ajaxcore/wsdl.xslt"&gt;http://www.mathertel.de/AJAXEngine/ajaxcore/wsdl.xslt&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The documentation of the SOAP client and the proxy generator can be found in the book at &lt;a title="AJAX book" href="http://www.mathertel.de/Ajax/AJAXeBook.aspx"&gt;http://www.mathertel.de/Ajax/AJAXeBook.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It's also integrated into the new downloads. &lt;/p&gt;&lt;p&gt;Read about the SOAP Basic Profile at &lt;a href="http://www.ws-i.org/Profiles/BasicProfile-1.1.html"&gt;http://www.ws-i.org/Profiles/BasicProfile-1.1.html&lt;/a&gt; &lt;p&gt;Read some arguments against the SOAP encoding at &lt;a title="http://msdn.microsoft.com/library/en-us/dnsoap/html/argsoape.asp" href="http://msdn.microsoft.com/library/en-us/dnsoap/html/argsoape.asp"&gt;http://msdn.microsoft.com/library/en-us/dnsoap/html/argsoape.asp&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-116396102388080571?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/116396102388080571/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=116396102388080571' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116396102388080571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116396102388080571'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/11/update-on-javascript-client-for-soap.html' title='Update on the JavaScript client for SOAP based WebServices'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-116007667083693136</id><published>2006-10-05T21:31:00.000+02:00</published><updated>2006-10-05T21:31:11.043+02:00</updated><title type='text'>Searching the AJAXEngine Code</title><content type='html'>&lt;p&gt;Google released a new search tool named codesearch specially for coders. They support also Zip files that contain code and you can find the sources for the Ajax engine by using the link:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.google.com/codesearch?hl=en&amp;amp;lr=&amp;amp;q=ajaxengine+mathertel" href="http://www.google.com/codesearch?hl=en&amp;amp;lr=&amp;amp;q=ajaxengine+mathertel"&gt;http://www.google.com/codesearch?hl=en&amp;amp;lr=&amp;amp;q=ajaxengine+mathertel&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When you open on of the *.js files you also have a navigation through the zip file. on the top there is the path to the current opened folder and on the left side you can see al the files within that folder.&lt;/p&gt; &lt;p&gt;Nice feature !&lt;/p&gt; &lt;p&gt;Google caches the zip file so be sure to get the actual zip file from &lt;a href="http://www.mathertel.de/AJAXEngine"&gt;http://www.mathertel.de/AJAXEngine&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-116007667083693136?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/116007667083693136/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=116007667083693136' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116007667083693136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/116007667083693136'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/10/searching-ajaxengine-code.html' title='Searching the AJAXEngine Code'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-115843808589994582</id><published>2006-09-16T22:21:00.000+02:00</published><updated>2007-06-10T17:04:22.356+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Help on this - Scope in JavaScript</title><content type='html'>&lt;p&gt;I really do not often link up to other postings on the web but in &lt;span style="FONT-WEIGHT: bold;color:#003399;" &gt;this&lt;/span&gt; case I have to!&lt;/p&gt;&lt;p&gt;Thanks to Mike West and his article "Scope in JavaScript" published at &lt;a href="http://digital-web.com/articles/scope_in_javascript/"&gt;http://digital-web.com/articles/scope_in_javascript/&lt;/a&gt;.&lt;/p&gt;I really like this article and I learned from it. It's the same story all the time: When you understand, things get easier and seems to be simpler. &lt;p&gt;If you've read my book you have noticed that I fell over the context problem when attaching JavaScript function to events. The solution I suggested was to implement a inner method that gets a usable context and there are some tricks implemented to find the right context by analyzing the target of the event.&lt;/p&gt;&lt;p&gt;Now, with the bind function I can reduce this overhead and we have right context right from the start.&lt;/p&gt;&lt;h3&gt;It's not as easy as it seems&lt;/h3&gt;&lt;p&gt;My first idea was to include the bind functionality into jcl.AttachEvent the cross browser compatible helper around attachEvent() or addEventListener() to register events but I had a lot of problems until I found that the DetachEvent is not working any more as expected.&lt;/p&gt;&lt;p&gt;The problem is that when using the bind() function you get a reference to a new, not the original passed function.  Because you have no reference to this new function you can not use it when calling jcl.DetachEvent. If you want to detach the handler from the event you have to pass the same reference. Calling obj.detachEvent("onclick", handler.bind(obj)) will never work as expected.&lt;/p&gt;&lt;h3&gt;... but don't give up&lt;/h3&gt;&lt;p&gt;After some analyzing I found that most of the events are using functions that never get detached. The "on___" functions of the behavior object are automatically attached to the corresponding events but will never get detached until the page gets reloaded. These functions are now executed in the context of the bound object and it gets really access other members of the behavior.&lt;/p&gt;&lt;p&gt;The other situations that benefits a lot from the .bind function is when registering a timer event. Here a detach will never happen because the timer event gets canceled by using clearTimeout and you have to pass the timer, not the function reference. In many cases we need to call a method of a specific element like:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._scrollTimer = &lt;span style="color:#0000ff;"&gt;window&lt;/span&gt;.&lt;span style="color:#0000ff;"&gt;setTimeout&lt;/span&gt;("&lt;span style="color:#8b0000;"&gt;document.getElementById('&lt;/span&gt;"
  + &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.id + "&lt;span style="color:#8b0000;"&gt;').scrollend()&lt;/span&gt;", 100);&lt;/pre&gt;
&lt;p&gt;By using the bind function it looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._scrollTimer = &lt;span style="color:#0000ff;"&gt;window&lt;/span&gt;.&lt;span style="color:#0000ff;"&gt;setTimeout&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.scrollend.bind(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;), 100);&lt;/pre&gt;
&lt;p&gt;The other advantage you can see here is that a function reference can be passed to setTimeout which is faster than a string that gets evaluated.&lt;/p&gt;
&lt;h3&gt;New version is online&lt;/h3&gt;
&lt;p&gt;The web site was updated to this new version including a lot of new visual controls and some housekeeping bug fixes. - Get a copy from &lt;a href="http://www.mathertel.de/Downloads/Start_AJAX.aspx"&gt;http://www.mathertel.de/Downloads/Start_AJAX.aspx&lt;/a&gt; or from the download area.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-115843808589994582?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/115843808589994582/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=115843808589994582' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115843808589994582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115843808589994582'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/09/help-on-this-scope-in-javascript.html' title='Help on this - Scope in JavaScript'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-115609613045115935</id><published>2006-08-20T19:48:00.000+02:00</published><updated>2007-06-10T17:05:34.267+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>The Lightbox Visual effect</title><content type='html'>&lt;p&gt;The Lightbox is another visual effect that uses the semi transparent feature available in the modern browsers.&lt;/p&gt;
&lt;p&gt;Here is is used to simulate another layer of user interaction by hiding the existing elements of the page and bringing up new elements in front of them.&lt;/p&gt;&lt;h3&gt;modal user interaction&lt;/h3&gt;&lt;p&gt;This effect was found to be useful for implementing modal windows or modal dialogs.&lt;/p&gt;&lt;p&gt;Modal user interaction is very helpful when implementing some functionality that sometimes needs to ask the user in the middle of the implementation without breaking the usual program flow.&lt;/p&gt;&lt;p&gt;I'm sure that you are using this feature as well by using the alert() or prompt() methods. The JavaScript interpreter will stop executing until the opened window is closed by the user by choosing one of the available options.&lt;/p&gt;&lt;p&gt;There have been some discussions in the past whether modal user interactions are good or bad and especially in the apple era modal windows and dialogs where found to restrict the user's freedom. &lt;/p&gt;&lt;p&gt;Now with HTML pages true modal dialogs cannot be implemented any more. The Microsoft Internet Explorer offers a showModalDialog method that allows opening true modal windows. There are some tricks necessary to use this feature with dynamic build content, see &lt;a href="http://weblogs.asp.net/datagridgirl/archive/2005/08/11/422309.aspx"&gt;http://weblogs.asp.net/datagridgirl/archive/2005/08/11/422309.aspx&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The Mozilla/Firefox offers a similar feature by using a special parameter in window.open, but you need some special privileges that are not available on the Internet to make it work.&lt;/p&gt;&lt;p&gt;Anyway it is all non-standard. &lt;/p&gt;&lt;h3&gt;Lightbox implementations &lt;/h3&gt;&lt;p&gt;You can find some implementations on the web: &lt;p&gt;&lt;a href="http://www.blakems.com/archives/000075.html"&gt;http://www.blakems.com/archives/000075.html&lt;/a&gt;
&lt;a href="http://www.huddletogether.com/projects/lightbox/"&gt;http://www.huddletogether.com/projects/lightbox/&lt;/a&gt;
&lt;a href="http://particletree.com/features/lightbox-gone-wild/"&gt;http://particletree.com/features/lightbox-gone-wild/&lt;/a&gt; &lt;p&gt;or just search the word "lightbox". &lt;/p&gt;&lt;p&gt;I implemented a ASP.NET User Control together with a client side JavaScript Behavior that implements the lightbox effect that can be used with embedded dialog elements.&lt;/p&gt;&lt;p&gt;The implementation has a extensibility model implemented so you can effectively show any kind of resource that is available. Pictures for example normally have no buttons or links but you need some elements in your dialog to close the dialog, show the next element or ... &lt;/p&gt;&lt;p&gt;All you need to use this visual effect is to include the lightbox user control:&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;ve:LightBox ID="LightBox1" runat="server" /&amp;gt;&lt;/pre&gt;
&lt;p&gt;There can only be one lightbox element on a page. The methods coming with the behavior are all usable by calling them directly on the LightBoxBehavior.&lt;/p&gt;
&lt;p&gt;Elements that should be displayed on top of the page can be implemented very easily using a simple div-element with a given width and height:&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;div id="HelloWorld" style="display:none;width:180px;height:140px"&amp;gt;
  &amp;lt;p&amp;gt;Hello world.&amp;lt;/p&amp;gt;
  &amp;lt;button onclick="LightBoxBehavior.hide()"&amp;gt;close&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;p&gt;It's a good idea to add some more style attributes to the outer &amp;lt;div&amp;gt; element to make it more look like a small dialog:&lt;/p&gt;&lt;pre class="code"&gt;style="background-color:white;border: solid 2px #203050; padding: 2px;"&lt;/pre&gt;
&lt;h3&gt;A small Image Slide Show&lt;/h3&gt;
&lt;p&gt;I've also implemented a more complex sample, a Image Slide Show. You can find the
code in the implementation of this page by using the "View Source" link in the upper
right corner of the page.&lt;/p&gt;
&lt;p&gt;It is also implemented by using a JavScript Behavior and handles some keys by attaching to the
keydown event.&lt;/p&gt;
&lt;p&gt;See it in action at: &lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/LightBoxDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/LightBoxDemo.aspx&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-115609613045115935?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/115609613045115935/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=115609613045115935' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115609613045115935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115609613045115935'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/08/lightbox-visual-effect.html' title='The Lightbox Visual effect'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-115295874070356674</id><published>2006-07-15T12:01:00.000+02:00</published><updated>2006-07-15T12:23:25.506+02:00</updated><title type='text'>AJAX Konferenz</title><content type='html'>&lt;a href="http://www.ajax-in-action.de"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/7662/473/320/AJAX-in-Action.gif" border="0" alt="AJAX in action Konferenz" /&gt;&lt;/a&gt;

&lt;p&gt;"&lt;i&gt;--&amp;gt; Mit AJAX bahnt sich eine Revolution im Internet an&lt;/i&gt;" ist der Opener der &lt;a href="http://www.ajax-in-action.de"&gt;AJAX in action Konferenz vom 27. - 28. September bei Frankfurt&lt;/a&gt; - zu recht wie ich meine.&lt;/p&gt;
&lt;p&gt;Es sind viele interessante Speaker und Themen dabei. Besonders interessant ist, dass viele Plattformen vorgestellt werden und letztendlich treffen sich alle wieder im Browser mit JavaScript und XMLHttpRequest Objekten.&lt;/p&gt;
&lt;h3&gt;Was AJAX-Entwickler über Web Services wissen sollten&lt;/h3&gt;
&lt;p&gt;Mein Vortrag beschäftigt sich mit WebServices und den Protokollen die in AJAX Applikationen verwendet werden. Wer mein Blog liest (insbesondere die Beiträge im letzten Jahr rund um SOAP im &lt;a href="http://ajaxaspects.blogspot.com/2005_06_01_ajaxaspects_archive.html"&gt;Juni&lt;/a&gt; und &lt;a href="http://ajaxaspects.blogspot.com/2005_07_01_ajaxaspects_archive.html"&gt;Juli&lt;/a&gt;
kennt meine persönliche Vorliebe für Standard-Protokolle. Es gibt aber noch mehr aus diesem Bereich und im letzten Jahr hat sich auch einiges getan.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-115295874070356674?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/115295874070356674/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=115295874070356674' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115295874070356674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115295874070356674'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/07/ajax-konferenz.html' title='AJAX Konferenz'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-115212766412438851</id><published>2006-07-05T21:27:00.000+02:00</published><updated>2007-06-10T17:06:00.856+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>AJAX Book now available as PDF download</title><content type='html'>&lt;p&gt;As requested by some people the book "Aspects of AJAX" is now available in PDF format so you can easily take it with you. I will update it from time to time when new text on theis Blog or samples on my website are written. So come back and check for new versions.&lt;/p&gt;

&lt;p&gt;&amp;gt;&amp;gt; &lt;a href="http://www.mathertel.de/Ajax/AJAXeBook.aspx" rel="index,follow"&gt;AJAX book download&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's written in English so it can reach most IT people. My native language is not English so please excuse my typos or just let me know about.&lt;/p&gt;

&lt;p style="DISPLAY: none"&gt;&lt;a href="http://www.mathertel.de/Ajax/AspectsOfAJAX0607.pdf" rel="index,follow"&gt;AJAX Book PDF&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-115212766412438851?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/115212766412438851/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=115212766412438851' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115212766412438851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115212766412438851'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/07/ajax-book-now-available-as-pdf.html' title='AJAX Book now available as PDF download'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-115047891588022024</id><published>2006-06-16T19:15:00.000+02:00</published><updated>2007-06-10T17:06:39.083+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Building a AJAX enabled popup control</title><content type='html'>&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/AJAXPopUpDemo.PNG"&gt;&lt;img style="WIDTH: 320px; CURSOR: hand" alt="" src="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/AJAXPopUpDemo.PNG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When fetching the extra information costs a lot of resources (cpu, memory
or time) on the server or is more than just a few words it is better to not include
it into the page all the time but get it from the server when the user requests
for it. This scenario is perfect for using the AJAX technology.&lt;/p&gt;

&lt;h3&gt;Using the AJAX engine&lt;/h3&gt;
&lt;p&gt;To get the information from the server we need a web service with one method that
gets a key string as parameter and returns the popup information. We can trust this
method so far that we can rely that it is returning valid html code.&lt;/p&gt;
&lt;p&gt;The timer object that we need to delay the popup a little bit can be completely
replaced by using the delay option of the AJAX engine.&lt;/p&gt;
&lt;p&gt;The &lt;i&gt;onmouseover&lt;/i&gt; event code only needs to start the AJAX engine after checking
for a valid html object.&lt;/p&gt;
&lt;pre class="code"&gt;ajax.Start(AJAXPopUpBehaviour.action, obj);&lt;/pre&gt;
&lt;p&gt;The action that describes the AJAX mechanism for the popUp keeps all the elements
of the asynchronous execution together. It prepares the server call be fetching
the url of the hyperlink, calls the GetDetails method on the server and then finishes
the action by showing the popUp control.&lt;/p&gt;
&lt;pre class="code"&gt;action: {
  delay: 300,
  queueMultiple: false,
  prepare: function(obj) { return (obj.href); },
  call: "proxies.ServerInfo.GetDetails",
  finish: "AJAXPopUpBehaviour.show",
  onException: proxies.alertException
}&lt;/pre&gt;
&lt;h3&gt;Using a Web Control&lt;/h3&gt;
&lt;p&gt;But it still can be easier by using a web control:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;ajax:PopUp runat="server" id="ajaxpopup1" infomethod="proxies.ServerInfo.GetDetails" /&amp;gt;&lt;/pre&gt;
&lt;p&gt;The method that returns the information to the client is made availale to the client by including
the WebService and creating a JavaScript proxy:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;script type="text/javascript"
  src="../ajaxcore/GetJavaScriptProxy.aspx?service=../S03_AJAXControls/ServerInfo.asmx"&amp;gt;
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;h3&gt;Implementing the sample web control&lt;/h3&gt;
&lt;p&gt;On the client a JavaScript Behavior
is used that is included into the page by the web control
that is executed on the server. Read more and see the sample live at: &lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/AJAXPopUpDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/AJAXPopUpDemo.aspx&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-115047891588022024?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/115047891588022024/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=115047891588022024' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115047891588022024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/115047891588022024'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/06/building-ajax-enabled-popup-control.html' title='Building a AJAX enabled popup control'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114943931882757895</id><published>2006-06-04T18:36:00.000+02:00</published><updated>2007-06-10T17:07:10.218+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>An ASP.NET popup web contol</title><content type='html'>&lt;p&gt;I just added a new control to the library that displays a popup on the page
that can be used to show additional information on a specific topic or item.&lt;/p&gt;
&lt;img src="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/PopUpDemo.PNG" /&gt;
&lt;p&gt;A detailed description and the source can be found on my web site.
Have a look at &lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/PopUpDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/PopUpDemo.aspx&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114943931882757895?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114943931882757895/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114943931882757895' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114943931882757895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114943931882757895'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/06/aspnet-popup-web-contol.html' title='An ASP.NET popup web contol'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114902292707401483</id><published>2006-05-30T22:43:00.000+02:00</published><updated>2006-05-30T23:02:07.110+02:00</updated><title type='text'>Visual Studio .NET add-in updated</title><content type='html'>&lt;p&gt;One of my older projects where updated today.&lt;/p&gt;
&lt;p&gt;I missed some commands so I started developing a collection of useful tools that help developing and controlling my work and files. The result was an add-in for Visual Studio that adds commands for comparing files and folders, an explore command, and some useful reports for web projects.&lt;/p&gt;
&lt;p&gt;Give it a try at: &lt;a href="http://www.codeproject.com/csharp/WebReports8.asp"&gt;http://www.codeproject.com/csharp/WebReports8.asp&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114902292707401483?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114902292707401483/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114902292707401483' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114902292707401483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114902292707401483'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/05/visual-studio-net-add-in-updated.html' title='Visual Studio .NET add-in updated'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114883645917897160</id><published>2006-05-28T18:54:00.000+02:00</published><updated>2007-06-10T17:11:39.567+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Back Button Problem'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Update to the back-button and history implementation</title><content type='html'>&lt;p&gt;The last past was about implementing a back-button and local history support to the AJAX Engine.&lt;/p&gt;
&lt;p&gt;I've added 2 attributes to the PropHistory web control that can be declared to avoid some scripting on the page:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;ajax:PropHistory runat="server" stateList="version,book,chapter" propList="vers" /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;i&gt;stateList&lt;/i&gt; specifies the page properties that together form the current state of the page. A change to the value of any of these properties will cause a 
new entry in the history of the browser.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;propList&lt;/i&gt; specifies the page properties that are persisted in the hash part of the url so that hyperlinks will work.&lt;/p&gt;
&lt;p&gt;The implementation takes care of the fact that all properties in the statList must also be part of the url but you don't have to specify them again in the propList attribute.&lt;/p&gt;

&lt;p&gt;The download files where updated today too.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/Downloads/Start_AJAX.aspx"&gt;Ajax.zip&lt;/a&gt;
contains the ASP.NET 2.0 web project that builds the side. The complete AJAX Engine and all samples are included. Use this project when you want to start building your AJAX web application.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/Downloads/Start_AJAXEngine.aspx"&gt;AJAXEngine.zip&lt;/a&gt;
This Zip-File contains the core files of the AJAX engine and the AJAX controls. You can use this if you want to update your project with the updated core files.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114883645917897160?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114883645917897160/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114883645917897160' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114883645917897160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114883645917897160'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/05/update-to-back-button-and-history.html' title='Update to the back-button and history implementation'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114746692296481932</id><published>2006-05-12T22:47:00.000+02:00</published><updated>2007-06-10T17:11:14.591+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Back Button Problem'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Another view to the Back Button Problem of AJAX applications</title><content type='html'>&lt;p&gt;A lot of people already wrote about this topic. Search &lt;a href="http://www.live.com/#q=AJAX%20%22BACK%20BUTTON%20PROBLEM%22"&gt;
"AJAX BACK BUTTON PROBLEM"&lt;/a&gt; on a search portal and you can find a lot of stuff about it!&lt;/p&gt;
&lt;p&gt;But there are still aspects that haven't been talked about.&lt;/p&gt;
&lt;p&gt;Let me explain that the problem is old, well known, not an AJAX specific problem and after all: technically solved.&lt;/p&gt;
&lt;h3&gt;What the back button does - and why not&lt;/h3&gt;
&lt;p&gt;Still some people think that the web is a mass of pages pointing to each other using hyperlinks. While
navigating along these hyperlinks every visited page is recorded into a local list often called "history".
The original idea was to support this list of pages with some functionality.&lt;/p&gt;
&lt;p&gt;When framesets came into the browser model this simple idea got the first scratch because when you
use hyperlinks that change only the content of a frame the url doesn't change. The url that you can
see in the address is not the only information you need to restore a browser situation.&lt;/p&gt;
&lt;p&gt;Up to here the back button still works in the browsers, because they also record this extra information
together with the url - at least when working with the browser history functionality.&lt;/p&gt;
&lt;p&gt;Then there are web servers that found a (not so) wonderful trick to use forms for navigating from one
page to another and things get complicated. Hyperlinks can be used to submit the content of a form (including
the current browser state) back to the server which then returns the next or the modified page. A problem
on this approach is that the same url (main.do, main.aspx, main.jspx, main.php, ...) can be reused for
the whole application.&lt;/p&gt;
&lt;p&gt;Here the back button also has to record all the data that was posted to the server so it can be re-posted
when the user wants to go one or more pages back.&lt;/p&gt;
&lt;p&gt;This kind of request cannot in generally be distinguished by the server from clicking the same button
of a form twice and often there are filters available on the server to redirect these requests to another
page.&lt;/p&gt;
&lt;p&gt;And this is why navigating back using the back button of the browser often doesn't work.&lt;/p&gt;
&lt;p&gt;And this is why many applications start a new window at the beginning without displaying the navigation
bar that includes the back button.&lt;/p&gt;
&lt;p&gt;And this is why many users like the back button on the mouse or keyboard (ALT-LEFT).&lt;/p&gt;
&lt;p&gt;And this is why the web doesn't work like this (too often).&lt;/p&gt;
&lt;h3&gt;The favorite problem&lt;/h3&gt;
&lt;p&gt;As with the history list a very similar problem exists with the favorites and with web urls stored
in files. When you save a current page to your favorites list you might think that this helps you coming
back to this page but if the server needs post information or the page is built using frames you might
become disappointed because this kind of information is not stored in hyperlinks.&lt;/p&gt;
&lt;p&gt;The IE implements a special *.url file type that is created when using the IE built in "Add to favorites..."
command that contains extra information about the current urls of the frames and maybe more.&lt;/p&gt;
&lt;p&gt;But the *.lnk file type that is created when dragging an URL from the IE address bar to the desktop
as well as the url file that is created by Mozilla/Firefox doesn't hold this information.&lt;/p&gt;
&lt;h3&gt;What's the problem?&lt;/h3&gt;
&lt;p&gt;The problem with the back button existed long before AJAX applications became widely known. The core
of the problem is about building a web application that works by using meaningful urls whether using
frames or not and enabling the usage of the history and favorites feature of the existing browsers.&lt;/p&gt;
&lt;p&gt;AJAX applications do have the same problem like those applications doing everything through a single
url: it's meaningless and you cannot rely on any posted information because it just doesn't exist.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;So what we all have to do is giving our applications meaningful urls.&lt;/b&gt;&lt;/p&gt;
&lt;h3&gt;Meaningful urls&lt;/h3&gt;
&lt;p&gt;Not every click should change the url and in many applications there is no clear "back" situation.
If you browse your mail inbox for example a click to open a message may be a clear "navigate to" situation.
When you delete the message by using a click on a button the main UI might navigate for you to the next
message in the list. But where is the "back" position now - on the deleted mail?&lt;/p&gt;
&lt;p&gt;
You can also argue that moving on to the next mail is neither forward nor back but something like up
and down and back will always bring you back to the list view you started.
&lt;p&gt;So what I want to say is that the (forward and) back direction is often very application or problem
specific. With AJAX you have the chance to model these situations the way you like and the way that
is the best for your application and you are not bound to the GET and POST requests done by hyperlinks
and forms.&lt;/p&gt;
&lt;p&gt;I use the url as a textual key to the global addressable state of an Ajax application. By moving some
information into the url and reading this information out of the url when a page loads or the urls changes,
there is a clear interface between the Ajax page and the external world that can be used for storing
browser history, favorites and links.&lt;/p&gt;
&lt;h3&gt;The back problem is technically solved&lt;/h3&gt;
&lt;p&gt;If you look for a good article on how to implement a technical solution to the problem have a look
at the article "AJAX: How to Handle Bookmarks and Back Buttons" by Brad Neuberg at &lt;a href="http://www.onjava.com/lpt/a/6293"&gt;
http://www.onjava.com/lpt/a/6293&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;... by tricking IE&lt;/h3&gt;
&lt;p&gt;The Mozilla/Firefox solves this problem really straight forward and it works as expected.&lt;/p&gt;
&lt;p&gt;When using the method &lt;i&gt;window.location.replace(newHash)&lt;/i&gt; only the current URL is changed.&lt;/p&gt;
&lt;p&gt;By assigning a new value to the &lt;i&gt;window.location.hash&lt;/i&gt; property a new entry in the history list
is created.&lt;/p&gt;
&lt;p&gt;The IE is very confused about URL-hash values hat do not really point to existing anchors and does
not record any history and needs a invisible iframe with a page coming from the same server. It's a
little bit tricky to get all situations working and you can see the current implementation by looking
into the JavaScript implementation of the PropHistory Behaviour &lt;a href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/PropHistory.js"&gt;
(view source)&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;p&gt;The AJAXEngine already has a client side state mechanism (Page Properties or DataConnections) I introduced
&lt;a href="http://ajaxaspects.blogspot.com/2005_09_01_ajaxaspects_archive.html"&gt;in September 2005&lt;/a&gt;
that stores key-value pairs. Instead of building a new API and leave it to the AJAX application to call
a method to change the URL you only have to declare what page properties should be used in the URL.
When a Page Property's value changes the URL is updated automatically and when the URL changes all connected
controls will get informed about it.&lt;/p&gt;
&lt;p&gt;When one of the properties, that define a state that should be persisted to the history changes, a new
history entry is recorded.&lt;/p&gt;
&lt;p&gt;All you need to do to make it work is to include the PropHistory control:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;ajax:PropHistory runat="server" /&amp;gt;&lt;/pre&gt;
&lt;p&gt;and to declare what properties should be used to form the url (propList) and what subset of these properties
should define the state (stateList):&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;script defer="defer" type="text/javascript"&amp;gt;
  // set default values for the Page Properties, if the value is not in the URL:
  jcl.DataConnections.Load("version", "luther1912");
  jcl.DataConnections.Load("book", "1");
  jcl.DataConnections.Load("chapter", "1");
  jcl.DataConnections.Load("vers", "1");
 
  // declare the properties that should be written to the URL:
  PropHistory.propList = {"version":"","book":"","chapter":"","vers":""};
 
  // declare the properties that are meaningful for history recording:
  PropHistory.stateList = {"version":"","book":"","chapter":""};
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;The sample comes from the updated &lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx"&gt;
Bible reader&lt;/a&gt; application. When you navigate through the verses of a chapter, only the URL gets changed.
The navigation to a new book, version or chapter a new entry in the history stack is created.&lt;/p&gt;

&lt;p&gt;You now also can use URLs to jump directly to some important content. Donald E. Knuth likes reading any book chapter
3 verse 16 and specially


&lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx#version=sf_kjv_strongs_rev1b&amp;book=43&amp;amp;chapter=3&amp;vers=16"&gt;
BiblePage.aspx#version=sf_kjv_strongs_rev1b&amp;amp;book=43&amp;chapter=3&amp;amp;vers=16&lt;/a&gt;

and an important verse of the upcoming da vinci code movie by Dan Brown is


&lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx#version=en_gb_KJV2000_1&amp;book=18&amp;amp;chapter=38&amp;vers=11"&gt;
BiblePage.aspx#version=en_gb_KJV2000_1&amp;amp;book=18&amp;chapter=38&amp;amp;vers=11&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114746692296481932?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114746692296481932/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114746692296481932' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114746692296481932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114746692296481932'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/05/another-view-to-back-button-problem-of.html' title='Another view to the Back Button Problem of AJAX applications'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114538644417455236</id><published>2006-04-25T23:07:00.000+02:00</published><updated>2006-04-25T23:10:32.546+02:00</updated><title type='text'>Moving HTML objects using drag and drop around, CSS and JavaScript</title><content type='html'>&lt;p&gt;If you want to enable a custom page layout for the user or a drag &amp; drop functionality in your solution you need a mechanism
    that enables moving html objects around. Here is a cross browser compatible solution that enables moving of HTML objects.&lt;/p&gt;
  &lt;p&gt;To make it easy to attach a moving functionality to a object I use the lightweight JavaScript Behaviour
    mechanism that is described in the AJAX eBook found here: &lt;a href="http://www.mathertel.de/AJAX/AJAXeBook.aspx"&gt;
      http://www.mathertel.de/AJAX/AJAXeBook.aspx&lt;/a&gt;. Especially the cross browser event handling mechanism
    is used here.&lt;/p&gt;
  &lt;h3&gt;Attaching the mouse events&lt;/h3&gt;
  &lt;p&gt;Three events must be captured to drag objects around:&lt;/p&gt;
  &lt;p&gt;&lt;b&gt;onmousedown&lt;/b&gt;&lt;/p&gt;
  &lt;p&gt;
  This event starts the moving scenario and you need to attach a method to this event.
  &lt;p&gt;It is sometimes necessary not to move the object that got this event but to identify a specific parent
    object that also contains other content elements. In this demo sample the title area of a web part is
    used to drag the whole part around. In the method that is attached to this event the parentNode references
    are searched until an html object is found that is marked with the className "VEPart".&lt;/p&gt;
  &lt;p&gt;Then current mouse offset to the left upper corner of the moving object is calculated. This is because
    you will not start dragging by using a exactly known single point of the object.&lt;/p&gt;
  &lt;p&gt;Now that we know that a specific object should be dragged around the 2 other events must be monitored
    and 2 other methods are attached to them.&lt;/p&gt;
  &lt;p&gt;&lt;b&gt;onmousemove&lt;/b&gt;&lt;/p&gt;
  &lt;p&gt;This event will be thrown multiple times and we will move the object arround by using the new mouse
    coordinates given each time the event gets fired.&lt;/p&gt;
  &lt;p&gt;&lt;b&gt;onmouseup&lt;/b&gt;&lt;/p&gt;
  &lt;p&gt;This event will be thrown at the end when the user wants to place the object at the new position by
    releasing the mouse button.&lt;/p&gt;
  &lt;p&gt;The first event can be caught on specific objects that enable the moving. I use the CSS class "VEMover"
    to mark these elements and attach a move cursor. The object that is moves is marked by using the CSS
    class "VEPart" that contains the VEMover.&lt;/p&gt;
  &lt;p&gt;The 2 other events should be caught on the document level because they will not be thrown always on
    the object that initiates the moving especially when the mouse pointer is moved very fast.&lt;/p&gt;
  &lt;p&gt;Because we need a reference to the object that is moved around the onmousedown event also saves a
    reference to the object by using properties of the MoverBehaviour element like a global variable
    so we can find the object again when onmousemove and onmouseup events are caught.&lt;/p&gt;
  &lt;h3&gt;A simple moveable object&lt;/h3&gt;
  &lt;pre class="code"&gt;&amp;lt;div class="VEPart" style="width:180px;height:90px"&amp;gt;
  &amp;lt;div class="VEMover"&amp;gt;::: move me&amp;lt;/div&amp;gt;
  I can be moved.
&amp;lt;/div&amp;gt;&lt;/pre&gt;
  &lt;h3&gt;The JavaScript implementation&lt;/h3&gt;
  &lt;p&gt;To make the implementation easier I use my JavaScript Control Library that enables writing compatible
    behaviours for HTML objects. All we need here is to include the 9 kByte jcl.js file and attach the behavior
    to the VEMover object.&lt;/p&gt;
  &lt;p&gt;The MoverBehaviour implements the 3 event handlers:&lt;/p&gt;
  &lt;pre class="code"&gt;var MoverBehaviour = {
  mo: null, // reference to the movable obj,
  x: 0, y: 0,
  
  // ----- Events -----
  onmousedown: function (evt) {
    evt = evt || window.event;
    var src = jcl.FindBehaviourElement(evt.srcElement, MoverBehaviour);
    src.MoveStart(evt);
  }, // onmousedown


  // track mouse moves. This handler will be attached to the document level !
  _onmousemove: function (evt) {
    evt = evt || window.event;
    MoverBehaviour.MoveIt(evt);
  }, // onmousemove


  // track mouse button up. This handler will be attached to the document level !
  _onmouseup: function (evt) {
    evt = evt || window.event;
    MoverBehaviour.MoveEnd(evt);
  }, // onmouseup


  // ----- Methods -----
  MoveStart: function (evt) {
    // find the moving part (position:absolute or class="VEPart")
    var mo = this;
    while ((mo != null) &amp;&amp; (mo.className != "VEPart"))
      mo = mo.parentNode;

    if (mo == null)
      return; // don't move
    MoverBehaviour.mo = mo;
      
    // calculate mousepointer-object distance
    mo.x = mo.y = 0;
    obj = mo;
    while (obj != null) {
      mo.x += obj.offsetLeft;
      mo.y += obj.offsetTop;
      obj = obj.offsetParent;
    } // while
    mo.x = evt.clientX - mo.x;
    mo.y = evt.clientY - mo.y;

    // make the moving object globally evailable when mouse is leaving this object.
    jcl.AttachEvent(document, "onmousemove", this._onmousemove);
    jcl.AttachEvent(document, "onmouseup", this._onmouseup);
  }, // MoveStart
  

  MoveIt: function (evt) {
    var mo = MoverBehaviour.mo;
    if (mo != null) {
      var p = (evt.clientX - mo.x) + "px";
      if (p != mo.style.left) mo.style.left = p;
      p = (evt.clientY - mo.y) + "px";
      if (p != mo.style.top) mo.style.top = p;
    } // if
    // cancel selecting anything
    evt.cancelBubble = true;
    evt.returnValue = false;
  }, // MoveIt
  

  MoveEnd: function () {
    var mo = MoverBehaviour.mo;
    if (mo != null) {
      MoverBehaviour.mo = null;
      jcl.DetachEvent(document, "onmousemove", this._onmousemove);
      jcl.DetachEvent(document, "onmouseup", this._onmouseup);
    } // if
  } // MoveEnd
    
} // MoverBehaviour

jcl.LoadBehaviour("moveme", MoverBehaviour);&lt;/pre&gt;

  &lt;p&gt;The sample web page is available at &lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/MoverDemo.aspx"&gt;
    http://www.mathertel.de/AJAXEngine/S04_VisualEffects/MoverDemo.aspx&lt;/a&gt; and a brief description of the
    JavaScript control library is available on web site in the eBook about my AJAX engine in the chapter
    "Building AJAX Controls" at: &lt;a href="http://www.mathertel.de/AJAX/AJAXeBook.aspx"&gt;http://www.mathertel.de/AJAX/AJAXeBook.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The MoverBehaviour is also available as a separate include file if you want to follow my advice of reusing behaviours by separating them into a JavaScript include file.
I will have a typical WebPart sample soon and will use the mover functionality there again.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114538644417455236?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114538644417455236/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114538644417455236' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114538644417455236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114538644417455236'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/04/moving-html-objects-using-drag-and.html' title='Moving HTML objects using drag and drop around, CSS and JavaScript'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114573542840136049</id><published>2006-04-22T21:46:00.000+02:00</published><updated>2007-06-10T16:57:46.147+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>Less waiting on AJAX</title><content type='html'>&lt;p&gt;It's a psychological phenomena that waiting takes less time as long as
something happens.&lt;/p&gt;

&lt;p&gt;I'm sure you have seen all these nice rotating arrows, bouncing points or bars that
are commonly used for situations where a progress bar should appear to
tell the user that it's time for waiting like on the windows start up screen on
&lt;a href="http://www.pageflakes.com/"&gt;http://www.pageflakes.com/&lt;/a&gt;
or even in windows media edition. It can also be as simple as the [Loading...] text
that is used by the Google-Mail user interface.&lt;/p&gt;

&lt;p&gt;So, when I fell over &lt;a href="http://www.ajaxload.info"&gt;http://www.ajaxload.info&lt;/a&gt;
last week where you can easily generate "AJAX-" animated gif files I thought it is time
to implement a few lines into the AJAX Engine.&lt;/p&gt;

&lt;p&gt;The right place to start displaying a progress indicator is just before starting the
webservice call to the server. Here I call StartProgress().&lt;/p&gt;
&lt;p&gt;But it also has to be hidden after anything happens that
ends the action like when the return value is there, an exception happens or when the
timeout timer strikes. To identify these places I searched the code for the ajax.current
gets cleared. There I call EndProgress();&lt;/p&gt;

&lt;p&gt;The first implementation was straight forward creating and removing a html element.
After some testing I found that this costs me more time than the real call over the
internet and in many situations immediate responses got slower and that's definitively not
that what I wanted to achieve.&lt;/p&gt;
&lt;p&gt;In the end I came to the following solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The StartProgress function only sets a flag
(ajax.progress) to true and starts a timer (ajax.progressTimer) with a timeout
of 220 msec.

&lt;li&gt;This time was chosen by some testing and many server
calls do not last so long and therefore need no progress indicator.

&lt;li&gt;When the timer strikes it calls the ajax.ShowProgress
function. Here I implement the real code that creates the HTML element or just
shows an existing one again.

&lt;li&gt;The EndProgress function clears the flag and also
starts the timer but with some less waiting.

&lt;li&gt;When the timer strikes after a call has finished the
existing object is just hidden.
&lt;p&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This architecture has some advantages. First the progress indicator is not shown when short calls are made and
when multiple calls are made one after the other it is not hidden.
This can save a lot of flickering.&lt;/p&gt;

&lt;p&gt;Here are the specific new functions:&lt;/p&gt;

&lt;pre class="code"&gt;// ----- show or hide a progress indicator -----

// show a progress indicator if it takes longer...
ajax.StartProgress = function() {
  ajax.progress = true;
  if (ajax.progressTimer != null)
    window.clearTimeout(ajax.progressTimer);
  ajax.progressTimer = window.setTimeout(ajax.ShowProgress, 220);
} // ajax.StartProgress


// hide any progress indicator soon.
ajax.EndProgress = function () {
  ajax.progress = false;
  if (ajax.progressTimer != null)
    window.clearTimeout(ajax.progressTimer);
  ajax.progressTimer = window.setTimeout(ajax.ShowProgress, 20);
} // ajax.EndProgress


// this function is called by a timer to show or hide a progress indicator
ajax.ShowProgress = function() {
  ajax.progressTimer = null;
  var a = document.getElementById("AjaxProgressIndicator");
 
  if (ajax.progress &amp;amp;&amp; (a != null)) {
    // just display the existing object
    a.style.top = document.documentElement.scrollTop + 2 + "px";
    a.style.display = "";
   
  } else if (ajax.progress) {
    // find a relative link to the ajaxcore folder containing ajax.js
    var path = "../ajaxcore/"
    for (var n in document.scripts) {
      s = document.scripts[n].src;
      if ((s != null) &amp;amp;&amp; (s.length &amp;gt;= 7) &amp;amp;&amp; (s.substr(s.length -7).toLowerCase() == "ajax.js"))
        path = s.substr(0,s.length -7);
    } // for
   
    // create new standard progress object
    a = document.createElement("div");
    a.id = "AjaxProgressIndicator";
    a.style.position = "absolute";
    a.style.right = "2px";
    a.style.top = document.documentElement.scrollTop + 2 + "px";
    a.style.width = "98px";
    a.style.height = "16px"
    a.style.padding = "2px";
    a.style.verticalAlign = "bottom";
    a.style.backgroundColor="#51c77d";

    a.innerHTML = "&amp;lt;img style='VERTICAL-ALIGN:bottom' src='" + path + "ajax-loader.gif'&amp;gt; please wait...";
    document.body.appendChild(a);

  } else if (a) {
    a.style.display = "none";
  } // if
} // ajax.ShowProgress&lt;/pre&gt;

&lt;p&gt;You can find the full source
&lt;a href="http://www.mathertel.de/AjaxEngine/ViewSrc.aspx?file=ajaxcore/ajax.js"&gt;here&lt;/a&gt;
and I will also include it into the next ajax.zip.&lt;/p&gt;

&lt;p&gt;If you want to see how it looks like you can use the old prime factor sample.
Try some long the numbers like: 98798798789878987. You might see it only if
someone else is stressing the server too - It seems to be a powerful machine :-) and
prime factors get calculated fast even with my stupid algorithm :-).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114573542840136049?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114573542840136049/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114573542840136049' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114573542840136049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114573542840136049'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/04/less-waiting-on-ajax.html' title='Less waiting on AJAX'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114538529661480420</id><published>2006-04-20T21:32:00.000+02:00</published><updated>2007-06-10T16:57:05.183+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><title type='text'>Simple sliding sample to move HTML elements around</title><content type='html'>&lt;p&gt;Moving HTML objects to new positions is not hard to implement. You can use absolute positioning and
just set the style attributes left and top to the new values but it doesn't look cool if the objects
use this kind of hyper speed: the eyes cannot follow and there may be a confusing effect of a sudden
rearrangement.&lt;/p&gt;
&lt;p&gt;Moving objects more slowly can be simulated by moving them using several steps and only a small distance
at once. All we need is a timer to start the next step after the current position is rendered, a little
bit of algebra and a heuristic to find the right distance for one step.&lt;/p&gt;
&lt;p&gt;Because no local variables can be used when executing timer scripts we declare 4 global variables that
hold all the information we need when the next step is to be started:&lt;/p&gt;
&lt;pre class="code"&gt;var slidingTimer = null; // the current running timer object
var slidingTarget = null; // the moving object
var slidingLeft = null; // the target left position
var slidingTop = null; // the target top position&lt;/pre&gt;
&lt;p&gt;Starting a sliding movement can be done by calling the startSlidePos function with 3 parameters: the
object that should be moved, the new left and the new top coordinate. You can also refer the object
by using the unique id.&lt;/p&gt;
&lt;pre class="code"&gt;onclick="startSlidePos('i', 10, 270)"&lt;/pre&gt;
&lt;p&gt;Every timer event now calculates the remaining vector but takes no more than 20 pixel length or a third
of it whatever is shorter. Only if the target is very close the object will be positioned exactly:&lt;/p&gt;
&lt;pre class="code"&gt;// calc the remaining vector
dx = slidingLeft - left;
dy = slidingTop - top;

// calc the movement length along the vector
len = Math.sqrt(dx * dx + dy * dy);
delta = Math.min(20, len/3);

if (len &amp;lt;= 2) {
  // snap exactly
  left = slidingLeft;
  top = slidingTop;

} else {
  left += Math.round(dx * delta / len);
  top += Math.round(dy * delta / len);
} // if&lt;/pre&gt;
&lt;p&gt;Using this calculation the movement gets slower at the end when the target is almost reached.&lt;/p&gt;
&lt;p&gt;You can see the full source code by using the view source functionality of your browser or in the right
upper corner of the page.&lt;/p&gt;
&lt;p&gt;You can find the sample live at:
&lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/SlidingDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/SlidingDemo.aspx&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114538529661480420?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114538529661480420/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114538529661480420' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114538529661480420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114538529661480420'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/04/simple-sliding-sample-to-move-html.html' title='Simple sliding sample to move HTML elements around'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114530182632330039</id><published>2006-04-17T21:20:00.000+02:00</published><updated>2007-06-10T16:56:34.241+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><title type='text'>HTML elements with rounded corners</title><content type='html'>&lt;p&gt;HTML elements up to now have always a rectangle shape. In the upcoming CSS3 standard (still a proposal)
there might be also other border shapes available including rounded corners by specifying a border radius.
But we do not have to wait to get this visual effect shown up.&lt;/p&gt;
&lt;p&gt;The trick that is shown here to get the usual rectangle corners into a round shape is to use a collection
of thin HTML elements to build a non rectangle border.&lt;/p&gt;
&lt;p&gt;The simplest solution to this is to use &lt;strong&gt;&amp;lt;div&amp;gt;&lt;/strong&gt; at the top and bottom and arrange
them like this:&lt;/p&gt;
&lt;img src="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/RoundedCornersPlot.png" /&gt;
&lt;h3&gt;Why not using a client side solution&lt;/h3&gt;
&lt;p&gt;The Rico framework for example is offering a client-side method to round the elements:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;div id='roundDemo' style='width:300px'&amp;gt;Insert content here.&amp;lt;/div&amp;gt;
&amp;lt;script&amp;gt;Rico.Corner.round('roundDemo', {corners:'tl br',bgColor:'#adba8c'});&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;By using a JavaScript solution on the client to generate these elements every div element can be transformed
to a rounded corner look. The disadvantage of this approach is that there is always a delay and maybe
a light flickering because the page will get rendered twice because the borders will be expanded by
adding the additional elements.&lt;/p&gt;
&lt;h3&gt;Why not using graphic elements&lt;/h3&gt;
&lt;p&gt;I've also seen solutions that use 4 specific corner graphics. The drawback about this approach is that
the colors of these images must correspond exactly to the colors of the other html elements. If you
want to change your style then you must change the images too. Again here will be a light flickering
because images are often loaded after displaying the page for the first time so it doesn't look very
perfect.&lt;/p&gt;
&lt;h3&gt;A server-side solution&lt;/h3&gt;
&lt;p&gt;It is also possible to generate all the additional html elements on the server. This adds some html
tags and some more data to the http response when the page gets loaded but also eliminates a lot of
JavaScript or images.&lt;/p&gt;
&lt;p&gt;For ASP.NET I've written a web control that derives from asp:Panel that does the same and avoids the
flickering:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;ajax:RoundedArea runat='server' id='any' width='300'&amp;gt;Insert content here.&amp;lt;/ajax:RoundedArea&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You can see a live sample of it at
&lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/RoundedDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/RoundedDemo.aspx&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114530182632330039?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114530182632330039/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114530182632330039' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114530182632330039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114530182632330039'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/04/html-elements-with-rounded-corners.html' title='HTML elements with rounded corners'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114450419291009067</id><published>2006-04-08T15:43:00.000+02:00</published><updated>2006-04-08T15:49:52.926+02:00</updated><title type='text'>HTML + CSS Shadow Effect with real transparency</title><content type='html'>&lt;p&gt;If you want to give your objects a kind of 3D feeling then you might want to use shadows for those
    objects that are placed upon the web page.&lt;/p&gt;
  &lt;h3&gt;Using special graphics&lt;/h3&gt;
  &lt;p&gt;A often solution for&amp;nbsp;a shadow effect is to use table layout around the main content and arrange
    a set of graphics around the right and bottom border. You can get really wonderful shadow dropping effects
    using this approach but because semi transparent images are not very well supported on IE you will have
    to pay attention to the background color you use on the page and have to mix it into your shadow images.&lt;/p&gt;
  &lt;h3&gt;Using a Microsoft IE specific CSS filter attribute&lt;/h3&gt;
  &lt;p&gt;When using the IE only you can also us one of the wonderful filter effects that are available in this
    browser. Just add a CSS filter attribute like that:&lt;/p&gt;
  &lt;pre class='code'&gt;filter: progid:DXImageTransform.Microsoft.dropShadow(Color=AAAAAA,offX=8,offY=8,positive= true);&lt;/pre&gt;
  &lt;p&gt;If you use IE that you can see these shadows on the &lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/default.aspx"&gt;entry page&lt;/a&gt; for the visual
    effects library. These shadows are also drawn by using solid colors.&lt;/p&gt;
  &lt;h3&gt;Using CSS opacity&lt;/h3&gt;
  &lt;p&gt;
  Here is a better solution that really resembles a kind of shadow because the text and graphics in the
  shadow are really displayed in dimmed light. The clue to this effect is a built-in opacity CSS graphics
  effect that is available IE, Mozilla, Firefox - but in different way.&lt;p&gt;In Internet Explorer:&amp;nbsp; style="filter:
    alpha(opacity= 50)"&lt;/p&gt;
  &lt;p style="margin-left: 12px"&gt;The IE notation of the opacity effect is using a proprietary CSS attribute
    named filter that can be used to add various effects to a HTML element. Here we use the alpha filter.&lt;/p&gt;
  &lt;p&gt;In Mozilla/Firefox: style= "-moz-opacity:0.5"&lt;/p&gt;
  &lt;p style="margin-left: 12px"&gt;The Mozilla / Firefox provides a proprietary css attribute named -moz-opacity
    that allows specifying a opacity value.&lt;/p&gt;
  &lt;p&gt;In Opera: style= "opacity:0.5"&lt;/p&gt;
  &lt;p style="margin-left: 12px"&gt;The Opera browser also has a proprietary css attribute named opacity that
    allows specifying an opacity value.&lt;/p&gt;
  &lt;p&gt;These 3 CSS attributes can be combined together and every browser ignores all the attributes that are
    unknown:&lt;/p&gt;
  &lt;pre class='code'&gt;style="filter: alpha(opacity= 50); -moz-opacity:0.5; opacity: 0.5" &lt;/pre&gt;
  &lt;h3&gt;The HTML shadow object&lt;/h3&gt;
  &lt;p&gt;This effect must be applied to rectangle region with a fixed width and height that is over the main
    content by using an absolute position by using the same size as the html part that is dropping this
    shadow.&lt;/p&gt;
  &lt;p&gt;Here is a simple sample that uses this trick. You can see it live at &lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/ShadowDemo.aspx"&gt;
    ShadowDemo.aspx&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;The good about this solution is, that no graphics are used and that the shadow does not hide the text
    below but only seems to dim the available light.&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;
    The outer div element is used to do the absolute positioning of the whole group.
    &lt;li&gt;
    The first inner &amp;lt;div&amp;gt; element is the object that has the opacity effect applied. It is positioned
    some pixel to the right and down by using an absolute positioning (relative to the containing &amp;lt;div&amp;gt;)
    too.
    &lt;li&gt;The Content is placed inside the second inner &amp;lt;div&amp;gt; element that must have a relative position
      without any offset to be displayed above the shadow object.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Here is the plain HTML code:&lt;/p&gt;
  &lt;pre class="code"&gt;
&amp;lt;div class="VEPart" style="position: relative; width: 120px; top:-90px; left: 40px;"&amp;gt;
  &amp;lt;div class="VEShadow" style="position: absolute; left: 10px; top: 10px;
    width: 120px; height: 84px; background-color: black;
    filter: alpha(opacity=30); -moz-opacity: 0.3; opacity: 0.3;"&amp;gt; &amp;lt;/div&amp;gt;
  &amp;lt;div class="VEContent" style="position: relative; height: 80px;
    background-color: #FFFFDD;"&amp;gt; I am flying above the text and dropping a shadow.&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt; &lt;/pre&gt;
  &lt;p&gt;You can see how it looks like on the demo website at 
&lt;a href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/ShadowDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/ShadowDemo.aspx&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114450419291009067?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114450419291009067/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114450419291009067' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114450419291009067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114450419291009067'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/04/html-css-shadow-effect-with-real.html' title='HTML + CSS Shadow Effect with real transparency'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114409085810705443</id><published>2006-04-03T20:59:00.000+02:00</published><updated>2007-06-10T17:08:46.291+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Effects'/><title type='text'>Why AJAX needs visual effects</title><content type='html'>&lt;p&gt;Implementing a web based application by using AJAX techniques is about improving
the backside, will elable the right user experience and will make your application
work the way it should.&lt;/p&gt;
&lt;p&gt;If you want that your application really looks like AJAX you also have to give
your application a modern design together with all kinds of visual effects. That
will really impress!&lt;/p&gt;
&lt;p&gt;Don't you think that this is nonsense ? - I did for some time last year but I had to change my mind - at least a little bit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
If you travel across the web sides of the commercial AJAX frameworks you will find
on almost every site a bunch of visual effect libraries that are technically not
bound to asyncronous JavaScript and XML nor xmlhttp.
&lt;li&gt;
Commercial frameworks like backbase or frameworks like script.aculo.us do offer
visual effects side by side with AJAX functionality. &lt;li&gt;Some of the effects shown
here are really stupid eye-catcher effects.&lt;/li&gt;
&lt;li&gt;
Web applications that do not use xmlhttp but do asynchronous image loading are seen
as AJAX applications.
&lt;li&gt;Articles about AJAX do mix up client-server communications with visual effects.
A sample on that: &lt;a href="http://www.maxkiesler.com/index.php/weblog/comments/451/"&gt;
http://www.maxkiesler.com/index.php/weblog/comments/451/&lt;/a&gt;
&lt;li&gt;Another article: AJAX Rounded Corner Tutorials at &lt;a href="http://encytemedia.com/blog/articles/2005/12/01/rico-rounded-corners-without-all-of-rico"&gt;
http://encytemedia.com/blog/articles/2005/12/01/rico-rounded-corners-without-all-of-rico&lt;/a&gt;
&lt;li&gt;Another article: Ajax Workshop 2 - Building Tabbed Content at &lt;a href="http://www.ajaxlessons.com/2006/02/18/ajax-workshop-2-building-tabbed-content/"&gt;
http://www.ajaxlessons.com/2006/02/18/ajax-workshop-2-building-tabbed-content/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;... and you can find a lot more of them&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Visual effects are definitvely an important aspect for AJAX applications today.
Maybe the "market" will learn the technical difference in some near future. Maybe
a "get-it-all-together" solution is the right approach for the "market".&lt;/p&gt;
&lt;p&gt;So here is a list of visual effects and other "cool" looking stuff. Some of these
effects can also be used in any other html based application, some of them will
use AJAX. I'll explain the HTML+CSS+JavaScript that makes the effect but I will
also bring the higher level approach using ASP.NET web controls that makes using
them really easy.&lt;/p&gt;
&lt;h2&gt;AJAX applications look great! :-)&lt;/h2&gt;
&lt;p&gt;So here comes a library of visual effects. From time to time I will add another
one and you will find them also on the demo side at &lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;
http://www.mathertel.de/AJAXEngine/&lt;/a&gt; see Examples -&amp;gt; Visual Effects .&lt;/p&gt;
&lt;p&gt;The documentation you will find here on my blog and (with a little delay) in the
AJAX eBook at http://www.mathertel.de/ajax/eBook.aspx. You will not find only a
working solution but also a brief description on how it works so you can also use
it in any of your projects too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114409085810705443?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114409085810705443/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114409085810705443' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114409085810705443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114409085810705443'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/04/why-ajax-needs-visual-effects.html' title='Why AJAX needs visual effects'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114147788736284742</id><published>2006-03-04T14:03:00.000+01:00</published><updated>2007-06-10T17:09:03.793+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>SOAP was made for AJAX</title><content type='html'>&lt;p&gt;I recently ran over the blog of Dave Winer and his post from Sun, Sep 12, 1999 titled "An end to the Über-Operating System". see: &lt;a href="http://davenet.scripting.com/1999/09/12/anEndToTheUberoperatingSystem"&gt;http://davenet.scripting.com/1999/09/12/anEndToTheUberoperatingSystem&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;... The purpose of both specs [SOAP and XML-RPC] is to enable scripted web applications to cross operating system boundaries.&lt;/cite&gt;&lt;/p&gt;

&lt;p&gt;Of course the term AJAX was not known then but I thing that "scripted web applications that cross operating system boundaries" is a good definition of AJAX.
By using SOAP there even is more XML on the wire than with AJAX applications using a JSON or plain text transport protocol.&lt;/p&gt;

&lt;p&gt;Ask yourself: what is or should be the standard protocol for AJAX applications when retrieving data from the server? - By using SOAP many aspects of a transport layer have been discussed (data types, attachments ...) and there are even more upcoming standard extensions for it (security, routing ...).&lt;/p&gt;

&lt;p&gt;The only thing that I really miss is a built-in native SOAP client in browsers.&lt;/p&gt;

&lt;p&gt;The (deprecated) SOAP spec from 1999: &lt;a href="http://www.oasis-open.org/cover/draft-box-http-soap-00.txt"&gt;http://www.oasis-open.org/cover/draft-box-http-soap-00.txt&lt;/a&gt;. I think that this doc is one of the most influencing documents I've read. It disappeared from the Microsoft site and http://www.ietf.org. Does anybody know who feels responsible for achieving historical documents from the internet?&lt;/p&gt;
&lt;p&gt;Thanks to Don Box, Dave Winer and all the other founders of SOAP.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114147788736284742?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114147788736284742/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114147788736284742' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114147788736284742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114147788736284742'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/03/soap-was-made-for-ajax.html' title='SOAP was made for AJAX'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-114036017230506348</id><published>2006-02-19T15:41:00.000+01:00</published><updated>2007-06-10T17:07:54.521+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>Use web services with multiple parameters in the AJAX Engine</title><content type='html'>&lt;p&gt;
In the past moths I've got mails that all request for more functionality in the
javascript webservice proxies and the AJAX engine so I've added more support for
datatypes and arrays in december last year and got some more compatibility with
other SOAP implementations then ASP.NET.&lt;/p&gt;
&lt;p&gt;
I've also got some requests that describe to reuse existing web services that have
multiple parameters on a AJAX page and I think this is a valid request.&lt;/p&gt;
&lt;p&gt;
While it is possible to use web methods with multiple parameters when using the
web service proxies layer directly, the AJAX engine level is only supporting one
parameter - but there is a small trick that help you out of this situation.&lt;/p&gt;
&lt;p&gt;
The AJAX engine knows about all the asynchronous steps that have to be done to complete
the whole functionality through the declaration of an action object. The details
about that can be found in the documentation at &lt;a href="http://www.mathertel.de/ajax/Aspects%20of%20AJAX_index.htm"&gt;
http://www.mathertel.de/ajax/Aspects%20of%20AJAX_index.htm&lt;/a&gt;. See the chapter
about the "AJAX Actions".&lt;/p&gt;
&lt;p&gt;
Now have a look how this mechanism can be used with multiple webservice parameters.
You can find a sample that simply adds 2 integers at &lt;a href="http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcAJAX.aspx"&gt;
http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/CalcAJAX.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
The &lt;b&gt;prepare&lt;/b&gt; function is normally used for retrieveing the client-side parameter
from the html objects. Because we need more than one parameter we just do nothing
here except returning the context object.&lt;/p&gt;
&lt;p&gt;
The &lt;b&gt;call&lt;/b&gt; function, that is called next is not just pointing to the proxy
function of the method of the web service but needs some more code. It retrieves
all the parameters itself and then calls the proxy method webservice. The trick
is, that the mechanism that handles asynchronous result messages is not hooked up
correctly and must be patched by using 2 lines of code for the regular and the exception
case:&lt;/p&gt;
&lt;pre class="code"&gt;proxies.CalcService.AddInteger.func = this.call.func;
proxies.CalcService.AddInteger.onException = this.call.onException;&lt;/pre&gt;
&lt;p&gt;
Now the call will be processed asynchronously and the result value will be passed
to the &lt;b&gt;finish&lt;/b&gt; function as usual.&lt;/p&gt;
&lt;p&gt;
Here the complete code that declares the AJAX action:&lt;/p&gt;
&lt;pre class="code"&gt;// declare an AJAX action
var action1 = {
  delay: 200, // wait for multiple keystrokes from fast typing people
 
  // the prepare function just returns the context object (if any)
  // and makes it available to the call function.
  prepare: function(obj) { return (obj); },

  // the call is not pointing to the webservice proxy directly but calls it using several parameters.
  call: function (obj) {
    var n1 = document.getElementById("n1").value;
    var n2 = document.getElementById("n2").value;
    proxies.CalcService.AddInteger.func = this.call.func; // patch
    proxies.CalcService.AddInteger.onException = this.call.onException; // patch
    proxies.CalcService.AddInteger(n1, n2); // and call
  },
 
  // the result will now be processed as usual.
  finish: function (p) { document.getElementById("outputField").value = p; },
 
  onException: proxies.alertException
} // action1&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-114036017230506348?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/114036017230506348/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=114036017230506348' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114036017230506348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/114036017230506348'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/02/use-web-services-with-multiple.html' title='Use web services with multiple parameters in the AJAX Engine'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113905974453403990</id><published>2006-02-04T20:26:00.000+01:00</published><updated>2006-02-04T14:29:05.350+01:00</updated><title type='text'>Comparisation of AJAX frameworks</title><content type='html'>&lt;p&gt;Daniel Zeiss, who is the man behind the ComfortASP.NET framework
see &lt;a href="http://www.comfortasp.de/"&gt;http://www.comfortasp.de/&lt;/a&gt;
has published a very interesting comparison on his web site
(&lt;a href="http://www.daniel-zeiss.de/AJAXComparison/Results.htm"&gt;http://www.daniel-zeiss.de/AJAXComparison/Results.htm&lt;/a&gt;)
 and his blog (&lt;a href="http://www.geekswithblogs.com/danielz"&gt;http://www.geekswithblogs.com/danielz&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;(Have you noticed that there are many German developers involved in AJAX engines and frameworks?)&lt;/p&gt;

&lt;p&gt;I have also implemented the simple sample he uses for the comparison at 
&lt;a href="http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/AJAXComparison.htm"&gt;http://www.mathertel.de/AJAXEngine/S02_AJAXCoreSamples/AJAXComparison.htm&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;My annotations on these results&lt;/h3&gt;

&lt;p&gt;The Aspects of AJAX Engine is consuming less bytes on the network that most of the other machines in this comparison.&lt;/p&gt;

&lt;p&gt;The size of the transferred bytes is indeed a very interesting aspect. I have not spent any time in reducing this value and I also have no chance to reduce the bytes of a standard SOAP call without leaving this standard and adding the need to implement server specific code.&lt;/p&gt;

&lt;p&gt;The initial transfer of the page is smaller than the original ASP.NET version mainly because I do not need any ASP.NET functionality for deploying a working page.&lt;/p&gt;

&lt;p&gt;The biggest part of the Engine is the ajax.js file with 21876 bytes
because it contains a lot of comments and additional information.
I could reduce this page in a view minutes by stripping off all the comments and blank lines down to 12000 bytes and it can be reduced even more.
Thats the size that should be used in the comparison because the other frameworks also only send optimized include files.&lt;/p&gt;

&lt;p&gt;The other AJAX implementations are very strong bound to the ASP.NET programming model
and therefore have to solve many content-update topics - That's what Daniel Zei calls "indirect AJAX programming".
The Aspects of AJAX Engine only transfers data on the network and must right now implement content changes
on the client using JavaScript. This is also true for many other "direct AJAX programming" environments.
By using AJAX enabled controls, even this work is not necessary because the controls can handle themselves and only the developer of the control itself has to think about it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113905974453403990?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113905974453403990/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113905974453403990' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113905974453403990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113905974453403990'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/02/comparisation-of-ajax-frameworks.html' title='Comparisation of AJAX frameworks'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113897017564203857</id><published>2006-02-03T21:31:00.000+01:00</published><updated>2007-06-10T17:12:18.470+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAXEngine'/><title type='text'>Aspects of AJAX: An Engine for Java</title><content type='html'>&lt;p&gt;This AJAX Engine was originating published in 2005 for the ASP.NET 2.0 Platform and is now partly also available in JAVA. This Engine can be ported very easily because it relies on web standards that are available on many platforms and in many languages:&lt;/p&gt;

&lt;h3&gt;JavaScript / ajax.js&lt;/h3&gt;
&lt;p&gt;A huge part of the coding is done using JavaScript on the client. This code needs shared by both projects and is always exchangeable.&lt;/p&gt;

&lt;h3&gt;WebServices&lt;/h3&gt;
&lt;p&gt;The asynchronous calls from the page in the browser to the server are implemented using the SOAP standard. On the server we only need Standard WebServices. Both platforms, ASP.NET and Java support the bottom up implementation of WebServices and we just need to write simple methods that get called from the client.&lt;/p&gt;

&lt;h3&gt;XSLT / WebService Proxies&lt;/h3&gt;
&lt;p&gt;To enable a communication from the client side, the server uses the WSDL definitions that can be generated from WebServices on both platforms and transforms them to proxy objects using JavaScript.&lt;/p&gt;

&lt;p&gt;The retrieval of the WSDL and for the transformation is ported and needs only about 30 lines of code that you can find in ~/ajaxcore/GetJavaScriptProxy.aspx or ~/ajaxcore/GetJavaScriptProxy.jsp.&lt;/p&gt;

&lt;p&gt;The definition of the translation itself is coded using an xslt definition in the file ~/ajaxcore/wsdl.xslt that is also identical on both platforms.&lt;/p&gt;

&lt;p&gt;The AJAX Engine needs nothing else than these 3 building blocks.&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;The download is available on my web side: http://www.mathertel.de/AJAXEngine/ in the download section containing a eclipse project. I use right now: Eclispe 3.1.2 with the Webtools plug-in 1.0, Java 1.4.2.x, Tomcat 5.5 incl. the compatibility jar and Axis 1.2.1&lt;/p&gt;

&lt;h3&gt;Documentation&lt;/h3&gt;
&lt;p&gt;If you search for more documentation use the following links that are part of the ASP.NET version written in C#. Java programmers should understand the code very easily and there are also many JavaScript hints and tricks documented in there.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/soap/JavaScriptProxy_01.asp"&gt;http://www.codeproject.com/soap/JavaScriptProxy_01.asp&lt;/a&gt;
A early available documentation about how the JavaScript proxies are generated and how they work.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ajaxaspects.blogspot.com/"&gt;http://ajaxaspects.blogspot.com/&lt;/a&gt;
The blog where all you can find all the documentation that was written while the project was growing.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;http://www.mathertel.de/AJAXEngine/&lt;/a&gt;
The ASP.NET based demo WebSide containing all the samples I talked about in my blog.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.mathertel.de/ajax/Aspects%20of%20AJAX_index.htm"&gt;http://www.mathertel.de/ajax/Aspects of AJAX_index.htm&lt;/a&gt;
An eBook about the AJAX Engine. Here you can find most of the content of the blog and some more hints.&lt;/p&gt;

&lt;p&gt;Please contact me via my blog and let me know how you find this work - and what you miss.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113897017564203857?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113897017564203857/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113897017564203857' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113897017564203857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113897017564203857'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/02/aspects-of-ajax-engine-for-java.html' title='Aspects of AJAX: An Engine for Java'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113872206842638806</id><published>2006-01-31T20:34:00.000+01:00</published><updated>2006-01-31T16:41:30.553+01:00</updated><title type='text'>AJAX for ASP.NET</title><content type='html'>&lt;p&gt;I've got several questions about what .NET version the &lt;a href="http://www.mathertel.de/AJAXEngine"&gt;AJAX Engine&lt;/a&gt; is supporting.&lt;/p&gt;
&lt;p&gt;The answer is: .NET 2.0&lt;/p&gt;

&lt;p&gt;BUT, most of the AJAX programming is done using JavaScript that runs on the client side and the AJAX part on the server is implemented by standard webservices and some people started porting the code to JAVA...&lt;/p&gt;

&lt;p&gt;If you know about ASP.NET 1.1 it should be possible for you to port the sources back to ASP.NET 1.1 and I've written a &lt;a href="http://www.mathertel.de/ajax/Aspects%20of%20AJAX_index.htm"&gt;some text&lt;/a&gt; about the concepts behind my ideas that may help.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113872206842638806?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113872206842638806/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113872206842638806' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113872206842638806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113872206842638806'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/01/ajax-for-aspnet.html' title='AJAX for ASP.NET'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113667234307912003</id><published>2006-01-07T23:17:00.000+01:00</published><updated>2006-01-10T21:13:13.850+01:00</updated><title type='text'>An AJAX based Tree View for the Bible</title><content type='html'>&lt;p&gt;I just published another Page displaying a English Bible using an AJAX Tree View Control. It just took me half an hour, including some other housekeepings.&lt;/p&gt;
&lt;p&gt;Have a Look at &lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BibleTreeView.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BibleTreeView.aspx&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113667234307912003?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113667234307912003/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113667234307912003' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113667234307912003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113667234307912003'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/01/ajax-based-tree-view-for-bible.html' title='An AJAX based Tree View for the Bible'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113641048436975169</id><published>2006-01-04T22:28:00.000+01:00</published><updated>2006-01-04T22:34:44.380+01:00</updated><title type='text'>TreeView sample did not run with FireFox - Bug fixed!</title><content type='html'>&lt;p&gt;The &lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TreeView.aspx"&gt;TreeView sample&lt;/a&gt; I posted yesterday did not run with FireFox. - I just did not test it and did not find it in time.&lt;/p&gt;
&lt;p&gt;I fixed the bug today and it works now. Changes are in ~/controls/TreeView.js.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113641048436975169?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113641048436975169/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113641048436975169' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113641048436975169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113641048436975169'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/01/treeview-sample-did-not-run-with.html' title='TreeView sample did not run with FireFox - Bug fixed!'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113632351033238868</id><published>2006-01-03T22:24:00.000+01:00</published><updated>2006-01-05T22:26:05.626+01:00</updated><title type='text'>Tree View AJAX Control</title><content type='html'>&lt;p&gt;The sample page is available at: &lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TreeView.aspx"&gt;http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TreeView.aspx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hierarchically structured data can be found in various places on this world.
File systems, network structures, dependencies, organisation charts, bill of materials
etc. are hierarchical by nature or by design or can be viewed to be so.&lt;/p&gt;

&lt;p&gt;(I personally think that the reason behind the fact that so many structures 
are hierarchically organized is that more complex structures are too
chaotic to be understood easily.)&lt;/p&gt;

&lt;p&gt;Displaying hierarchical data as trees is relatively easy
to be implemented and you can find many implementations with ASP.NET Controls on the web.
But when it comes to mass data situations (like the content of a file system)
it is almost impossible to load the complete tree at.
A simple paging approach, that is known from huge table-data doesn't fit for
structured data.&lt;/p&gt;

&lt;p&gt;Displaying this kind of data of a good place for using the AJAX technology and
the architecture of my AJAX controls is also used here.
The best solution is to load and open only the root level of the tree when
loading the page and to load all sub-levels when the user wants to dig down
by clicking a folder.
Already loaded sub-levels can stay at the client until the page gets reloaded.&lt;/p&gt;

&lt;p&gt;The AJAX engine can be used to solve the server call in the background
very easily by using a WebService that can be queried for sub-level data. 
With JavaScript and the XMLhttp object this data can be requested from the server
an transformed into html code to display all the nested items.&lt;/p&gt;


&lt;h3&gt;1. Defining a contract&lt;/h3&gt;

&lt;p&gt;The AJAX control, after beeing loaded will use a WebService for retrieving
the list of sub-nodes (folders and files) from a given node (the user clicks).
A WebService that can be used for this purpose has a very simple interface with
only a single method. The parameter is used with a key that uniquely defines
a already known folder node and the return value is a structure with the folders
and files under that node.&lt;/p&gt;

&lt;p&gt;The unique key of a node can be described by a path string and the return value 
is typed as a  XML document:&lt;/p&gt;

&lt;pre class="code"&gt;[WebMethod]
public XmlDocument GetSubNodes(string path);&lt;/pre&gt;

&lt;p&gt;Every folder and every file must have a name that must be unique among the subnodes 
of a folder ans we can concatinate these names as we usually do for filesystems
to get a overall unique identifying string.&lt;/p&gt;

&lt;p&gt;The returned XML has the form:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;folder&amp;gt;
  &amp;lt;folder name="[name of the folder]" title="[some more text]" /&amp;gt;
  &amp;lt;file name="[name of a file]" title="[some more text]" /&amp;gt;
&amp;lt;/folder&amp;gt;&lt;/pre&gt;

&lt;p&gt;There can be as multiple files and folders in any order.&lt;/p&gt;

&lt;h3&gt;2. Implementing a WebService&lt;/h3&gt;

The WebService implementation we need is very simple. I've published a version that
loads a XML file and uses this data source.


&lt;h3&gt;3. Javascript and HTML: building a tree layout&lt;/h3&gt;

&lt;p&gt;There are many &amp;lt;table&amp;gt; - based sample implementations for tree structures on the web.
I use a very simple approach here that works fine but supports the indenting of subnodes,
but no lines in front of the icons that uses &amp;lt;div&amp;gt;-elements.
Here is the basic structure of a folder with the container of the subnodes:&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;div class="du" name="foldername"&amp;gt;&amp;lt;span class="ft"&amp;gt;foldertitle&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class="subframe"&amp;gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;The click event is captured at the root level and has to do the following things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;identify the clicked folder object (&amp;lt;div&amp;gt; with class=[do|dc|de|du])&lt;/li&gt;
&lt;li&gt;hiding (do) or showing (dc) the container with the subnodes&lt;/li&gt;
&lt;li&gt;or starting an AJAX action (du) that loads the subnodes&lt;/li&gt;
&lt;/ul&gt;



&lt;h3&gt;4. the AJAX action&lt;/h3&gt;

&lt;p&gt;The context parameter of the only ajax action we need is the node of the folder
with the still unkown subnodes.&lt;/p&gt;
&lt;p&gt;The prepare function builds the path string for this folder.&lt;/p&gt;
&lt;p&gt;The asynchronous call will return the xml document that is passed to the finish method.&lt;/p&gt;
&lt;p&gt;In the finish method we transform the returned xml document into the html wee need by using
a simple xslt transformation that can be found inline in the file of the page.&lt;/p&gt; 

&lt;p&gt;All we have to code for that is an AJAX Action: &lt;/p&gt;

&lt;pre class="code"&gt;  // Retrieve the sub-nodes of a given folder.
  ExploreAction: {
    delay: 10,
    queueMultiple: true,

    prepare:
      function(src) { 
        var path = "";
        var root = jcl.FindBehaviourElement(src, TreeViewBehaviour);
        while ((src != null) &amp;amp;&amp;amp; (src != root)) {
          if (src.className == "subframe") {
            src = src.previousSibling;
          } else if (src.className == "do") {
            path = "/" + src.name + path;
            src = src.parentNode;
          }
        }
        while (path.substr(0,2) == "//")
          path = path.substr(1);
        return (path);
      },

    call: "proxies.TreeView.GetSubNodes",

    finish:
     function(data, src) {
       jcl.FindBehaviourElement(src, TreeViewBehaviour).ExtendTree(src, data);
     },
    
    onException: proxies.alertException
  }, // FetchAction&lt;/pre&gt;

&lt;p&gt;That's still a lot of code, so we build a Control to get that
coding off from our daily work by implementing a control.&lt;/p&gt;


&lt;h3&gt;5. the AJAX control&lt;/h3&gt;

&lt;p&gt;All the coding up to here should be covered by the AJAX Control so the developer
only adds this control with the following attributes:&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;ajax:TreeView runat="server" title="Cities of USA" service="WebServiceAlias" /&amp;gt;&lt;/pre&gt;

&lt;p&gt;The &lt;i&gt;title&lt;/i&gt; attribute is the label shown on the root folder.&lt;/p&gt;
&lt;p&gt;The &lt;i&gt;service&lt;/i&gt; attribute is the alias name of the web service that serves the data of the tree&lt;/p&gt;

&lt;p&gt;The complete implementation can be found in the 2 files that build the AJAX Control and the
JavaScript behaviour: TreeView.ascx and TreeView.js that can be found in the controls folder.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113632351033238868?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113632351033238868/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113632351033238868' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113632351033238868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113632351033238868'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2006/01/tree-view-ajax-control.html' title='Tree View AJAX Control'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113589236265763080</id><published>2005-12-29T22:38:00.000+01:00</published><updated>2006-01-05T22:29:19.130+01:00</updated><title type='text'>An AJAX enabled bible reader</title><content type='html'>&lt;h2&gt;Handbook&lt;/h2&gt;

&lt;p&gt;This is a small documentation for the online available Bible Reader at &lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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...".&lt;/p&gt;

&lt;p&gt;You can select one of the server-side installed bibles by using the first select box:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;sf_kjv_strongs_rev1b:&lt;/td&gt;&lt;td&gt;A English version of the bible.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;en_gb_KJV2000_1:&lt;/td&gt;&lt;td&gt;A more modern English version of the bible.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;luther1912:&lt;/td&gt;&lt;td&gt;A German version of the bible.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;biblehebr:&lt;/td&gt;&lt;td&gt;a Hebrew version of the bible.&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

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

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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...&lt;/p&gt;

&lt;p&gt;In the big text box below the text of the selected verse will be shown.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Below the text boxes are 2 buttons that enables the forward and backward navigation cross all 
book and chapter boundaries in a given version.&lt;/p&gt;

&lt;p&gt;You navigate across multiple 5 MByte sized books. Fast !&lt;/p&gt;

&lt;h2&gt;Technology&lt;/h2&gt;

&lt;p&gt;The published web page available at
&lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx&lt;/a&gt;
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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;Cascading Select Elements&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Here, the AJAX Select box control is used together with a AJAX action and some JavaScript code. The chapter select box is defined by&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;ajax:Select id="ChapterSelect" runat="server" pageproperty="chapter" style="width: 120px"&amp;gt;
&amp;lt;/ajax:Select&amp;gt;&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;script defer="defer" type="text/javascript"&amp;gt;
  var obj = document.getElementById("ChapterSelect");
  obj.GetValue = function(prop, value) {
    if (((prop == "version") || (prop == "book")) &amp;amp;&amp;amp; (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
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;Very similar scripts can be found for the other 2 cascaded select boxes.&lt;/p&gt;

&lt;h3&gt;Retrieving the Vers Text&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;pre class="code"&gt;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&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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: &lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BibleData.asmx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BibleData.asmx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Programming AJAX Web Applications can be easy and without a lot of source code if you choose the right technology and level of programming. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113589236265763080?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113589236265763080/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113589236265763080' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113589236265763080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113589236265763080'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/12/ajax-enabled-bible-reader.html' title='An AJAX enabled bible reader'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113511375057856688</id><published>2005-12-20T21:56:00.000+01:00</published><updated>2005-12-20T22:22:30.630+01:00</updated><title type='text'>Powerpoint Slides on AJAX</title><content type='html'>&lt;p&gt;I had to give a speech at the Karlsruher Software Council about AJAX some days ago.&lt;/p&gt;
&lt;p&gt;Now I've posted the Powerpoint slides titled "AJAX – Hype and Reality" on my site at &lt;a href="http://www.mathertel.de/AJAX/AJAXVortrag20051123.ppt"&gt;PowerPoint Slides on AJAX&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Maybe you find the slides useful.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113511375057856688?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113511375057856688/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113511375057856688' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113511375057856688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113511375057856688'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/12/powerpoint-slides-on-ajax.html' title='Powerpoint Slides on AJAX'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113473520256649308</id><published>2005-12-15T22:12:00.000+01:00</published><updated>2006-01-05T22:31:27.670+01:00</updated><title type='text'>JavaScript Proxies for WebServices extended</title><content type='html'>&lt;p&gt;
I updated the bits on the &lt;a href="http://www.mathertel.de/AJAXEngine"&gt;AJAX Engine&lt;/a&gt; site some days ago. There are some new features I want to let you know:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;There is now a new &lt;a href="http://www.mathertel.de/Sitemap.aspx"&gt;sitemap&lt;/a&gt; available for the whole site. You can find the link on the home page at &lt;a href="http://www.mathertel.de"&gt;http://www.mathertel.de&lt;/a&gt; on the left side. It's very easy now to discover all the posted source code files.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113473520256649308?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113473520256649308/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113473520256649308' title='5 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113473520256649308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113473520256649308'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/12/javascript-proxies-for-webservices.html' title='JavaScript Proxies for WebServices extended'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113187715436702651</id><published>2005-11-16T00:03:00.000+01:00</published><updated>2005-12-03T13:45:58.550+01:00</updated><title type='text'>Moving the server</title><content type='html'>&lt;p&gt;&lt;span style="FONT-WEIGHT: bold;color:red;" &gt;Update you favorites !&lt;/span style="font-size:+0;"&gt; (and I hope that my AJAX project is part of them)&lt;/p&gt;

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

&lt;p&gt;I decided to move my personal domain &lt;a href="http://www.mathertel.de/AJAXEngine" &gt;http://www.mathertel.de/AJAXEngine&lt;/a&gt;that moved to a ASP.NET 2.0 enabled host so I can put both sides together.&lt;/p&gt;
&lt;p&gt;If you have saved a link to the AJAX Demo WebSite you should update this link.&lt;/p&gt;

&lt;p&gt;You can find the new samples at &lt;a href="http://www.mathertel.de/AJAXEngine"&gt;http://www.mathertel.de/AJAXEngine&lt;/a&gt; and the documentations at &lt;a href="http://www.mathertel.de/AJAX"&gt;http://www.mathertel.de/AJAX&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Stay tuned.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113187715436702651?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113187715436702651/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113187715436702651' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113187715436702651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113187715436702651'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/11/moving-server.html' title='Moving the server'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113187600355909258</id><published>2005-11-13T20:53:00.000+01:00</published><updated>2005-11-30T20:44:06.486+01:00</updated><title type='text'>Tuning TableData</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;Speed&lt;/h3&gt;

&lt;p&gt;The first version (&lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TableData1.aspx"&gt;still available here&lt;/a&gt;) 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.

&lt;h3&gt;FireFox compatibility&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;I fixed some minor things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The parentElement attribute of the html dom should not be used. Use parentNode instead.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;The onscroll event it is not documented but works as expected in FireFox. Great !&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Reusability&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113187600355909258?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113187600355909258/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113187600355909258' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113187600355909258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113187600355909258'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/11/tuning-tabledata.html' title='Tuning TableData'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-113174597586190386</id><published>2005-11-11T22:49:00.000+01:00</published><updated>2005-11-30T20:45:36.746+01:00</updated><title type='text'>Displaying huge tables using AJAX</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;In fact it's a 3 steps approach:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;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. &lt;/li&gt;
  &lt;li&gt;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. &lt;/li&gt;
  &lt;li&gt;Then every row that is visible is fetched from the server using another WebService call that returns
    a XML document for each row. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Give it a try and check out the sample implementation at: &lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TableData.aspx"&gt;
http://www.mathertel.de/AjaxEngine/S03_AJAXControls/TableData.aspx&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The implementation consists of a WebService, 2 Web Controls and the AJAX Engine that does the asynchronous
  communication and the caching.&lt;/p&gt;
&lt;h3&gt;DataTablePager Control &lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;There are some methods available that can be used by additional buttons to load a specific view or
  to clear the actual data.&lt;/p&gt;

&lt;p&gt;Buttons can use these functions to select rows by supplying a filter and a sorting criteria.&lt;/p&gt;

&lt;p&gt;The events that are triggered by scrolling the table also use methods of this control to fetch data
  from the server.&lt;/p&gt;

&lt;h3&gt;DataTable Control&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Every time a row gets visible a fetching the data is initiated by calling the DataTablePager Control's
  FetchRow Method.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;The TableData WebService&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-113174597586190386?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/113174597586190386/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=113174597586190386' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113174597586190386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/113174597586190386'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/11/displaying-huge-tables-using-ajax.html' title='Displaying huge tables using AJAX'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112922889189508548</id><published>2005-10-13T20:41:00.000+02:00</published><updated>2005-11-30T20:47:01.303+01:00</updated><title type='text'>CustomValidation AJAX Control Sample</title><content type='html'>&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the form data is sent back to the server a specific server-side functionality of the control or the page is called.&lt;/li&gt;
&lt;li&gt;When the user changes the value of a field and leaves the field a specific client-side function is called.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;When the user changes the value of a field and leaves the field a specific WebService can check the value.&lt;/p&gt;
&lt;p&gt;The implementation is obvious.&lt;/p&gt;
&lt;p&gt;1. We use the built-in CustomValidator control to attach a client side function:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;input autocomplete="off" id="EMAIL_IN" runat="server" name="EMAIL" /&amp;gt;
&amp;lt;asp:CustomValidator ID="CustomValidator1" runat="server"
  ControlToValidate="EMAIL_IN"
  ErrorMessage="Please enter a valid e-mail address." 
  ClientValidationFunction="validateEMail"&amp;gt;*&amp;lt;/asp:CustomValidator&amp;gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code"&gt;function validateEMail(source, arguments) {
  ajax.Start(validateAction, source);
} // validateEMail&lt;/pre&gt;

&lt;p&gt;3. The AJAX action needs to be declared and is based on some implementation details of the client-side validation mechanism:&lt;/p&gt;
&lt;pre class="code"&gt;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&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The sample can be found at
&lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/ValidatorDemo.aspx"&gt;http://www.mathertel.de/AjaxEngine/S03_AJAXControls/ValidatorDemo.aspx&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112922889189508548?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112922889189508548/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112922889189508548' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112922889189508548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112922889189508548'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/10/customvalidation-ajax-control-sample.html' title='CustomValidation AJAX Control Sample'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112834771033905814</id><published>2005-10-03T15:54:00.000+02:00</published><updated>2005-11-30T20:48:43.906+01:00</updated><title type='text'>Using AJAX enabled controls in ASP.NET Forms</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Validate values immediately on the server after the user exits the field without reloading the form.&lt;/li&gt;
  &lt;li&gt;Help the user to find the right value by extending a field with a specific lookup function.&lt;/li&gt;
  &lt;li&gt;Show or hide a field, depending of already entered values.&lt;/li&gt;
  &lt;li&gt;Fill fields in the form, depending of already entered values.&lt;/li&gt;
  &lt;li&gt;Fill the OPTIONS of HTML SELECT elements depending of already entered values.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;On the sample website to this Blog at &lt;a href="http://www.mathertel.de/AjaxEngine/Default.aspx"&gt;
  http://www.mathertel.de/AjaxEngine/Default.aspx&lt;/a&gt; you can find some samples that show
  the usage of AJAX based functionality in regular Web Form applications:&lt;/p&gt;
&lt;h3&gt;Validator Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ValidatorDemo.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ValidatorDemo.aspx&lt;/a&gt;
  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.&lt;/p&gt;
&lt;h3&gt;Bible Reader&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx"&gt;http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx&lt;/a&gt;
  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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112834771033905814?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112834771033905814/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112834771033905814' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112834771033905814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112834771033905814'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/10/using-ajax-enabled-controls-in-aspnet.html' title='Using AJAX enabled controls in ASP.NET Forms'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112715616992085748</id><published>2005-09-19T20:55:00.000+02:00</published><updated>2005-11-30T20:49:56.670+01:00</updated><title type='text'>Connecting Controls</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;The classical approach&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.. &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;The WebPart approach&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;There are some advantages for this approach:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It works even if the controls that build up a page are not known at compile-time. (Sharepoint)&lt;/li&gt;
  &lt;li&gt;Multiple controls can easily publish the same property.&lt;/li&gt;
  &lt;li&gt;Multiple controls can easily consume the same property.&lt;/li&gt;
  &lt;li&gt;We do not need any browser- or object-specific events.&lt;/li&gt;
  &lt;li&gt;The IDs of the objects must not be known.&lt;/li&gt;
&lt;/ul&gt;
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.
&lt;h2&gt;The Connection Test Sample&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;See: &lt;a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ConnectionsTestPage.aspx"&gt;
  http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ConnectionsTestPage.aspx&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;PropInput Control &lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;This control also registers itself as a consumer to display the actual value when changed by another
  control.&lt;/p&gt;
&lt;h3&gt;PropHSlider&lt;/h3&gt;
&lt;h3&gt;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.&lt;/h3&gt;
&lt;h3&gt;This control also registers itself as a consumer to display the actual value when changed by another
  control.&lt;/h3&gt;
&lt;h3&gt;PropBarChart&lt;/h3&gt;
&lt;p&gt;This control implements a simple bar chart to display multiple values. The names of the properties
  are displayed below the bars.&lt;/p&gt;
&lt;p&gt;The names of the values can be specified by the "properties" attribute by using a semicolon separated
  list of names.&lt;/p&gt;
&lt;p&gt;The max displayable number can be specified by the "maxvalue" attribute. This value is used as a scale
  factor for the display.&lt;/p&gt;
&lt;h3&gt;PropEventLog&lt;/h3&gt;
&lt;p&gt;This control logs every change of any property and lists the new value on the page.&lt;/p&gt;
&lt;h2&gt;DataConnections Reference&lt;/h2&gt;
&lt;p&gt;The names of the properties are always converted to lowercase characters so they should only be compared
  by after a toLowercase conversion.&lt;/p&gt;
&lt;h3&gt;DataConnections.RegisterProvider(obj, propName)&lt;/h3&gt;
&lt;p&gt;An object that provides a property must register itself using this function.&lt;/p&gt;
&lt;p&gt;The name of the property set to a '*'-character to register for all existing properties.&lt;/p&gt;
&lt;h3&gt;DataConnections.RegisterConsumer(obj, propName)&lt;/h3&gt;
&lt;p&gt;An object that wants to be informed about the values of a property must register itself using this
  function.&lt;/p&gt;
&lt;p&gt;The name of the property can be specified by a star-character to register for any properties that exist
  on the page.&lt;/p&gt;
&lt;h3&gt;DataConnections.Raise(propName, propValue)&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;DataConnections.GetPropValue(propName)&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;DataConnections.PersistPropValue(propName)&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The used cookie is not a permanent cookie so the content will be not available after the browser was
  closed.&lt;/p&gt;
&lt;h3&gt;control.GetValue(propName, propValue)&lt;/h3&gt;
&lt;p&gt;This function must be implemented by a control to receive the notification changes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112715616992085748?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112715616992085748/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112715616992085748' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112715616992085748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112715616992085748'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/09/connecting-controls.html' title='Connecting Controls'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112685463342161508</id><published>2005-09-16T09:03:00.000+02:00</published><updated>2007-06-10T17:15:31.269+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Anatomy of an AJAX Control</title><content type='html'>&lt;img height="293" alt="AJAX Web Control architecture" src="http://www.mathertel.de/AJAX/Images/Usercontrol.png" width="533" border="0" /&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;You should be familiar with the technique of the &lt;a href="http://ajaxaspects.blogspot.com/2005/08/javascript-behaviours.html"&gt;&amp;lt;ajax:Lookup ... LookUpService="OrteLookup" ... /&amp;gt;&lt;/p&gt;&lt;/a&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;%@ Control Language="C#" ... %&amp;gt;
&amp;lt;script runat="server"&amp;gt;
  public string lookupservice = "DefaultService.asmx";
  ...
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;input ... lookupservice="&amp;lt;%=this.lookupservice %&amp;gt;" ... /&amp;gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Be sure to also add the unique id of the control into the generated HTML code:&lt;/p&gt;
&lt;pre class="code"&gt;id="&amp;lt;%=this.UniqueID %&amp;gt;"&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;If you need a reference to another web resource you can use the ResolveUrl method of the Page object:&lt;/p&gt;
&lt;pre class="code"&gt;src="&amp;lt;%=Page.ResolveUrl("~/controls/images/drop.gif") %&amp;gt;"&lt;/pre&gt;
&lt;h3&gt;Programming the Behaviour&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;I use the same name as the *.ascx file for this control specific include file and place them all into
the ~/controls folder.&lt;/p&gt;
&lt;p&gt;To attach the behaviour to the html object a small JavaScript fragment is also part of the rendered
HTML code:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt; script defer="defer" type="text/javascript"&amp;gt;
  jcl.LoadBehaviour("&amp;lt;%=this.UniqueID %&amp;gt;", LookUpBehaviour);
&amp;lt;/script &amp;gt;&lt;/pre&gt;
&lt;h3&gt;AJAX Actions&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code"&gt;// 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&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code"&gt;this._fillAction = jcl.CloneObject(this._fillAction);
this._fillAction.call = proxies[this.lookupservice].GetPrefixedEntries;&lt;/pre&gt;
&lt;h3&gt;Registering the script includes&lt;/h3&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre class="code"&gt;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("&amp;lt;script type='text/javascript' src='"
      + Page.ResolveUrl("~/controls/jcl.js")
      + "'&amp;gt;&amp;lt;" + "/script&amp;gt;\n"));
  } // if

  if (!Page.ClientScript.IsClientScriptBlockRegistered(this.GetType(), "MyBehaviour")) {
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyBehaviour", String.Empty);
    ((HtmlHead)Page.Header).Controls.Add(new LiteralControl("&amp;lt;script type='text/javascript' src='"
      + Page.ResolveUrl("~/controls/LookUp.js")
      + "'&amp;gt;&amp;lt;" + "/script&amp;gt;\n"));
  } // if
} // OnPreRender&lt;/pre&gt;
p&gt;All the code fragments can be found in the &lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/Default.aspx"&gt;
third part of the samples&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/AjaxEngine/S03_AJAXControls/OrteLookUp.aspx"&gt;OrteLookUp.aspx&lt;/a&gt;
is the implementation of the page,&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/AjaxEngine/ViewSrc.aspx?file=controls/LookUp.ascx"&gt;~/controls/LookUp.ascx&lt;/a&gt;
is the first visible control and&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/AjaxEngine/ViewSrc.aspx?file=controls/LookUp.js"&gt;~/controls/LookUp.js&lt;/a&gt;
is the corresponding JavaScript Behaviour.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112685463342161508?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112685463342161508/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112685463342161508' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112685463342161508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112685463342161508'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/09/anatomy-of-ajax-control.html' title='Anatomy of an AJAX Control'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112672626328437127</id><published>2005-09-14T21:30:00.000+02:00</published><updated>2005-09-14T21:31:03.290+02:00</updated><title type='text'>AJAX Engine documentation update</title><content type='html'>&lt;p&gt;Today I updated the documentation of the AJAX Engine.&lt;/p&gt;
&lt;p&gt;See &lt;a href="http://www.mathertel.de/AJAX/Aspects%20of%20AJAX_index.htm"&gt;http://www.mathertel.de/AJAX/Aspects%20of%20AJAX_index.htm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s not necessary any more to read the articles from the end to the beginning because they layer upon each other partially.&lt;/p&gt;
&lt;h3&gt;ATLAS&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;They use a JSON syntax and not SOAP or WSDL for the communications so it’s not very portable to other server-side platforms.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112672626328437127?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112672626328437127/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112672626328437127' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112672626328437127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112672626328437127'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/09/ajax-engine-documentation-update.html' title='AJAX Engine documentation update'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112663927940639689</id><published>2005-09-13T21:20:00.000+02:00</published><updated>2005-09-13T21:22:57.213+02:00</updated><title type='text'>Using ASP.NET</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;User Controls&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Web Controls&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;No Form element&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;The Return key&lt;/h3&gt;
&lt;p&gt;One thing will disturb users when a form element is present: pressing the
  &lt;return&gt; or &lt;enter&gt;
  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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Common JavaScript&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Registering Script includes&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;With "IsClientScriptBlockRegistered" it is possible to check if a include file is already registered.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code" lang="cs"&gt;Page.RegisterClientScriptBlock("CommonBehaviour",
  "&amp;lt;script type='text/javascript' src='"
  + Page.ResolveUrl("~/controls/jcl.js 
  + "'&amp;gt;&amp;lt;" + "/script&amp;gt;\n"));&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Registering Script includes without a form element&lt;/h3&gt;
&lt;p&gt;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".&lt;/p&gt;
&lt;pre class="code" lang="cs"&gt;// 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("&amp;lt;script type='text/javascript' src='"
    + Page.ResolveUrl("~/controls/jcl.js ")
    + "'&amp;gt;&amp;lt;" + "/script&amp;gt;\n"));
} // if&lt;/pre&gt;
&lt;p&gt;Using this trick, it makes no difference whether a HTML form element exists in the page or not. &lt;/p&gt;
&lt;h3&gt;Samples and Downloads&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112663927940639689?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112663927940639689/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112663927940639689' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112663927940639689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112663927940639689'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/09/using-aspnet.html' title='Using ASP.NET'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112599988679565797</id><published>2005-09-06T11:44:00.000+02:00</published><updated>2005-09-06T11:44:46.803+02:00</updated><title type='text'>Caching with AJAX applications</title><content type='html'>&lt;p&gt;AJAX applications offer better response times and are faster (or at least seems
  to be faster) that traditional web applications.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Caching the initial page download&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Also http://msdn.microsoft.com/library/default.asp?url=/workshop/author/perf/perftips.asp
  is worth reading.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;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.&lt;/li&gt;
  &lt;li&gt;The page MUST be designed to be a (almost) static resource from the view of the
    client.&lt;br /&gt;
    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.&lt;/li&gt;
  &lt;li&gt;The smaller, the faster.&lt;br /&gt;
    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.&lt;/li&gt;
  &lt;li&gt;Use include files for JavaScript and CSS-files.&lt;br /&gt;
    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.&lt;/li&gt;
  &lt;li&gt;Use only lowercase character in URLs.&lt;br /&gt;
    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.&lt;/li&gt;
  &lt;li&gt;Use the right http headers.&lt;br /&gt;
    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.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Caching the asynchronous requests&lt;/h3&gt;
&lt;p&gt;After the page is loaded there are more requests to the server now by using asynchronous
  calls in the background using the XmlHttpRequest objects.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code"&gt;[WebMethod(CacheDuration=60)]&lt;/pre&gt;
&lt;p&gt;A simple sample on this can be found in the article at: http://support.microsoft.com/default.aspx?scid=kb;en-us;318299&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre class="code"&gt;proxies.EnableCache(proxies.CalcService.CalcPrimeFactors)&lt;/pre&gt;
&lt;p&gt;Also the TableData.aspx sample uses caching to prevent retrieving the same records
  multiple times.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;This is not a perfect solution, but it works under the following circumstances:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The parameter must be a string or number that can be used for indexing the properties
    of a JavaScript object.&lt;/li&gt;
  &lt;li&gt;The cache doesn’t clear itself. It can be cleared by calling EnableCache once
    again.&lt;/li&gt;
  &lt;li&gt;Only methods with a single parameter are supported.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Caching works good into AJAX applications and speeds up by preventing calculations,
  downloads and webserver calls.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112599988679565797?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112599988679565797/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112599988679565797' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112599988679565797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112599988679565797'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/09/caching-with-ajax-applications.html' title='Caching with AJAX applications'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112559349377752434</id><published>2005-09-01T18:49:00.000+02:00</published><updated>2006-02-05T17:14:09.126+01:00</updated><title type='text'>Project Site Update</title><content type='html'>&lt;p&gt;This was a long week, not writing text but code. I updated the AJAX Aspects project side &lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;http://www.mathertel.de/AJAXEngine/&lt;/a&gt; and I hope you find it more useful. It got more structure and there is now a good place to start the next steps.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;I separated the pre-AJAX samples (part 1) from the AJAX samples (part 2). Old links might not work any more.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope you like it :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112559349377752434?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112559349377752434/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112559349377752434' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112559349377752434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112559349377752434'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/09/project-site-update.html' title='Project Site Update'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112474698773735187</id><published>2005-08-22T23:42:00.000+02:00</published><updated>2007-06-10T17:15:03.356+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Behaviors'/><category scheme='http://www.blogger.com/atom/ns#' term='components'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>JavaScript Behaviours</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;General&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Proprietary behaviours&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Lightweight, compatible behaviours&lt;/h3&gt;
&lt;p&gt;Building a cross-browser functionality that is very similar to the built-in behaviours
  of the browsers is not very hard to do.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;A simple example&lt;/h3&gt;
&lt;p&gt;This is the HTML object&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;div id="TimerSample" style="..."&amp;gt;click here&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre class="code"&gt;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&lt;/pre&gt;
&lt;p&gt;The behaviour functionality must be bound to the HTML object by calling one method
  only:&lt;/p&gt;
&lt;pre class="code"&gt;LoadBehaviour(document.getElementById("TimerSample"), TimerSampleBehaviour);&lt;/pre&gt;
&lt;p&gt;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.:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;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.&lt;/li&gt;
  &lt;li&gt;Other methods are just bound to the HTML object as function objects.&lt;/li&gt;
  &lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We might expect more functionality from behaviours but this is a set of functionalities
  that are available in all the supported browsers.&lt;/p&gt;
&lt;p&gt;This simple sample can be found on the sample website: &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;http://www.mathertel.de/AJAXEngine/&lt;/a&gt; in Samples Part 2.&lt;/p&gt;
&lt;p&gt;The relevant code can be found in the html page itself and in the include file
  cb.js.&lt;/p&gt;
&lt;h3&gt;Writing event handlers&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre class="code"&gt;evt = evt || window.event; // get a compatible event object&lt;/pre&gt;
&lt;p&gt;The clicked HTML object is available by using the srcElement property of the event
  object.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Writing methods&lt;/h3&gt;
&lt;p&gt;Writing a method for a behaviour is as simple as writing compatible JavaScript.&lt;/p&gt;
&lt;p&gt;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".&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Defining default values&lt;/h3&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;An attribute can be set on the HTML object&lt;/li&gt;
  &lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;The init method&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;p&gt;The Mozilla/Firefox behaviours: &lt;a href="http://www.mozilla.org/projects/xbl/xbl.html"&gt;
  http://www.mozilla.org/projects/xbl/xbl.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The IE behaviours: &lt;a href="http://msdn.microsoft.com/workshop/components/htc/reference/htcref.asp"&gt;
  http://msdn.microsoft.com/workshop/components/htc/reference/htcref.asp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Search for behaviours using Google: &lt;a href="http://www.google.com/search?q=htc+filetype%3Ahtc"&gt;
  http://www.google.com/search?q=htc+filetype%3Ahtc&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112474698773735187?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112474698773735187/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112474698773735187' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112474698773735187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112474698773735187'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/08/javascript-behaviours.html' title='JavaScript Behaviours'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112462480729789184</id><published>2005-08-21T13:46:00.000+02:00</published><updated>2005-08-21T13:46:47.306+02:00</updated><title type='text'>Application Aspects</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Integration of AJAX components&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;AJAX controls&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;To reach a high percentage of reusability those components are realized outside of the individual pages and are parameterized for their concrete usage.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;ASP.NET and AJAX controls&lt;/h3&gt;
&lt;p&gt;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&lt;/p&gt;
&lt;p&gt;Building a complete new framework is not my intention because there are already some very useful frameworks that permit building component-based web applications. &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The advantage of ASP.NET is beside that is the simple realization of Web services.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112462480729789184?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112462480729789184/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112462480729789184' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112462480729789184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112462480729789184'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/08/application-aspects.html' title='Application Aspects'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112379131492783794</id><published>2005-08-11T22:10:00.000+02:00</published><updated>2005-08-11T22:15:14.936+02:00</updated><title type='text'>Model View Controller (MVC) Pattern</title><content type='html'>&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  Sometimes those thoughts exceed this range and lead into almost religious discussions
  about holy principles.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  Here I want to look and analyze the existing AJAX Engine and not build a ideal optimal
  AJAX architecture.&lt;/p&gt;
&lt;h3&gt;Definition of MVC&lt;/h3&gt;
&lt;p&gt;
  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: &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;
    http://en.wikipedia.org/wiki/Model-view-controller&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Model: This is the domain-specific representation of the information (data and
    methods) on which the application operates. &lt;/li&gt;
  &lt;li&gt;View: This renders the model into a form suitable for interaction, typically a
    user interface element. &lt;/li&gt;
  &lt;li&gt;Controller: This responds to events, typically user actions, and invokes changes
    on the model or view as appropriate.&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Model&lt;/h3&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Independent of HTML objects &lt;/li&gt;
  &lt;li&gt;No culture or language specific implementations &lt;/li&gt;
  &lt;li&gt;Manipulating and storing data &lt;/li&gt;
  &lt;li&gt;Stateless &lt;/li&gt;
  &lt;li&gt;Checking and securing of the parameters of the webmethods. &lt;/li&gt;
  &lt;li&gt;Reliable algorithms and functionalities&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;View&lt;/h3&gt;
&lt;p&gt;
  The View part can be localized in the realization of the User Interface by using
  HTML objects and some supplement JavaScript methods.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;UI Events &lt;/li&gt;
  &lt;li&gt;Active elements like input fields &lt;/li&gt;
  &lt;li&gt;Layout elements and decorative additions &lt;/li&gt;
  &lt;li&gt;Converting of numbers and date formats to strings &lt;/li&gt;
  &lt;li&gt;Methods to support the working&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Controller&lt;/h3&gt;
&lt;p&gt;
  But where is the Controller part in a AJAX application and how does it work ?&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;h3&gt;Page Controller&lt;/h3&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  Struts mixes up both aspects what may end in complex struts-config.xml files.&lt;/p&gt;
&lt;p&gt;
  Both approaches for realizing web applications are described and compared regarding
  the MVC pattern in &lt;a href="http://msdn.microsoft.com/library/en-us/dnaspp/html/ASPNet-ASPNet-J2EE-Struts.asp"&gt;
    http://msdn.microsoft.com/library/en-us/dnaspp/html/ASPNet-ASPNet-J2EE-Struts.asp&lt;/a&gt;
  as well as in &lt;a href="http://struts.apache.org/userGuide/building_controller.html"&gt;
    http://struts.apache.org/userGuide/building_controller.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112379131492783794?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112379131492783794/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112379131492783794' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112379131492783794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112379131492783794'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/08/model-view-controller-mvc-pattern.html' title='Model View Controller (MVC) Pattern'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112273893317090334</id><published>2005-07-30T17:54:00.000+02:00</published><updated>2005-07-30T17:55:33.176+02:00</updated><title type='text'>Extensions to the proxy generator</title><content type='html'>&lt;p&gt;
  With Version 2.0 there is now more support for different datatypes.&lt;/p&gt;
&lt;h3&gt;
  Simple data types&lt;/h3&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;pre class="code"&gt;proxies.CalcService.AddDouble.params = ["number1:float","number2:float"];
proxies.CalcService.AddDouble.rtype = ["AddDoubleResult:float"];&lt;/pre&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;h3&gt;
  XML data&lt;/h3&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  A Method has to be is declared in C# like this:&lt;/p&gt;
&lt;pre class="code"&gt;[WebMethod()]
public XmlDocument Calc(XmlDocument xDoc) {
...
return (xDoc);
} // Calc&lt;/pre&gt;
&lt;p&gt;
  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" &amp;lt;? ... ?&amp;gt;.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;table id="TABLE1" class="DICTIONARY"&gt;
  &lt;caption&gt;
    Supported Datatypes&lt;/caption&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;td&gt;XML data type&lt;/td&gt;
      &lt;td&gt;Alias in the proxy&lt;/td&gt;
      &lt;td&gt;JavaScript data taype&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;string &lt;/td&gt;
      &lt;td&gt;string / null &lt;/td&gt;
      &lt;td&gt;String &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;int, unsignedInt,&lt;br /&gt;
        short, unsignedShort,&lt;br /&gt;
        unsignedLong,s:long &lt;/td&gt;
      &lt;td&gt;int &lt;/td&gt;
      &lt;td&gt;Number, (parseInt) &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;double, float &lt;/td&gt;
      &lt;td&gt;float &lt;/td&gt;
      &lt;td&gt;Number, (parseFloat) &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dateTime' &lt;/td&gt;
      &lt;td&gt;date &lt;/td&gt;
      &lt;td&gt;Date &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;boolean &lt;/td&gt;
      &lt;td&gt;bool &lt;/td&gt;
      &lt;td&gt;Boolean &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;In Mozilla / Firefox:&lt;br /&gt;
        XMLDocument&lt;br /&gt;
        Im Internet Explorer:&lt;br /&gt;
        ActiveXObject("Microsoft.XMLDOM")&lt;br /&gt;
        ActiveXObject("MSXML2.DOMDocument") &lt;/td&gt;
      &lt;td&gt;x &lt;/td&gt;
      &lt;td&gt;System.Xml.XmlDocument &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112273893317090334?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112273893317090334/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112273893317090334' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112273893317090334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112273893317090334'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/extensions-to-proxy-generator.html' title='Extensions to the proxy generator'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112258231313298555</id><published>2005-07-28T22:24:00.000+02:00</published><updated>2005-07-28T22:25:13.140+02:00</updated><title type='text'>Sample for AJAX Forms</title><content type='html'>&lt;p&gt;
  This sample implements the processing of data of a form using the AJAX engine and
  the AJAX Forms.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;script type="text/javascript" src="ajaxForms.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;
  The connection to the corresponding WebService is done by using the proxy generator:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;script type="text/javascript" src="GetJavaScriptProxy.aspx?service=_Kreditcalc.asmx"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;h3&gt;
  Exceptions&lt;/h3&gt;
&lt;p&gt;
  The function ajaxForms.processException can be used to handle and display the exceptions
  that occur within validating the passed data.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  This name is then passed to the client using an exception return package.&lt;/p&gt;
&lt;p&gt;
  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:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;span class="AJAXFORMEXCEPTION" name="LOAN"&amp;gt;&amp;lt;/span&amp;gt;&lt;/pre&gt;
&lt;h3&gt;
  The Form&lt;/h3&gt;
&lt;p&gt;
  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:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;input id="loan" name="LOAN" value="100000"&amp;gt;
  ...
&amp;lt;input name="MONTHLYREPAY" disabled="disabled"&amp;gt;&lt;/pre&gt;
&lt;h3&gt;
  The Actions&lt;/h3&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  The first action uses the functions getData und setData from ajaxForms.js and needs
  no further programming.
&lt;/p&gt;
&lt;pre class="code"&gt;// declare an AJAX action
var action1 = {
  delay: 200,
  prepare: ajaxForms.getData,
  call: proxies.KreditCalc.Calc,
  finish: ajaxForms.setData,
  onException: ajaxForms.processException
} // action1&lt;/pre&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;pre class="code"&gt;
var action2 = {
  name: "Amortization",
  delay: 800,
  prepare: ajaxForms.getData,
  call: proxies.KreditCalc.Amortization,
  finish: displayAmortization,
  onException: proxies.alertException
} // action2&lt;/pre&gt;
&lt;h3&gt;
  Starting the actions&lt;/h3&gt;
&lt;p&gt;
  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.&lt;/p&gt;
&lt;p&gt;
  The second parameter on starting the actions is used to reference the AJAX form.&lt;/p&gt;
&lt;pre class="code"&gt;onkeyup="ajax.Start(action1, 'frm');ajax.Start(action2, 'frm')"&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112258231313298555?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112258231313298555/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112258231313298555' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112258231313298555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112258231313298555'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/sample-for-ajax-forms.html' title='Sample for AJAX Forms'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112248392455116982</id><published>2005-07-27T20:09:00.000+02:00</published><updated>2005-07-27T19:05:24.556+02:00</updated><title type='text'>A lookup example for city names</title><content type='html'>&lt;p&gt;In example of implementing an AJAX action you can see how to load and display data
  fragments from a huge dataset on the server.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The connection to this WebService is done by using the proxy generator:&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;script type="text/javascript" src="GetJavaScriptProxy.aspx?service=OrteLookup.asmx"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="code"&gt;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&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112248392455116982?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112248392455116982/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112248392455116982' title='6 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112248392455116982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112248392455116982'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/lookup-example-for-city-names.html' title='A lookup example for city names'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112212102333037908</id><published>2005-07-23T14:16:00.000+02:00</published><updated>2005-07-23T14:17:03.336+02:00</updated><title type='text'>AJAX Form Services</title><content type='html'>&lt;p&gt;The implementation of the AJAX Form Services, that allows an efficient implementation of forms can be found in the JavaScript include file ajaxForms.js.&lt;/p&gt;

&lt;p&gt;Again, only one global object named ajaxForms is defined to minimize possible name conflicts. Attached to this object the following methods are available.&lt;/p&gt;


&lt;h3&gt;data = ajaxForms.getData(obj)&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The obj parameter can be passed using the id of a formular or as a reference to a HTML Object.&lt;/p&gt;

&lt;p&gt;This result of this method is a XmlDocument object.&lt;/p&gt;


&lt;h3&gt;ajaxForms.setData(obj, data)&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The obj parameter can be passed using the id of a formular or as a reference to a HTML Object.&lt;/p&gt;

&lt;p&gt;The data parameter can be passed as a XML text of a XmlDocument object.&lt;/p&gt;

&lt;p&gt;This method also calls clearErrors at the end (see below).&lt;/p&gt;


&lt;h3&gt;ajaxForms.clearData(obj)&lt;/h3&gt;

&lt;p&gt;All HTML INPUT, TEXTAREA and SELECT elements that are part of the form are cleared or unchecked.&lt;/p&gt;

&lt;p&gt;The data parameter can be passed as a XML text of a XmlDocument object.&lt;/p&gt;


&lt;h3&gt;ajaxForms.resetData(obj)&lt;/h3&gt;

&lt;p&gt;All HTML INPUT, TEXTAREA and SELECT elements that are part of the form get their initial value that is coded inside the &lt;/p&gt;

&lt;p&gt;The obj parameter can be passed using the id of a formular or as a reference to a HTML Object.&lt;/p&gt;


&lt;h3&gt;ajaxForms.processException(ex)&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;span class="AJAXFORMEXCEPTION" name="LOANVALUE"&amp;gt;&amp;lt;/span&amp;gt;&lt;/pre&gt;


&lt;h3&gt;ajaxForms.clearErrors()&lt;/h3&gt;

&lt;p&gt;This method clears all exception texts inside the form.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112212102333037908?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112212102333037908/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112212102333037908' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112212102333037908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112212102333037908'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/ajax-form-services.html' title='AJAX Form Services'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112197097239851815</id><published>2005-07-21T20:57:00.000+02:00</published><updated>2005-07-21T20:36:12.406+02:00</updated><title type='text'>AJAX and Forms</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;


&lt;h3&gt;Classical approach and drawbacks&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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,&lt;/p&gt;


&lt;p&gt;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.&lt;/p&gt;


&lt;h3&gt;Using Form Data&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;This HTML code ...&lt;/p&gt;

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

&lt;p&gt;... corresponds to this XML document:&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;data&amp;gt;
  &amp;lt;F1&amp;gt;one by one&amp;lt;/F1&amp;gt;
  &amp;lt;F2&amp;gt;false&amp;lt;/F2&amp;gt;
  &amp;lt;T1&amp;gt;some
text
lines&amp;lt;/T1&amp;gt;
  &amp;lt;S1&amp;gt;12&amp;lt;/S1&amp;gt;
&amp;lt;/data&amp;gt;&lt;/pre&gt;


&lt;p&gt;The data of a form is now available as a single value and therefore fits well into the existing functionalities of the AJAX engine.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112197097239851815?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112197097239851815/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112197097239851815' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112197097239851815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112197097239851815'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/ajax-and-forms.html' title='AJAX and Forms'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112171657889065865</id><published>2005-07-18T21:53:00.000+02:00</published><updated>2005-07-18T21:58:16.736+02:00</updated><title type='text'>More Options for AJAX Actions</title><content type='html'>&lt;p&gt;Since the first publication I have implemented some changes and additions in the AJAX engine and the framework for WebServices.&lt;/p&gt;

&lt;h3&gt;ajax.Start(action1, option)&lt;/h3&gt;
&lt;h3&gt;prepare(option) / finish(data, option), onExeption(ex, option)&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;proxies.cancel()&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;This is only possible on asynchronous calls.&lt;/p&gt;

&lt;h3&gt;proxies.alertResult()&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;This option can be activated by assigning the alertResult method to the otherwise internally used corefunc property.&lt;/p&gt;

&lt;pre class="code"&gt;proxies.service.method.corefunc = proxies.alertResult;&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;ajax.Cancel()&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;ajax.CancelAll()&lt;/h3&gt;
&lt;p&gt;This method cancels the execution of the currently running and all the pending actions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112171657889065865?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112171657889065865/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112171657889065865' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112171657889065865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112171657889065865'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/more-options-for-ajax-actions.html' title='More Options for AJAX Actions'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112151654145183095</id><published>2005-07-16T14:19:00.000+02:00</published><updated>2006-02-05T17:11:29.400+01:00</updated><title type='text'>The AJAX prime factors sample</title><content type='html'>&lt;p&gt;
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.&lt;/p&gt;

&lt;p&gt;The connection to the already known WebService is done by using the proxy generator:&lt;/p&gt;

&lt;pre class='code'&gt;&amp;lt;script type="text/javascript" src="GetJavaScriptProxy.aspx?service=CalcService.asmx"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;The HTML code contains 2 input elements that are used for the communication with the user.

&lt;p&gt;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.

&lt;p&gt;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.

&lt;p&gt;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.

&lt;p&gt;The field with id outputField is deactivated and is used to show the calculated prime factors.

&lt;pre class='code'&gt;...
  &amp;lt;td&amp;gt;&amp;lt;input id="inputField" onkeyup="ajax.Start(action1)"&amp;gt;&amp;lt;/td&amp;gt;
...
  &amp;lt;td&amp;gt;&amp;lt;input id="outputField" size="60" disabled="disabled"&amp;gt;&amp;lt;/td&amp;gt;
...&lt;/pre&gt;

&lt;p&gt;The AJAX action is declared inside the JavaScript block and there is no other programming necessary except this.&lt;/p&gt;

&lt;p&gt;You can see within the methods prepare and finish how to exchange the values with HTML Elements.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;pre class='code'&gt;// 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&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;You can find all the samples on &lt;a href="http://www.mathertel.de/AJAXEngine/"&gt;http://www.mathertel.de/AJAXEngine/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112151654145183095?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112151654145183095/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112151654145183095' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112151654145183095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112151654145183095'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/ajax-prime-factors-sample.html' title='The AJAX prime factors sample'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112111676138293133</id><published>2005-07-11T23:18:00.000+02:00</published><updated>2005-07-11T23:19:21.386+02:00</updated><title type='text'>Handling Exceptions</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The answer to a call to a WebService in the SOAP format will under normal conditions return the result of the method:&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;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"&amp;gt;
  &amp;lt;soap:Body&amp;gt;
    &amp;lt;CalcPrimeFactorsResponse xmlns="http://www.mathertel.de/CalcFactorsService/"&amp;gt;
      &amp;lt;CalcPrimeFactorsResult&amp;gt;2 2&amp;lt;/CalcPrimeFactorsResult&amp;gt;
    &amp;lt;/CalcPrimeFactorsResponse&amp;gt;
  &amp;lt;/soap:Body&amp;gt;
&amp;lt;/soap:Envelope&amp;gt;&lt;/pre&gt;

&lt;p&gt;In the case of an error the information about the failure of the server-side execution will be passed back to the client.&lt;/p&gt;

&lt;p&gt;In the simplest case this information is shown to the user but also other reactions may be appropriate like reloading the whole page.&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;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"&amp;gt;
  &amp;lt;soap:Body&amp;gt;
    &amp;lt;soap:Fault&amp;gt;
    &amp;lt;faultcode&amp;gt;soap:Server&amp;lt;/faultcode&amp;gt;
    &amp;lt;faultstring&amp;gt;Server was unable to process request.
---&amp;gt; Input string was not in a correct format.&amp;lt;/faultstring&amp;gt;
    &amp;lt;detail /&amp;gt;
    &amp;lt;/soap:Fault&amp;gt;
  &amp;lt;/soap:Body&amp;gt;
&amp;lt;/soap:Envelope&amp;gt;&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;There is usable method defined in ajax.js that can be used for showing exceptions:&lt;/p&gt;

&lt;h3&gt;proxies.alertException(ex):&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7581919-112111676138293133?l=ajaxaspects.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ajaxaspects.blogspot.com/feeds/112111676138293133/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7581919&amp;postID=112111676138293133' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112111676138293133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7581919/posts/default/112111676138293133'/><link rel='alternate' type='text/html' href='http://ajaxaspects.blogspot.com/2005/07/handling-exceptions.html' title='Handling Exceptions'/><author><name>MatHertel</name><uri>http://www.blogger.com/profile/00264803682396593801</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7581919.post-112066759180214954</id><published>2005-07-06T20:47:00.000+02:00</published><updated>2005-07-06T18:35:54.406+02:00</updated><title type='text'>AJAX Actions</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;

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

&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;This makes it easy to follow the idea of each action.&lt;/p&gt;
&lt;p&gt;The AJAX engine layers upon the WebService proxies shown before.&lt;/p&gt;
&lt;p&gt;Every action on the page is described with the assistance of an object that holds
all information together. The properties of this object are:&lt;/p&gt;
&lt;p&gt;prepare(): This property defines a function that is used directly before sending
the SOAP of package to the serv
