Et1 Detailed Design
Document: 'lib/view/FormElementMassager.js'
Author: cbalz
Last Updated: 2008-07-17
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.
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.
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.
Classes
- lib/model/utils/FormElementContainer (optional)
- lib/model/utils/FormElementMassager
- lib/model/utils/DataMassager
Objects
- <lib/model/utils/FormElementContainer> One of these
optionally exists.
- <lib/model/uitils/FormElementMassager> Controls the
massaging of the form element data.
- <lib/model/utils/DataMassager> Does the actual work of
massaging the form element data.
Sequence
Initialization
Alternative A:
- Upon instantiation, 'FormElementContainer' checks to see if a
constructor for a 'lib/view/FormElementMassager' object exists.
- If so, it:
- Instantiates the 'FormElementMassager' object with a single
parameter, which is the
original dom target of the 'FormElementContainer' object.
- Sets an event listener on 'FormElementMassager' for the
'massage' event.
- 'FormElementContainer''s 'eventMassage' event
handler simply emits the same event.
- When 'FormElementMassager' is instantiated, it sets the
'onchange' event listeners on all form elements in the container with
massagable data.
Alernative B:
- 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):
- The 'massage' method of a 'FormElementContainer' object performs
all the work needed to support the defined massage services.
- It is invoked with no parameters.
- When it is invoked, it first checks to see if there is an
'oMassager' property.
- If not, it the JavaScript interpreter throws an exception.
- It calls the 'massage' method of 'FormElementMassager'.
<FormElementMassager>.massage (May be called 'standalone', per
Alternative
A or Alternative B, above).
- The 'eventChange' method of 'oMassager' checks for the existence
of a css class name that matches the regular expression,
'/format-|precision-|required-./'.
- If there is a match, it passes control to a worker method,
'massage', which takes a dom form element as a parameter.
- If not, the method returns.
- The 'massage' method inspects the form element for a
given
massage css classname key.
- 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.
- The 'massage' method invokes the appropriate specific
massage method
for each match, passing the given dom element instance each
time.
- The specific massage method changes the form element's 'value'
or 'selectedIndex' property to suit.
- The 'massage' method emits an
'EventMassage' object.
- 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
- Removes any pre-existing event listeners and adds new ones to all
form elements of interest in the dom container.