Ajax Makeover Casting Call

I’d like to hear your suggestions for a short and simple web application that could use a Ajax makeover.

The makeover will be the centerpiece for my next articles on web application developement.

One reader previously suggested a quizz builder, but that’s a bit too close to the form builder. Any other idea?

How to Customize wForms

This documentation was updated on may 09 2005.

This post is part of the wForms Documentation. wForms is an open-source javascript library that adds commonly needed behaviors to traditional web forms without the need for any programming skill.

For additional help, visit the wForms forum.

wForms was designed from the onset to be easily customizable.

When the wForms extension loads, it instantiates a javascript object called ‘wf’. Public properties and methods of that object can be easily overwritten for customization purpose.

You should not change wForms.js directly, as it would hinder your ability to install updates. Instead, use a short javascript file, linked after wForms.js.

For instance,

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

See the sample customization file.

wForms Behaviors Configuration Options

wf.preserveRadioName [true / false]
Default: true. The Repeat behavior preserves the name attribute of radio inputs accross repeated elements, effectively expanding the radio group. Set to ‘false’ to make repeated radio inputs independant.
wf.preventSubmissionOnEnter [true / false]
Default: false. If set to ‘true’ the form will not be submited when the ‘enter’ key is pressed. ‘True’ is the recommanded setting for multi-page forms, to prevent submission of incomplete forms.
wf.showAlertOnError [true / false]
Default: true. The validation routine will run the showAlert function if there’s an error, with the message in wf.arrErrorMsg[8]
wf.switchScopeRootTag
Default: “FORM”. If you need the Switch behavior to be able to target elements outside of its form, you may change the switchScopeRootTag value to ‘BODY’.

How to modify error messages and text outputs

See the documentation about wForms localization.

wf.showAlert
If you’d like to display the alert message in a different way (popup, insert..) you can overrite the wf.showAlert function.

wf.showAlert = function (nbTotalErrors) {
    alert(self.arrErrorMsg[8].replace('%%',nbTotalErrors));
}

How to add a custom form validation routine

  1. Overwrite the default form validation handler with yours:
    wf.functionName_formValidation = "myCustomValidation";
  2. Implement your custom function:
    function myCustomValidation (evt) {
    // evt is the onsubmit event.

       // call the wForms default validation routine
       if(wf.formValidation(evt)) {

           // do your stuff..

       } else
        // will prevent the form from being submitted.
        return wf.utilities.XBrowserPreventEventDefault(evt);
    }

How to change the CSS Classes used by wForms

Here are the classes defined in wForms. You probably won’t need to ever change them, but if you do, you may do so in the customization.js file.

Please note: if your form has been created using the form builder, you need to apply your changes to your form’s HTML as well.

wf.classNamePrefix_switch = “switch”;
wf.classNamePrefix_offState = “offstate”;
wf.classNamePrefix_onState = “onstate”;
wf.className_repeat = “repeat”;
wf.className_delete = “removeable”;
wf.className_required = “required”;
wf.className_validationError_msg = “errMsg”;
wf.className_validationError_fld = “errFld”;
wf.classNamePrefix_validation = “validate”;
wf.className_duplicateLink = “duplicateLink”;
wf.className_removeLink = “removeLink”;
wf.className_activeFieldHint = “field-hint”;
wf.className_inactiveFieldHint = “field-hint-inactive”;
// id attribute suffixes
wf.idSuffix_fieldHint = “-H”;
wf.idSuffix_fieldLabel = “-L”;
wf.idSuffix_fieldError = “-E”;
wf.idSuffix_repeatCounter = “-RC”;

 

Update: Comments are now closed for this post, but you can go to the wForms forum if you have any question or comment. Thanks !

wForms Input Validation Explained

This post is part of the wForms Documentation. wForms is an open-source javascript library that adds commonly needed behaviors to traditional web forms without the need for any programming skill.

For additional help, visit the wForms forum.

The purpose of the input validation in wForms is to help users fill out a form
correctly, by defining required fields and allowed formats and by providing appropriate
error messages when the condition for submission are not met.

 

 

 

Example of Form Validation (click on submit)

(required and alphabetic characters only)


(required and email values only)


(required, number only)


(not required, date format)


(required)

Your favorite color:

Implementation

If you use the form builder, you don’t have to worry about these details, but to use the wForms input validation on your own web forms, follow the following steps:

  1. Enable the wForms extension by adding the following code to the <head> element of your page:
    <script type="text/javascript" src="wforms.js" ></script>
  2. Add any of the following classes to your input fields:
    required
    Field value cannot be empty. Use it on any field type (<input>, <select>,<textarea>).
    validate-alpha
    Allows only alphabetic characters ([a-z], can be modified for localization purpose). Allows an empty value.
    validate-alphanum
    Allows number and alphabetic characters, no ponctuation or exotic characters (can be modified for localization purpose). Allows an empty value.
    validate-date
    Allows a date, in any format supported by the local browser. Allows an empty value.
    validate-email
    Allows only a valid email syntax (someome@somewhere.somext). Allows an empty value.
    validate-integer
    Allows only a number (digits). Allows an empty value.
    validate-float
    Allows float numbers (ex: 0,00). Allows an empty value.

    You may use ‘required’ in combination with any other class. For instance:

    <input type="text" name="wf_Yourname" class="validate-alpha required"/>

  3. To require at least one response to a multiple-choice question, add the class ‘required’ to the parent element (the container). For instance:
    <div class="required">
    <input type="checkbox" name="something" … />
    <input type="checkbox" name="somethingelse" … />
    <input type="checkbox" name="anothersomething" … />
    </div>
  4. Add the following CSS rules to your stylesheet to control the look of the error messages:
    • .errFld {border: 1px solid #F00; /*... or any other css properties ... */}
    • .errMsg { color: #C33; /*... or any other css properties ... */ }

 

Update: Comments are now closed for this post, but you can go to the wForms forum if you have any question or comment. Thanks !

Ajax: It’s not all about XMLHTTPRequest (part II)

In my previous article, I pointed out that XmlHttpRequest is already misused and misunderstood, and that cutting down server accesses is the key for better and faster web applications.

A slightly revisited Ajax Web Application model looks like this (based on J.J. Garrett original article on Ajax)

Ajax Web Application Model Revisited
Ajax Web Application Model Revisited

In this model, the client retrieves the preliminary data and the interface templates from the server. The Ajax engine then takes over the responsibility for running the application. The next server access only occurs to save the final state of the data.

Note: This diagram is not showing asynchronous server access, because I’m trying to make the point that server access is often not necessary in the first place. But of course, asynchronous server access can sometimes be beneficial or required (multi-user functionalities or user authentication for instance).

To fulfill his role, the Ajax Engine must be able to display the different screens of the interface, process the user inputs and apply the changes to its internal representation of the data. Respectively, this involves XSLT, Javascript and DOM.

Managing Data Client-Side

The Document Object Model (DOM) is pretty good at this game. After all, it already maintains the state of your web page. Modern browsers will let you instantiate a new DOM Document that you can use to manage your data. A DOM document it is not limited to HTML but can hold any type of XML data.

Painting User Interface Client-Side

XSL is a templating language designed to be the perfect companion to XML. Applying the template to a XML document is a process called Transformation (XSLT).

XSL templates will typically contain HTML markup for the different pieces of the interface, and several XSL templates can apply to only one XML document, representing the different states of the data through the life of the application.

Support Considerations

The XSLT specification was finalized by the W3C in 1999. XSLT is currently supported by Internet Explorer, Gecko-based browsers (Mozilla, Netscape 7 and Firefox) and will be supported by Safari 1.3.

The technology is definitively mature and supported by over 95% of the current browser market. If you are concerned by the few remaining percents (Opera and other marginal browsers), it is possible to use a fallback solution: Offload the XSL Transformation to the server using a pseudo-XmlHttpRequest.

Sarissa is an open-source wrapper that offers a handy uniform syntax across browsers for everything XML/XSLT and XMLHttpRequest.

Conclusion (updated)

For a practical example of client-side XML / XSLT integration, see the Ajax makeover articles.

Ajax: It’s not all about XMLHTTPRequest (part I)

In the current craze around Ajax, XMLHttpRequest is getting all the attention. While there’s no doubt it is well deserved, there are other technologies in the Ajax realm that should not be overlooked and XSLT is one of them.

In the Form Builder, there is only one call to XMLHttpRequest, when you click the ’save’ button. Everything else relies on the transformation by the browser (ie. client-side) of XML data using XSL templates. Client-side XSLT dramatically reduces the need for server access. That’s its strength.

The Problem with XmlHttpRequest

In a typical web application the data is modified on the client. A back and forth with the server is used to

  1. save the data,
  2. retrieve the new state of the interface, which often involves also,
  3. reload the data.

XmlHttpRequest makes the round-trip to the server seamless, which can be good… or bad, if you have a noticeable network delay.

In the traditional click & load model, users expect their browser to behave in a certain way when they click on a link or a button. The throbber (your browser loading indicator) should start its animation, the mouse pointers should show the hourglass and the page should go blank before reappearing.

None of those happen when you use XmlHttpRequest, leaving the user with a feeling of uncertainty; ‘did I click or not ?’. To circumvent this, developers need to add a custom loading indicator (welcome to the world of Flash developers…).

What happens really is that XmlHttpRequest is not used for what it is good at: asynchronous, behind-the-scene, access to the server, but in the context of a synchronous transaction by the user.

Users want instant feedback from an application, and a better way to achieve that is by freeing the application from its over-reliance on the server.

When applications break free

To curb down server access, you need to transfer to the client responsibility for two things: (1) maintaining the state of the data and (2) drawing the different screens of the interface. The server remains in charge of saving the finalized form of the data, which can be done behind the scene with XmlHttpRequest.

This is how you can design rich web applications. This is how the form builder is made and this is the subject of the second part of this article.

Javascript Enabled Stylesheets

It is sometimes necessary to hide a CSS stylesheet from the browser if javascript is disabled or not available.

A collapsed section of a document, for instance, will never be visible if the javascript functionality to expand it is not working. To prevent this situation from happening you need two different behaviors: “section expanded” if javascript is disabled and “section collapsed” otherwise.

Such behaviors can be easily implemented by moving the javascript-dependant CSS rules to a specific stylesheet that cannot be activated without javascript.

For instance,

default.css
.expanded { display: block; }
.collapsed { }

jsonly.css
.collapsed { display: none; }

The idea is too use a technique similar to some stylesheet switching scripts. The js only stylesheet will first be loaded as an alternate stylesheet, while the default stylesheet is loaded normaly.

<link href="default.css" rel="stylesheet" type="text/css" />
<link href="jsonly.css" rel="alternate stylesheet" type="text/css" title="this stylesheet is activated by javascript" />

The alternate stylesheet is safely ignored by the browser, until the following script, if allowed to run, enables it.

function activateStylesheet(sheetref) {
     if(document.getElementsByTagName) {
        var ss=document.getElementsByTagName('link');
     } else if (document.styleSheets) {
        var ss = document.styleSheets;
     }
     for(var i=0;ss[i];i++ ) {
          if(ss[i].href.indexOf(sheetref) != -1) {
          ss[i].disabled = true;
          ss[i].disabled = false;
          }
     }
}
activateStylesheet('jsonly.js');

This function should be called from your onload event handler, or in any case, after the links to the stylesheets. It basically enumerates the stylesheet collection, looking for the one named after the given parameters and then enables it. It might look a bit silly to do disabled = true before doing disabled = false, but it is necessary in order for the disabled property to work correctly in Internet Explorer.

This method was tested in IE5.5+, Safari, Firefox, Netscape 7+ and Opera 7.5.

Ajax and the true separation of presentation, content and behavior

Contrary to what some may argue, you can use Ajax technologies in web applications and keep your code clean and separated from your presentation markup and content.

To kick off this column on Web Application development, I am going to address this issue with the 3 simple rules I used while working on the Form Builder.

Note: cross-browser considerations intentionally left out.

Rule #1: Use unobtrusive javascript

Don’t embed javascript inside your tags.

<a href="..." onclick="dostuff();"> do stuff </a>

This is just as bad as inline CSS or font tags.

Instead, do:

<a href="..." id="stuffDoer"> do stuff </a>

and have a separate javascript file, linked from the <head> of your page, with something like this :

document.addEventListener ('load', function() {
     document.getElementById('stuffDoer').onclick = doStuff; }, false);

See also these other recommendations.

 

Rule #2: Do not use javascript to generate markup

Or let me put it this way: build template driven applications. Use XMLHTTPRequest or XSLT to retrieve XHTML formatted strings, and insert them in your document.

The insertion point is identified by a placeholder, often an empty DIV element:

<div id="my_placeholder"></div>

For XHTML generated server side, use XMLHttpRequest:

var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", someResourceURI, true);
xmlhttp.onreadystatechange= function() {
if (xmlhttp.readyState==4) {
document.getElementById('my_placeholder').innerHTML = xmlhttp.responseText;
}
xmlhttp.send()

For XHTML generated client-side, use XSLT:

var processor = new XSLTProcessor();
processor.importStylesheet(your_xsl_template);
var xhtml = processor.transformToDocument(your_xml_data);
document.getElementById('my_placeholder').importNode(xhtml);

Note: The Sarissa wrapper provides a uniform syntax across browsers for all Ajax related coding.

 

Rule #3: Do not use javascript to style your content

Don’t do

document.getElementById('some_id').style.color = '#ff0000';

Instead do:

document.getElementById('some_id').className = 'some_class';

and set the color property in your CSS stylesheet
.some_class {
color: #ff0000;
}

If you are trying to achieve a visual effect, you may want to consider class switching:

document.getElementById('some_id').className.replace('old_class','new_class');

 

That’s it for today. What do you think?

Technorati Tags: ,

wForms Extension Overview

This post is part of the wForms Documentation.

For additional help, visit the wForms forum.

wForms is a javascript extension that adds commonly needed behaviors to traditional web forms. It follows the principle of progressive enhancement : unobtrusive, cross-browser and degradable. I should also point out that not a single line of code is required to actually use it. That makes the learning curve almost non-existant. If you can add a class to a tag, then you can use wForms.

Implemented behaviors are:

* Switch: Allows you to show/hide relevant parts of a form based on the user inputs.
* Repeat: Allows parts of a form to be repeated if the user wants to provide more answers.
* Field Hint: Displays contextual help based on the current input focus.
* Input Validation: Validates common input types (email, numbers, ..) and displays appropriate error messages.

wForms is not as complete or ambitious as XForms or Web Forms 2.0 are, but at least it works with today’s browsers and is web standards compliant.

 

Update: Comments are now closed for this post, but you can go to the wForms forum if you have any question or comment. Thanks !

How to Localize wForms

This post is part of the wForms Documentation. wForms is an open-source javascript library that adds commonly needed behaviors to traditional web forms without the need for any programming skill.

For additional help, visit the wForms forum.

wForms was designed from the onset to be easily adapted to languages other than english.

When the wForms extension loads, it instantiates a javascript object called ‘wf’. Public properties and methods of that object can be easily overwritten for localization purpose.

You should not change wForms.js directly, as it would hinder your ability to install updates. Instead, use a short javascript file, linked after wForms.js.

For instance,

<script type="text/javascript" src="js/wforms.js" ></script>
<script type="text/javascript" src="js/localization-francais.js" ></script>

Available Localization Files

  • Please visit http://www.formassembly.com/wForms for the complete list.

How to create your own localization file

1. Translating Error Messages

Error messages are contained in an array (wf.arrErrorMsg[]). Your translation should follow this example :

wf.arrErrorMsg[0] = "Champs requis"; // required field
wf.arrErrorMsg[1] = "Caractères alphabétiques uniquement (a-z)"; // alpha char. only
wf.arrErrorMsg[2] = "Adresse email invalide"; // email
wf.arrErrorMsg[3] = "Entrez un nombre entier"; // integer
wf.arrErrorMsg[4] = "Entrez un nombre"; // float
wf.arrErro rMsg[5] = ""; // password - not implemented
wf.arrErrorMsg[6] = "Caractères alpha-numeriques uniquement (a-z 0-9)"; // alphanumeric
wf.arrErrorMsg[7] = "Date invalide"; // date
wf.arrErrorMsg[8] =”Il y a %% erreur(s). Votre formulaire n’a pas été envoyé.\nVérifiez les informations saisies.”; // %% will be replaced by the actual number of errors.

2. Translating Other Texts

wf.arrMsg[0] = "Ajouter"; // repeat link
wf.arrMsg[1] = "Ajouter un nouveau rang" // title attribute on the repeat link
wf.arrMsg[2] = "Supprimer"; // remove link
wf.arrMsg[3] = "Supprimer le rang" // title attribute on the remove link
wf.arrMsg[4] = "Next Page"; // label used with multi-page forms
wf.arrMsg[5] = "Previous Page"; // label used with multi-page forms

3. Adapting Input Validation

The Alphabetic and Alphanumeric field types are accepting by default only basic latin characters : a-z, A-Z and 0-9. To validate a different character set, the wf.isAlpha() and wf.isAlphanum() methods must be redefined.

These two methods rely on a regular expression to validate the input.

wf.isAlpha = function(s) {
var reg = /^[\u0041-\u007A\u00C0-\u00FF\u0100–\u017F]+$/;
return this.isEmpty(s) || reg.test(s);
}

wf.isAlphaNum = function(s) {
var reg = /^[\u0030-\u0039\u0041-\u007A\u00C0-\u00FF\u0100–\u017F]+$/;
return this.isEmpty(s) || reg.test(s);
}

The expression /^[\u0041-\u007A]+$/ covers the Unicode range 0041 to 007A, which corresponds to the basic latin alphabet.

The expression /^[\u0041-\u007A\u00C0-\u00FF\u0100–\u017F]+$/ covers the Unicode ranges 0041 to 007A, 00C0 to 00FF and 0100 to 017F. This includes the most common variations of the latin alphabet.

Here’s an overview of common Unicode ranges :

Unicode Range Character Set Languages
\u0030-\u0039 Numbers 0-9  
\u0041-\u007A Basic Latin English
\u0041-\u007A +
\u00C0-\u00FF
Latin-1 (used with Basic Latin) Danish, Dutch, Faroese, Finnish, Flemish, German, Icelandic, Irish,Italian, Norwegian, Portuguese, Spanish, and Swedish.
\u0041-\u007A +
\u00C0-\u00FF +
\u0100–\u017F
Latin Extended-A (used with Latin-1 and Basic Latin) Afrikaans, Basque, Breton, Catalan, Croatian, Czech, Esperanto, Estonian, French, Frisian, Greenlandic, Hungarian, Latin, Latvian, Lithuanian, Maltese, Polish, Provençal, Rhaeto-Romanic, Romanian, Romany, Sami, Slovak, Slovenian, Sorbian, Turkish, Welsh, and many others.
\u0370-\u03FF Greek  
\u0400-\u04FF Cyrillic Russian, etc..
\u0590–\u05FF Hebrew  
\u0600–\u06FF Arabic  
\u0900–\u097F Devanagari Hindi, etc..
\u4E00–\u9FFF Han Chinese, Japanese, and Korean languages

See http://www.unicode.org/charts/ for other languages.

Please share your localization files by sending them to webmaster at formassembly dot com.

 

Update: Comments are now closed for this post, but you can go to the wForms forum if you have any question or comment. Thanks !

Quick Notice :

I am trying to identify any problem related to the use of non-ascii characters in the Form Builder.

Can someone try to create a form with kanji, cyrillic or any alphabet with accentuated characters (é, à,ù, etc..) and leave a comment on this post with his/her results ?

Thanks !

Next Page »

You are currently browsing The Form Assembly weblog archives for April, 2005.

Search the Blog Archive

 

The Form Assembly blog is powered by WordPress ~ Entries (RSS) and Comments (RSS).