Freitag, Juni 29, 2007

The fade effect and the DataFade control

Here is a nice visual effect for data fields:

When a page contains multiple values that might change from time to time it is a good idea to bring the users attention to the updated value. The DataFade implements this by changing the background color of a field and fading it from yellow to the original background color that defined by the regular style.

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.

Here is a simple implementation using a horizontal scrollbar and a simple field.

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

When the DataFade control is initialized the actual background color is detected and stored in the local orgcolor field.

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.

The DataFade control is implemented using a JavaScript Behavior so it can be used inside AjaxForms for displaying, but not entering values. This is because it is inheriting the DataOutput Behaviour it implements a setData(newValue) method that is detected by the ajaxForms implementation and is used for setting the new value.

Dienstag, Juni 19, 2007

Aspects of OpenAjax

You know I like standards.

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.

That's why I use the SOAP standard webservice protocol for my Ajax implementations.

OpenAjax

Now OpenAjax Alliance 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.

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.

http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification 

Libraries and Namespaces

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.

Did you try to use 2 libraries that both register the $() function but implement it differently?

The OpenAjax registerLibrary and unregisterLibrary methods that can be used to help mastering this problem space.

The ajax, the proxies and the jcl 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! :-)

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.

The namespace used by the Aspects of Ajax frameworks will be de.mathertel because http://www.mathertel.de/AJAXEngine/ is the URL where the documentation and the samples can be found on the web.

... but maybe it's time to register a product name related web address :-)

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.

Events - inter controls connections

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 ...

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.

The Aspects of Ajax framework has a small implementation since almost 2 years (see http://ajaxaspects.blogspot.com/2005/09/connecting-controls.html) 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.

  1. 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).
  2. 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.
  3. 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.
  4. 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.

Overall the OpenAjax implementation has some big advantages over the older DataConnections and the additional functionality can be added.

Implementation

The OpenAjax Alliance provides a reference implementation 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.

The size of the implementation

As of this writing the (unfinished) reference implementation is about 2801 bytes. The (current) implementation available on my side at http://www.mathertel.de/OpenAjax 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 http://alex.dojotoolkit.org/shrinksafe/. This is because I don't want to compare the comment lines or different programming styles.

 

The same implementation is also embedded into the jcl.js implementation that also implements the JavaScript Behavior mechanism.

Future planning

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.

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.

Sonntag, Juni 17, 2007

A simple page for displaying a record

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 http://www.mathertel.de/AJAXEngine/S06_AJAXForms/SimpleReader.aspx is  built by a combination of the 3 components:

  • The Form contains DataInput fields and other Data Contol elements that are used to display the values.
  • The Menubar is used to offer the typical buttons for searching and navigating through the dataset.
  • The DataSource control controls the binding between these controls and the server side web methods.

The Form element

Many web applications need to display and modify relational data by using 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.

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 <form> element but use a <div> element instead.

The functionality that is attached to the form (the <div> element) of the page handles getting and setting values by respecting the correct formats for several datatypes and converting them to regular xml data formats.

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.

The functionality of the form element is implemented by using the DataForm JavaScript Behavior 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.

The Menubar element

This element contains the typical buttons that enable the navigation through a set of records.

These buttons and icons will trigger the corresponding methods of the datasource control by publishing events. 

The DataSource control

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.

The following commands are available:

clear: This command will just clear all the values inside the form.

search: A call to the server is 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.

first: The first record in the cursor is retrieved from the server and is displayed inside the form.

next: The next record in the cursor is retrieved from the server and is displayed inside the form.

previous: The previous record in the cursor is retrieved from the server and is displayed inside the form.

last: The last record in the cursor is retrieved from the server and is displayed inside the form.

(future extensions: add, update, delete, ...)

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.

Searching and the AJAX calls in the background

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.

Here is a sample how to search:

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".

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.

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.

Events between the controls

Connecting elements on the page might be done by using scripts in one element that direct address the other element or by using events.

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 events and another mechanism is needed for tasks like this.

The OpenAjax Alliance is targeting this problem with the hub implementation that is still under development for version 1.0.

Inside jcl.js (view source) you can now find a (almost) compatible version of the OpenAjax 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... 

Montag, Juni 11, 2007

Building data-centric and forms based AJAX applications

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 are not a lot of drag & drop elements or popping visual effects here but most active elements deal with data that comes from databases or other data sources.

Many developers do not build E-Mail applications, portal frameworks, maps or mashups but we need to display, edit and control records from a company's database and implement transactions on these entities.

This part of the framework and the upcoming posts are about the aspects and coding the client side of this kind of web applications and here is my blueprint of the ongoing work that will extend and consolidate the framework in this direction.

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.

Inside the archive file Ajax_new.zip download you can follow the development of this part of the framework in the S06_AJAXForms folder.

Typical data-centric web pages

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:

  • Fields and other elements where values are shown and edited by the users (Input fields, checkboxes, ...)
  • Buttons that help editing these values (calendar popup, drop-down lists, ...)
  • Foreign key Lookup mechanisms [check against a list of countries]
  • Buttons that offer a way of navigation through huge data sources  (|< first, next >>, ...)
  • Buttons that commit a current state to the backend system ([Update])
  • Buttons that trigger special transactions or back-end calculations
  • Tables that display mass data by paging or scrolling
  • Tree Views that display hierarchical (mass-) data

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 aspects about the major features.

Forms and binding data

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 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 will be extended and tuned a little bit.

Supporting national language specific notations

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.

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.

Input Helpers

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 or sliders that can be used to adjust a value.

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.

Navigating through table data

In many cases the data comes from a data source on the server that stores many records in a 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.

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.

Tree Data

A data bound tree sample has already been published at http://www.mathertel.de/AJAXEngine/S03_AJAXControls/TreeView.aspx

but we will see how to integrate it into the scenario by reusing the same web service interface for the Ajax call.

Common data interface on the server

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 with the minimal set of methods.

AJAX Controls for AJAX forms

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.

(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).

 

Technorati tags: , , ,

Sonntag, Juni 03, 2007

A simple menubar

By using the hover effect it is possible to realize a simple menubar that will be used by an upcoming control that allows rich text editing. 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.

Building the html code for the menubar

The html code for building a menubar is implemented by using an outer <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.

The inner elements and menu items can be implemented using <img> images or <span> elements with text content.

The third type of an inner element is a vertical line or separator that can be used to group elements.

Here is a small sample:  

<div class="VEMenuBar">
  <span class="VEMenu" tabindex="1" onclick="datasource.search();">Search</span>
  <img class="VEMenuSeparator" alt="" src="../controls/images/white.gif" />
  <img class="VEMenu" alt="show first record" tabindex="1" src="../controls/images/first.gif" /> 
</div>

The hover effect

When positioning the mouse over any enabled item of the menubar the individual item for starting a specific command is highlighted. For implementing this effect the already known hover behavior 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.

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

The menubar behavior (MenubarBehavior)

This behavior implements all the basic functionality for menubars. When bound to a html element it also loops through all the children 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.

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.

The HTML elements that build the menubar 

First of all the outermost 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.

The icons or other images are placed in the menu by using <img> elements as children inside the VEMenuBar element

and will have a classname "VEMenu". They will automatically get an attribute hover="true" to enable the hover effect.

CSS definitions 

Some classnames need to be defined:

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

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

.VEMenuBar * { vertical-align:top;}

All elements will be vertically aligned by the top.

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

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

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

This rule is used for the state of 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.

.VEMenuHover { border-style:solid;border-width:1px;border-color: #acc1e4 #203050 #203050 #acc1e4;padding:1px}
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.

.VEMenuPushed { border-style:solid;border-width:1px;border-color: #203050 #acc1e4 #acc1e4 #203050;padding:1px}
This is the state of a icon when the icon is pushed down. In my layout I use 1 pixel of border on every side but with different colors and I reduce the padding to 1 px to avoid the shifting and flickering of the graphic.

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

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

Attaching functionality

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.

 

You can find the state of the current implementation here:

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

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

 

Download the current version under development

I've added another downloadable archive file to the site : Ajax_new.zip.

This Zip-File contains the current version of the ASP.NET 2.0 web project that builds this side.
The complete AJAX Engine and all samples and also unfinished samples and componente are included.
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.