Et1 Detailed Design Document: 'lib/view/FormElementMassager.js'

Author: cbalz
Last Updated: 2008-07-17


Overview

For the interface definition, see below.

'FormElementMassager' provides data smoothing (also called "massaging") and form element decoration services.  The services are accessed via object construction.  The constructor calls a method, 'refreshEventListeners', that sets 'change' ('onchange') event listeners on all the form elements within a given container.  If the dom elements change over the course of a session, the event listeners may be refreshed by a call to that method.

The services will automatically be turned by an object of type 'FormElementContainer' for its document object model (dom) target, if the constructor for 'FormElementMassager' is present (defined in the current JavaScript context).  The data smoothing to be performed and the decorations to be made are specified by pre-defined css classnames on given html form elements.  Data massaging is strictly limited to proper html form elements: 'input' of type 'text' and 'textarea'.

Client objects of 'FormElementMassager' or of a massage-enabled 'FormElementContainer' object may optionally set an event listener onto the top level object (either 'FormElementContainer' or 'FormElementMassager' (detail below) for the event, 'massage'.  That enables them to validate a given form value directly after it has been massaged. 

Use-case

Developer has a given 'div' on a html page.  A set of html form objects are in that page.  A 'FormElementContainer' has already been instantiated in the current JavaScript context, with the 'div' as its dom target.  The user (not the developer) of the html application enters some data in a form field. 

The user then tabs out of the form field, causing the user-agent ("web browser") to emit an 'change' event.  The 'FormElementMassager' object massages the data that the user entered into a proper format based on pre-defined css class name identifiers that it discovered on the form element.

The 'FormElementMassager' emits a 'massage' event.  This event is heard by the application developer's code.  The application developer desires to validate the form field immediately, so s/he then performs data validation on that (massaged) form field.

Interface

1.               Display class attributes:

 

1.1           precision-‘n’

 

This class attribute should pad/round the user-entered number accordingly for the given decimal.  Negative values for 'n'  cause the rounding to be applied to the power of ten indicated (i.e., round to 100s or thousands place).   See example below:

Example:

precision-3: 

Padding:  If the user enters 123.2, it should be padded by 0 for the remaining decimal, and display 123.200

      Rounding: If the user enters 123.2345, it should be rounded to given decimal, and display 123.235.   
                        If the precision is 0, then the number is rounded to the nearest integer.

Example:

precision--3:

      Rounding: If the user enters 123500, it should be rounded to the thousands place, and display 124000.

 

      XSL Code:

      <input type="text" name="Price" value="">

      <xsl:attribute name="maxlength">10</xsl:attribute>

      <xsl:attribute name="class"> price type-decimal maxlength=10

</xsl:attribute>

<xsl:attribute name="class"> precision-<xsl:value-of select="ValuePrecision"/>

</xsl:attribute>

      </input>

 

1.2           format-num

 

This class attribute will format the user entered number to the given class regular expression.

 

Example:

format-num:  If the locale is 'en_US', it should format the given number to the US 1000 separated display. 


If the user enters 12345, it should display 12,345.

1000 becomes 1,000, 100000.01 becomes 100,000.01, and so on.


XSL Code:

      <input type="text" name="Price" value="">

      <xsl:attribute name="class">price type-decimal </xsl:attribute>

<xsl:attribute name="class">format-num-<xsl:value-of select="/root/locale"/></xsl:attribute>

      </input>

 

1.3           Display * for the required field.

       Because this functionality is purely view related, it is handled in lib/view/FormElementDecorator.js.

1.4           Display date format.

The format of the date should be configurable at the application level, and the formats MM/DD/YYYY (12/30/2008) and DD-MMM-YYYY (15 AUG 2006) should be supported.

 

Example: format-date  If the locale is 'en_US',  it should format the given number adaptively to the US  formats : MM/DD/YYYY (12/30/2008) and DD-MMM-YYYY (15 AUG 2006)
 

When the user enters the date in the MM-DD-YYYY format, It should first display the date to the MM/DD/YYYY format before performing the validation.  It should just replace the hyphen (-) with slash (/).

 

Example Scenarios:

A)      When the user enters the 3-3-05, it should display 03/03/05.

B)      When the user tries to enter 3-3-3-3, it should display 03/03/03/03 (validation is a separate piece of functionality not covered by this class).

C)      When the user enters 3 AUG 2005, it should display 3 AUG 2005.

 

Implementation

Classes

Objects

Sequence

Initialization

Alternative A:
  1. Upon instantiation, 'FormElementContainer' checks to see if a constructor for a 'lib/view/FormElementMassager' object exists. 
  2. If so, it:
    1. Instantiates the 'FormElementMassager' object with a single parameter, which is the original dom target of the 'FormElementContainer' object.
    2. Sets an event listener on 'FormElementMassager' for the 'massage' event.
      1. 'FormElementContainer''s 'eventMassage' event handler simply emits the same event.
  3. When 'FormElementMassager' is instantiated, it sets the 'onchange' event listeners on all form elements in the container with massagable data.
Alernative B:
  1. The developer manually instantiates a a 'lib/view/FormElementContainer' object, supplying a dom container parameter to the constructor and optionally setting an event listener on it (per the above).

Execution

<FormElementContainer>.massage (per Alternative A, above):
  1. The 'massage' method of a 'FormElementContainer' object performs all the work needed to support the defined massage services. 
  2. It is invoked with no parameters. 
  3. When it is invoked, it first checks to see if there is an 'oMassager' property. 
    1. If not, it the JavaScript interpreter throws an exception.
  4. It calls the 'massage' method of 'FormElementMassager'.
<FormElementMassager>.massage (May be called 'standalone', per Alternative A or Alternative B, above).
  1. The 'eventChange' method of 'oMassager' checks for the existence of a css class name that matches the regular expression, '/format-|precision-|required-./'. 
    1. If there is a match, it passes control to a worker method, 'massage', which takes a dom form element as a parameter.
    2. If not, the method returns.
  2. The 'massage' method inspects the form element for a given massage css classname key. 
    1. Implementation here will probably be by an existence test of each key in a hash that maps keys to methods on the 'FormElementMassager' instance.  This allows iteration through the small number of classnames on the form element, versus through the large number of possible massage keys.
  3. The 'massage' method invokes the appropriate specific massage method for each match, passing the given dom element instance each time.
    1. The specific massage method changes the form element's 'value' or 'selectedIndex' property to suit.
  4. The 'massage' method emits an 'EventMassage' object.
    1. If there was a change in the value of the form element, the 'bChanged' flag on the 'EventFormElementMassaged' object is set to 'true'.
<FormElementMassager>.refreshEventListeners
  1. Removes any pre-existing event listeners and adds new ones to all form elements of interest in the dom container.