<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2010://34/tag:www.insideria.com,2009://34.36127-</id>
  <updated>2010-03-19T18:31:15Z</updated>
  <title>Comments for Building an Enterprise Framework - Enterprise Development with Flex, Part 3 (http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2009://34.36127</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=36127" title="Building an Enterprise Framework - Enterprise Development with Flex, Part 3" />
    <published>2009-05-20T18:43:48Z</published>
    <updated>2009-05-20T18:43:48Z</updated>
    <title>Building an Enterprise Framework - Enterprise Development with Flex, Part 3</title>
    <summary>Note: This is excerpted from Chapter 3 of the Rough Cuts version of Enterprise Development with Flex. This book is still in progress, and you can get access to it now. Get the Enterprise Development with Flex Rough Cut Rough...</summary>
    <author>
      <name>Yakov Fain</name>
      
    </author>
    
    <category term="Features" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<p><em>Note: This is excerpted from Chapter 3 of the <a href="http://oreilly.com/roughcuts/faq.csp" target="_blank">Rough Cuts</a> version of <a href="http://oreilly.com/catalog/9780596801014/">Enterprise Development with Flex</a>. This book is still in progress, and you can <a href="http://my.safaribooksonline.com/9780596801465?cid=orm-cat-readnow-9780596801465" target="_blank">get access to it now</a>.</em></p>

<div class="ap_r_front"><img src="http://oreilly.com/catalog/covers/9780596801014_cat.gif" alt="Enterprise Development with Flex cover" style="width: 148px;" /><div class="apcaption"><a href="http://oreilly.com/catalog/9780596801014/">Get the Enterprise Development with Flex Rough Cut</a></div></div>

<p><em><a href="http://www.oreilly.com/roughcuts">Rough Cuts</a> is a service from Safari Books Online that gives you early access to content on cutting-edge technologies -- before it's published.  It lets you literally read the book as it is being written. </em></p>

<p><strong>Table of Contents, Part 3</strong></p>
<dt><span class="sect1"><a href=
"#validation">Validation</a></span></dt>
<dd>
<dl>
<dt><span class="sect2"><a href=
"#sample_application_-_dataformvalidator">Sample
Application &ndash; DataFormValidator</a></span></dt>
<dt><span class="sect2"><a href=
"#class_validationrule_explained">Class ValidationRule
Explained</a></span></dt>
<dt><span class="sect2"><a href=
"#embedding_validation_rules_into_a_datagr">Embedding
Validation Rules into a DataGrid</a></span></dt>
</dl>
</dd>
<dt><span class="sect1"><a href=
"#minimizing_the_number_of_custom_events">Minimizing the
Number of Custom Events</a></span></dt>
<dt><span class="sect1"><a href=
"#summary">Summary</a></span></dt>
</dl>

<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="validation" id=
"validation"></a>Validation</h2>
</div>
</div>
</div>
<p>Like data forms and components in general, the Flex <code class=
"literal">Validator</code> could use some enhancement to make it
more flexible for your application developers. In Flex validation
seems to have been designed with an assumption that software
developers will mainly use it with forms and each validator class
will be dependent on and attached to only one field. Say, you have
a form with two email fields. Flex framework forces you to create
two instances of the <code class="literal">EmailValidator</code>
object &ndash; one per field.</p>
<p>In the real life though, you may also need to come up with
validating conditions based on relationships between multiple
fields, as well as to highlight invalid values in more than one
field. For example, you might want to set the date validator to a
field and check if the entered date falls into the time interval
specified in the start <span class="emphasis"><em>and</em></span>
end date fields. If the date is invalid, you may want to highlight
all form fields.</p>
<p>In other words, you may need to do more than validate an object
property. You may need the an ability to write validation rules in
a function that can be associated not only with the UI control but
also with the underlying data, i.e. with a data displayed in a row
in a <code class="literal">DataGrid</code>.</p>
<p>Yet another issue of Flex <code class="literal">Validator</code>
is its limitations regarding view states of automatically generated
UI controls. Everything would be a lot easier if validators could
live inside the UI controls, in which case they would be
automatically added to view states along with the hosting
controls.</p>
<p>Having convenient means of validation on the client is an
important part of the enterprise Flex framework. Consider, for
example, an RIA for opening new customer accounts in a bank or an
insurance company. This business process often starts with filling
multiple sections in a mile-long application form. In Flex, such an
application may turn into a <code class="literal">ViewStack</code>
of custom components with, say five forms totaling 50 fields. These
custom components and validators are physically stored in separate
files. Each section in a paper form can be represented as a content
of one section in an <code class="literal">Accordion</code> or
other navigator. Say you have total of 50 validators, but
realistically, you'd like to engage only those validators that are
relevant to the open section of the <code class=
"literal">Accordion</code>.</p>
<p>If an application developer decides to move a field from one
custom component to another, he needs to make appropriate changes
in the code to synchronize the old validators with a relocated
field.</p>
<p>What some of the form fields are used with view states? How
would you validate these moving targets? If you are adding three
fields when the <code class=
"literal">currentState="Details"</code>, you'd need manually write
<code class="literal">AddChild</code> statements in the state
section <code class="literal">Details</code>.</p>
<p>Say 40 out of these 50 validators are permanent, and the other
10 are used once in a while. But even these 40 you don't want to
use simultaneously hence you need to create, say two arrays having
20 elements each, and keep adding/removing temporary validators to
these arrays according to view state changes.</p>
<p>Even though it seems that Flex separates validators and field to
validate, this is not a real separation but rather a tight
coupling. What's the solution? For the customer accounts example,
you want a <code class="literal">ViewStack</code> with five custom
components, each of which has one <code class=
"literal">DataForm</code> whose elements have access to the entire
set of 50 fields, but that validates only its own set of 10. In
other words, all five forms will have access to the same 50-field
<code class="literal">dataProvider</code>. If during account
opening the user entered 65 in the field <span class=
"emphasis"><em>age</em></span> on the first form, the fifth form
may show fields with options to open a pension plan account, which
won't be visible for young customers.</p>
<p>That's why each form needs to have access to all data, but when
you need to validate only the fields that are visible on the screen
at the moment, you should be able to do this on behalf of this
particular <code class="literal">DataForm</code>. To accomplish all
this, we created a new class called <code class=
"literal">ValidationRule</code>. Our goal is not to replace
existing Flex validation routines, but rather offer you an
alternative solution that can be used with forms and list-based
controls. The next section demonstrates a sample application that
uses the class <code class="literal">ValidationRule</code>. After
that, you can take a look at the code under the hood.</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="sample_application_-_dataformvalidator"
id="sample_application_-_dataformvalidator"></a>Sample Application
&ndash; DataFormValidator</h3>
</div>
</div>
</div>
<p>The <span class=
"emphasis"><em>DataFormValidator.mxml</em></span> application
(<a href="#running_dataformvalidation_a" title=
"Figure&nbsp;3.5.&nbsp;Running DataFormValidation application">Figure&nbsp;3.5,
&ldquo;Running DataFormValidation application&rdquo;</a>) has two
<code class="literal">DataForm</code> containers located inside the
<code class="literal">HBox</code>. Pressing the button <span class=
"emphasis"><em>Save</em></span> initiates the validation of both
forms and displays the message if the entered data is valid or
not.</p>
<div class="figure"><a name="running_dataformvalidation_a" id=
"running_dataformvalidation_a"></a>
<p class="title"><b>Figure&nbsp;3.5.&nbsp;Running
DataFormValidation application</b></p>
<div class="figure-contents">
<div class="mediaobject"><a name="I_mediaobject3_d1e11436" id=
"I_mediaobject3_d1e11436"></a><img src="http://www.insideria.com/riaimages/edwf_0305.png"
alt="Running DataFormValidation application" /></div>
</div>
</div>
<br class="figure-break" />
<p>Here's the code of the <span class=
"emphasis"><em>DataFormValidation.mxml</em></span> application that
created these forms:</p>
<a name="I_programlisting3_d1e11446" id=
"I_programlisting3_d1e11446"></a>

<pre style="height: 600px;"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application width="100" height="100" layout="vertical"
    xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:fx="http://www.faratasystems.com/2008/components"
    creationComplete="onCreationComplete()"
    &gt;
    &lt;mx:VBox width="100" height="100" backgroundColor="white"&gt;
         &lt;mx:Label text="Submit Vacation Request"
               fontWeight="bold" fontSize="16" fontStyle="italic"
               paddingTop="10" paddingBottom="5" paddingLeft="10"
               /&gt;

        &lt;mx:HBox width="100" height="100" &gt;
          &lt;fx:DataForm id="left" width="100" dataProvider="{vacationRequestDTO}"&gt;
            &lt;fx:DataFormItem label="Employee Name: " fontWeight="bold"
             dataField="EMPLOYEE_NAME" required="true"
             validators="{[nameValidator, requiredValidator]}"&gt;
               &lt;mx:TextInput  fontWeight="normal" /&gt;
            &lt;/fx:DataFormItem&gt;
            &lt;fx:DataFormItem label="Employee Email: " fontWeight="bold"
              dataField="EMPLOYEE_EMAIL" required="true"
              validators="{[emailValidator]}"&gt;
                     &lt;mx:TextInput   fontWeight="normal"/&gt;
             &lt;/fx:DataFormItem&gt;
             &lt;fx:DataFormItem label="Employee Email: " fontWeight="bold"
               dataField="MANAGER_EMAIL" required="true"
               validators="{[emailValidator]}"&gt;
                &lt;mx:TextInput   fontWeight="normal"/&gt;
             &lt;/fx:DataFormItem&gt;
             &lt;fx:DataFormItem label="Department: " fontWeight="bold"
              dataField="DEPARTMENT" required="true"
              validators="{[requiredValidator]}"&gt;
                &lt;fx:TextInput fontWeight="normal"/&gt;
             &lt;/fx:DataFormItem&gt;
             &lt;mx:Spacer height="10"/&gt;
             &lt;fx:DataFormItem label="Description: " fontWeight="bold"
               dataField="DESCRIPTION"&gt;
                &lt;mx:TextArea width="200"  height="80" fontWeight="normal" /&gt;
             &lt;/fx:DataFormItem&gt;
          &lt;/fx:DataForm&gt;

          &lt;fx:DataForm id="right" width="100" dataProvider="{vacationRequestDTO}"&gt;
               &lt;fx:DataFormItem label="Start Date: " fontWeight="bold"
                dataField="START_DATE"  valueName="selectedDate" required="true"&gt;
                     &lt;mx:DateField fontWeight="normal"/&gt;
               &lt;/fx:DataFormItem&gt;
               &lt;fx:DataFormItem label="End Date: " fontWeight="bold"
                 dataField="END_DATE" valueName="selectedDate" required="true"&gt;
                     &lt;fx:DateField  fontWeight="normal"/&gt;
                       &lt;fx:validators&gt;
                          &lt;mx:Array&gt;
                           &lt;fx:ValidationRule
                               rule="{afterStartDate}"
                                errorMessage="End Date ($[END_DATE]) must be later
                             than Start Date $[START_DATE]"&gt;
                          &lt;/fx:ValidationRule&gt;
                          &lt;fx:ValidationRule
                               rule="{afterToday}"
                                errorMessage="End Date ($[END_DATE]) must be later
                             than today"&gt;
                          &lt;/fx:ValidationRule&gt;
                         &lt;/mx:Array&gt;
                     &lt;/fx:validators&gt;
               &lt;/fx:DataFormItem&gt;
               &lt;fx:DataFormItem label="Request Status: " fontWeight="bold"
                      dataField="STATUS"&gt;
                     &lt;mx:Label  fontWeight="normal"/&gt;
               &lt;/fx:DataFormItem&gt;
             &lt;/fx:DataForm&gt;
          &lt;/mx:HBox&gt;
    &lt;/mx:VBox&gt;
    &lt;mx:Button label="Save" click="onSave()"/&gt;

    &lt;mx:Script&gt;
          &lt;![CDATA[
               <span class=
"bold"><strong>import</strong></span> com.farata.datasource.dto.VacationRequestDTO;
               <span class=
"bold"><strong>import</strong></span> mx.utils.UIDUtil;

               [Bindable] <span class=
"bold"><strong>private var</strong></span> vacationRequestDTO:VacationRequestDTO ;
               <span class=
"bold"><strong>private function</strong></span> afterToday( val: Object) : Boolean {
                     <span class=
"bold"><strong>var</strong></span> b : Boolean = val.END_DATE &gt; <span class="bold"><strong>new</strong></span> Date();
                     <span class=
"bold"><strong>return</strong></span> b;
               }
               <span class=
"bold"><strong>private function</strong></span> afterStartDate( val: Object) : Boolean {
                     <span class=
"bold"><strong>var</strong></span> b : Boolean = val.END_DATE &gt; val.START_DATE;
                     <span class=
"bold"><strong>return</strong></span> b;
               }

               <span class=
"bold"><strong>private function</strong></span> onCreationComplete():<span class="bold"><strong>void</strong></span> {
                     <span class=
"emphasis"><em>// create a new vacation request</em></span>
                     vacationRequestDTO = <span class=
"bold"><strong>new</strong></span> VacationRequestDTO;
                     vacationRequestDTO.REQUEST_ID = UIDUtil.
createUID();
vacationRequestDTO.STATUS = <span class=
"bold"><strong>"Created"</strong></span>;
                                       vacationRequestDTO.START_DATE =
                              <span class=
"bold"><strong>new</strong></span> Date(<span class=
"bold"><strong>new</strong></span> Date().time + 1000 * 3600 * 24);
                     vacationRequestDTO.EMPLOYEE_NAME = <span class="bold"><strong>"Joe P"</strong></span>;
                         vacationRequestDTO.EMPLOYEE_EMAIL =
 <span class=
"bold"><strong>"jflexer@faratasystems.com"</strong></span>;
                     vacationRequestDTO.VACATION_TYPE =
 <span class="bold"><strong>"L"</strong></span>; <span class=
"emphasis"><em>//Unpaid leave - default</em></span>
               }

               <span class=
"bold"><strong>private function</strong></span> onSave():<span class="bold"><strong>void</strong></span>       {
                     <span class=
"bold"><strong>if</strong></span> (isDataValid()) {
                          mx.controls.Alert.show(<span class=
"bold"><strong>"Validation succedded"</strong></span>);
                     } <span class=
"bold"><strong>else</strong></span> {
                          mx.controls.Alert.show(<span class=
"bold"><strong>"Validation failed"</strong></span>);
                     }
               }

               <span class=
"bold"><strong>private function</strong></span> isDataValid():Boolean {
                     <span class=
"bold"><strong>var</strong></span> failedLeft:Array = left.validateAll();
                     <span class=
"bold"><strong>var</strong></span> failedRight:Array = right.validateAll();
                     <span class=
"bold"><strong>return</strong></span> ((failedLeft.length == 0)&amp;&amp;(failedRight.length == 0));
               }
          ]]&gt;
    &lt;/mx:Script&gt;

    &lt;mx:StringValidator id="nameValidator" minLength="6"
                  requiredFieldError="Provide your name, more than 5 symbols" /&gt;
    &lt;mx:EmailValidator id="emailValidator"
                  requiredFieldError="Provide correct email" /&gt;
    &lt;mx:StringValidator id="requiredValidator"
                  requiredFieldError="Provide non-empty value here" /&gt;
&lt;/mx:Application&gt;
</code></pre>

<p>On <code class="literal">creationComplete</code> event this
application creates an instance of the <code class=
"literal">vacationRequestDTO</code> that is used as a <code class=
"literal">dataProvider</code> for both left and right data
forms.</p>
<p>This code uses a mix of standard Flex validators (<code class=
"literal">StringValidator</code>, <code class=
"literal">EmailValidator</code>) and subclasses of <code class=
"literal">ValidatorRule</code>. Note that both email fields use the
same instance of the <code class="literal">EmailValidator</code>,
which is not possible with regular Flex validation routines:</p>
<a name="I_programlisting3_d1e11571" id=
"I_programlisting3_d1e11571"></a>

<pre><code>&lt;fx:DataFormItem label="Employee Email: " fontWeight="bold"
              dataField="EMPLOYEE_EMAIL" required="true"
              validators="{[emailValidator]}"&gt;
                     &lt;mx:TextInput   fontWeight="normal"/&gt;
             &lt;/fx:DataFormItem&gt;
             &lt;fx:DataFormItem label="Employee Email: " fontWeight="bold"
               dataField="MANAGER_EMAIL" required="true"
               validators="{[emailValidator]}"&gt;
                &lt;mx:TextInput   fontWeight="normal"/&gt;
             &lt;/fx:DataFormItem&gt;
</code></pre> 

<p>Notice that these validators are encapsulated inside the
<code class="literal">DataFormItem</code>. If application
programmers decide to add or remove some of the form item when the
view state changes, they don't need to program anything special to
ensure that validators work properly! The form item <span class=
"emphasis"><em>end date</em></span> encapsulates two validation
rules that are given as a closures <code class=
"literal">afterStartDate</code> and <code class=
"literal">afterToday</code>.</p>
<a name="I_programlisting3_d1e11587" id=
"I_programlisting3_d1e11587"></a>

<pre><code>&lt;fx:DataFormItem label="End Date: " fontWeight="bold"
                 dataField="END_DATE" valueName="selectedDate" required="true"&gt;
                     &lt;fx:DateField  fontWeight="normal"/&gt;
                       &lt;fx:validators&gt;
                          &lt;mx:Array&gt;
                           &lt;fx:ValidationRule
                               rule="{afterStartDate}"
                                errorMessage="End Date ($[END_DATE]) must be later
                             than Start Date $[START_DATE]"&gt;
                          &lt;/fx:ValidationRule&gt;
                          &lt;fx:ValidationRule
                               rule="{afterToday}"
                                errorMessage="End Date ($[END_DATE]) must be later
                             than today"&gt;
                          &lt;/fx:ValidationRule&gt;
                         &lt;/mx:Array&gt;
                     &lt;/fx:validators&gt;
               &lt;/fx:DataFormItem&gt;
</code></pre>

<p><code class="literal">...</code></p>
<a name="I_programlisting3_d1e11593" id=
"I_programlisting3_d1e11593"></a>


<pre><code><span class=
"bold"><strong>private function</strong></span> afterToday( val: Object) : Boolean {
    <span class=
"bold"><strong>var</strong></span> b : Boolean = val.END_DATE &gt; <span class="bold"><strong>new</strong></span> Date();
    <span class="bold"><strong>return</strong></span> b;
}

<span class=
"bold"><strong>private function</strong></span> afterStartDate( val: Object) : Boolean {
    <span class=
"bold"><strong>var</strong></span> b : Boolean = val.END_DATE &gt; val.START_DATE;
    <span class="bold"><strong>return</strong></span> b;
}
</code></pre>

<p>The code above does not include standard Flex validators inside
the <code class="literal">&lt;fx:validators&gt;</code>, but this is
supported too. For example, you can add the line in the
<code class="literal">validators</code> section of a <code class=
"literal">DataFormItem</code> right under the <code class=
"literal">&lt;mx:Array&gt;</code> tag.</p>
<a name="I_programlisting3_d1e11630" id=
"I_programlisting3_d1e11630"></a>

<pre><code>&lt;mx:StringValidator id="requiredValidator"
                  requiredFieldError="Provide non-empty value here" /&gt;
</code></pre>

<p>If you do it, you'll have three validators bound to the same
form item End Date: one standard Flex validator and two functions
with validation rules.</p>
<p>From the application programmer's perspective, using such
validation rules is simple. It allows reusing validators, which can
be nicely encapsulated inside the form items.</p>
<p>For brevity, the function <code class="literal">onSave()</code>
just displays a message box stating that the validation failed:</p>
<a name="I_programlisting3_d1e11641" id=
"I_programlisting3_d1e11641"></a>

<pre><code>mx.controls.Alert.show(<span class=
"bold"><strong>"Validation failed"</strong></span>);
</code></pre> 

<p>But if you run this application through a debugger and place a
breakpoint inside the function <code class=
"literal">isDataValid()</code>, you'll see that all validation
errors in the <code class="literal">failedLeft</code> and
<code class="literal">failedRight</code> arrays (<a href=
"#debugger_apostrophy_s_view_of_validation" title=
"Figure&nbsp;3.6.&nbsp;Debugger's View of validation errors">Figure&nbsp;3.6,
&ldquo;Debugger's View of validation errors&rdquo;</a>).</p>
<div class="figure"><a name=
"debugger_apostrophy_s_view_of_validation" id=
"debugger_apostrophy_s_view_of_validation"></a>
<p class="title"><b>Figure&nbsp;3.6.&nbsp;Debugger's View of
validation errors</b></p>
<div class="figure-contents">
<div class="mediaobject"><a name="I_mediaobject3_d1e11662" id=
"I_mediaobject3_d1e11662"></a><img src="http://www.insideria.com/riaimages/edwf_0306.png"
alt="Debugger's View of validation errors" /></div>
</div>
</div>
<br class="figure-break" />
<p>The next question is, "How does all this work?"</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="class_validationrule_explained" id=
"class_validationrule_explained"></a>Class ValidationRule
Explained</h3>
</div>
</div>
</div>
<p>Enhancing the original Flex validators, the new <code class=
"literal">ValidationRule</code> extends Flex <code class=
"literal">Validator</code> and is known to clear.swc's UI controls.
With it, developers can attach any number of validation rules to
any field of a form or a list-based component. This means you can
attach validation rules not only on the field level, but also on
the parent level, such as to a specific <code class=
"literal">DataGrid</code> column or to an entire row.</p>
<p>When we designed the class, our approach was to separate (for
real) validation rules from the UI component they validate. We also
made them reusable to spare application developers from
copy/pasting the same rule repeatedly. With the <code class=
"literal">ValidationRule</code> class you can instantiate each rule
once and reuse it across the entire application. Our goal was to
move away from one-to-one relations between a validator and a
single property of a form field, to many-to-many relations where
each field can request multiple validators and vice versa.</p>
<p>If you don't need to perform cross-field validation in the form,
you can continue using the original Flex validator classes. If you
need to validate, interdependent fields&mdash;say if the
<span class="emphasis"><em>amount</em></span> field has the value
greater than $10K you need to block overnight delivery of the
<span class="emphasis"><em>order</em></span> field until additional
approval is provided&mdash;use our more flexible extension,
<code class="literal">ValidationRule</code>.</p>
<p>We still want to be able to reuse the validators (<code class=
"literal">EmailValidator</code>, <code class=
"literal">StringValidator</code> et al.) that come with Flex, but
they should be wrapped in our class <code class=
"literal">ValidationRule</code>. On the other hand, with the class
ValidationRule the application developers should also be able to
write validation rules as regular functions, which requires less
coding.</p>
<p>The source code of the class <code class=
"literal">ValidationRule</code> that supports all this
functionality is listed in <a href="#class_validationrule"
title=
"Example&nbsp;3.17.&nbsp;Class ValidationRule">Example&nbsp;3.17,
&ldquo;Class ValidationRule&rdquo;</a>.</p>
<div class="example"><a name="class_validationrule" id=
"class_validationrule"></a>
<p class="title"><b>Example&nbsp;3.17.&nbsp;Class
ValidationRule</b></p>
<div class="example-contents">

<pre style="height: 600px;"><code><span class=
"bold"><strong>package</strong></span> com.farata.validators{
    <span class=
"bold"><strong>import</strong></span> mx.controls.Alert;
    <span class=
"bold"><strong>import</strong></span> flash.utils.describeType;

    <span class=
"bold"><strong>import</strong></span> mx.events.ValidationResultEvent;
    <span class=
"bold"><strong>import</strong></span> mx.validators.ValidationResult;
    <span class=
"bold"><strong>import</strong></span> mx.validators.Validator;

    <span class=
"bold"><strong>public class</strong></span> ValidationRule   <span class="bold"><strong>extends</strong></span> Validator{
        <span class=
"bold"><strong>public var</strong></span> args:Array = [];
        <span class=
"bold"><strong>public var</strong></span> wrappedRule:Function ;
        <span class=
"bold"><strong>public var</strong></span> errorMessage : String = <span class="bold"><strong>"[TODO] replace me"</strong></span>;
        <span class=
"bold"><strong>public var</strong></span> data:Object;

          <span class=
"bold"><strong>public function</strong></span> ValidationRule() {
               <span class="bold"><strong>super</strong></span>();
               required = <span class=
"bold"><strong>false</strong></span>;
          }
        <span class=
"bold"><strong>private function</strong></span> combineArgs(v:Object):Array {
               <span class=
"bold"><strong>var</strong></span> _args:Array = [v];
                     <span class=
"bold"><strong>if</strong></span>( args!=<span class=
"bold"><strong>null</strong></span> &amp;&amp; args.length&gt;0 )
                          _args[<span class=
"bold"><strong>"push"</strong></span>].apply(_args, args);
                     <span class=
"bold"><strong>return</strong></span>  _args;
        }

<span class=
"bold"><strong>        public function set</strong></span> rule(f:Object) : <span class="bold"><strong>void</strong></span> {
            <span class=
"bold"><strong>if</strong></span> (!(f <span class=
"bold"><strong>is</strong></span> Function)){
               Alert.show(<span class=
"bold"><strong>""</strong></span>+f, <span class=
"bold"><strong>"Incorrect Validation Rule"</strong></span> );
              <span class=
"bold"><strong>return;</strong></span> // You may throw an exception here
           }

            wrappedRule = <span class=
"bold"><strong>function</strong></span>(val:Object) :Boolean {
               <span class=
"bold"><strong>return</strong></span> f(val);
            }
       }

        <span class=
"bold"><strong>private function</strong></span> substitute(...rest):String {
            <span class=
"bold"><strong>var</strong></span> len:uint = rest.length;
            <span class=
"bold"><strong>var</strong></span> args:Array;
            <span class=
"bold"><strong>var</strong></span> str:String = <span class=
"bold"><strong>""</strong></span> + errorMessage;
            <span class=
"bold"><strong>if</strong></span> (len == 1 &amp;&amp; rest[0] <span class="bold"><strong>is</strong></span> Array){
                args = rest[0] <span class=
"bold"><strong>as</strong></span> Array;
                len = args.length;
            }
            <span class="bold"><strong>else</strong></span>{
                args = rest;
            }

            <span class=
"bold"><strong>for</strong></span> (<span class=
"bold"><strong>var</strong></span> i:int = 0; i &lt; len; i++){
                str = str.replace(<span class=
"bold"><strong>new</strong></span> RegExp(<span class=
"bold"><strong>"\\$\\["</strong></span>+i+<span class=
"bold"><strong>"\\]"</strong></span>, <span class=
"bold"><strong>"g"</strong></span>), args[i]);
            }
               <span class=
"bold"><strong>if</strong></span> ( args.length == 1 &amp;&amp; args[0] <span class="bold"><strong>is</strong></span> Object) {
               <span class=
"bold"><strong>var</strong></span> o:Object = args[0];
                  <span class=
"bold"><strong>for each</strong></span> (<span class=
"bold"><strong>var</strong></span> s:*  <span class=
"bold"><strong>in</strong></span> o){
                      str = str.replace(<span class=
"bold"><strong>new</strong></span> RegExp(<span class=
"bold"><strong>"\\$\\["</strong></span>+s+<span class=
"bold"><strong>"\\]"</strong></span>,
 <span class="bold"><strong>"g"</strong></span>), o[s]);
                  }

                  <span class=
"bold"><strong>var</strong></span> classInfo:XML = describeType(o);
                <span class=
"emphasis"><em>// List the object's variables, their values, and their types</em></span>.
             <span class=
"bold"><strong>for each</strong></span> (<span class=
"bold"><strong>var</strong></span> v:XML <span class=
"bold"><strong>in</strong></span> classInfo..variable) {
                      str = str.replace(<span class=
"bold"><strong>new</strong></span> RegExp(<span class=
"bold"><strong>"\\$\\["</strong></span>+v.@name+
<span class="bold"><strong>"\\]"</strong></span>, <span class=
"bold"><strong>"g"</strong></span>),
                                                                    o[v.@name]);
                }

            <span class=
"emphasis"><em>// List accessors as properties</em></span>.
                <span class=
"bold"><strong>for each</strong></span> (<span class=
"bold"><strong>var</strong></span> a:XML <span class=
"bold"><strong>in</strong></span> classInfo..accessor) {
                <span class=
"emphasis"><em>// Do not get the property value if it is write only</em></span>.
                 <span class=
"bold"><strong>if</strong></span> (a.@access != <span class=
"bold"><strong>'writeonly'</strong></span>) {
                           str = str.replace(<span class=
"bold"><strong>new</strong></span> RegExp(<span class=
"bold"><strong>"\\$\\["</strong></span>+a.@name+<span class=
"bold"><strong>"\\]"</strong></span>,
                                                            <span class="bold"><strong>"g"</strong></span>), o[a.@name]);
                 }
                }
               }
            <span class="bold"><strong>return</strong></span> str;
        }

    <span class=
"bold"><strong>override protected function</strong></span> doValidation(value:Object):Array{
             <span class=
"bold"><strong>var</strong></span> results:Array = [];

            <span class=
"bold"><strong>if</strong></span> (!wrappedRule(data))
                 results.push(<span class=
"bold"><strong>new</strong></span> ValidationResult(<span class=
"bold"><strong>true</strong></span>, <span class=
"bold"><strong>null</strong></span>, <span class=
"bold"><strong>"Error"</strong></span>,
                          substitute(combineArgs(data))));

            <span class=
"bold"><strong>return</strong></span> results;
        }
    <span class=
"bold"><strong>override public function</strong></span> validate(value:Object = <span class="bold"><strong>null</strong></span>,
                   suppressEvents:Boolean = <span class=
"bold"><strong>false</strong></span>):ValidationResultEvent{
        <span class=
"bold"><strong>if</strong></span> (value == <span class=
"bold"><strong>null</strong></span>)
            value = getValueFromSource();

        <span class=
"emphasis"><em>// if required flag is true and there is no value</em></span>
        <span class=
"emphasis"><em>// we need to generate a required field error</em></span>
        <span class=
"bold"><strong>if</strong></span> (isRealValue(value) || required){
            <span class=
"bold"><strong>return super</strong></span>.validate(value, suppressEvents);
        }
        <span class="bold"><strong>else</strong></span> {
            <span class=
"emphasis"><em>// Just return the valid value</em></span>
            <span class=
"bold"><strong>return new</strong></span> ValidationResultEvent(ValidationResultEvent.VALID);
        }
      }
    }
}
</code></pre>

</div>
</div>
<br class="example-break" />
<p>The superclass <code class="literal">Validator</code> has two
methods that will be overridden in its descendents: <code class=
"literal">doValidation()</code>, which initiates and performs the
validation routine, and the function <code class=
"literal">validate()</code>, which watches required arguments and
gets the values from the target UI control.</p>
<p>Notice this code fragment from the DataFormValidation
application:</p>
<a name="I_programlisting3_d1e12041" id=
"I_programlisting3_d1e12041"></a>

<pre><code>&lt;fx:ValidationRule rule="{afterStartDate}"
 errorMessage="End Date ($[END_DATE]) must be later than Start Date $[START_DATE]"&gt;
&lt;/fx:ValidationRule&gt;
</code></pre> 

<p>mentions the name of the function <code class=
"literal">afterStartDate</code> that alternatively could have been
declared inline as a closure. The function ensures that the date
being validated is older than the END_DATE.</p>
<a name="I_programlisting3_d1e12049" id=
"I_programlisting3_d1e12049"></a>

<pre><code><span class=
"bold"><strong>private function</strong></span> afterToday( val: Object) : Boolean {
    <span class=
"bold"><strong>var</strong></span> b : Boolean = val.END_DATE &gt; <span class="bold"><strong>new</strong></span> Date();
    <span class="bold"><strong>return</strong></span> b;
}
</code></pre> 

<p>In this code <code class="literal">val</code> points at the
<code class="literal">dataProvider</code> of the form, which, in
the sample application, is an instance of the <code class=
"literal">vacationRequestDTO</code>. An important point is that
both the <code class="literal">DataForm</code> and the <code class=
"literal">ValidationRule</code> see the same <code class=
"literal">dataProvider</code>.</p>
<p>The value of the <code class="literal">errorMessage</code>
attribute includes something that looks like a macro language:
<code class="literal">($[END_DATE])</code>. The function
<code class="literal">substitute()</code> finds and replaces via
regular expression the specified name (i.e. <code class=
"literal">END_DATE</code>) in all properties in the <code class=
"literal">dataProvider</code> with their values.</p>
<p>If <code class="literal">dataProvider</code> is a dynamic
object, the function <code class=
"literal">ValidationRule.substitute()</code> enumerates all its
properties via or <code class="literal">for each</code> loop. For
regular classes, Flex offers a reflection mechanism using the
function <code class="literal">describeType()</code> &ndash; give
it a class name and it'll return a definition of this class in a
form of XML. Then, the function <code class=
"literal">substitute()</code> gets all class variables and
<span class="emphasis"><em>accessors</em></span> (getters and
setters) and applies the regular expression to the <code class=
"literal">errorMessage</code> text.</p>
<p>For example, if you deal with a dynamic object <code class=
"literal">o</code> that has a property <code class=
"literal">END_DATE</code>, the following line will replace
<code class="literal">($[END_DATE])</code> in the error text with
the value of this property &ndash; <code class=
"literal">o[s]</code>:</p>
<a name="I_programlisting3_d1e12138" id=
"I_programlisting3_d1e12138"></a>

<pre><code>str = str.replace(new RegExp("\\$\\["+s+"\\]", "g"), o[s]);
</code></pre>

<p>The method <code class="literal">substitute()</code> is called
from <code class="literal">doValidate()</code>, and if the user
entered invalid dates (i.e. the start date is 12/10/2008 and the
end date 12/06/2008), the validator will find the properties called
<code class="literal">END_DATE</code> and <code class=
"literal">START_DATE</code> and turn this error text:</p>
<a name="I_programlisting3_d1e12154" id=
"I_programlisting3_d1e12154"></a>

<pre><code>"End Date ($[END_DATE]) must be later than Start Date $[START_DATE]"
</code></pre> 

<p>into this one:</p>
<a name="I_programlisting3_d1e12158" id=
"I_programlisting3_d1e12158"></a>

<pre><code>"End Date (12/06/2008) must be later than Start Date 12/10/2008"
</pre></code> 

<p>In Chapter&nbsp;2, <i>Selected Design Patterns</i> you learned how to write class factories that can wrap functions and return them as objects. This
technique is applied in the <code class=
"literal">ValidationRule</code> class too, which supports functions
as validators. If the application code uses the setter <code class=
"literal">rule</code> the function with business-specific
validation rules is expected.</p>
<p>The class <code class="literal">ValidationRule</code> has this
setter:</p>
<a name="I_programlisting3_d1e12176" id=
"I_programlisting3_d1e12176"></a>


<pre><code><span class=
"bold"><strong>public function set</strong></span> rule(f:Object) : <span class="bold"><strong>void</strong></span> {
          <span class=
"bold"><strong>if</strong></span> (!(f <span class=
"bold"><strong>is</strong></span> Function)){
             Alert.show(<span class=
"bold"><strong>""</strong></span>+f, <span class=
"bold"><strong>"Incorrect Validation Rule"</strong></span> );
            <span class="bold"><strong>return;</strong></span>
         }

          wrappedRule = <span class=
"bold"><strong>function</strong></span>(val:Object) :Boolean {
          <span class="bold"><strong>return</strong></span> f(val);
          }
}
</code></pre> 

<p>In the application DataFormValidation you can easily find this
setter has been used (we've already discussed the function
<code class="literal">afterStartDate</code> above):</p>
<a name="I_programlisting3_d1e12210" id=
"I_programlisting3_d1e12210"></a>

<pre><code>&lt;fx:ValidationRule
    rule="{afterStartDate}"
    errorMessage="End Date ($[END_DATE]) must be later
                    than Start Date $[START_DATE]"&gt;
&lt;/fx:ValidationRule&gt;
</code></pre>

<p>We hope you like the simplicity that <code class=
"literal">ValidationRule</code> offers to application developers
that have to validate forms. The next section examines a more
sample application that demonstrates the use of this class in a
<code class="literal">DataGrid</code> control.</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name=
"embedding_validation_rules_into_a_datagr" id=
"embedding_validation_rules_into_a_datagr"></a>Embedding Validation
Rules into a DataGrid</h3>
</div>
</div>
</div>
<p>As opposed to component libraries, classes in a framework depend
on each other. In this context is means that the <code class=
"literal">ValidationRule</code> class requires an enhanced
<code class="literal">DataGrid</code> component.</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>Please note that sample application shown below does uses
<code class="literal">DataGrid</code> and <code class=
"literal">DataGridItem</code> from a different namespace. These
classes are included in the clear.swc library and come with the
source code accompanying the book, but due to space constraints, we
won't include the source code of these objects here.</p>
</div>
<p>This example is yet another version of the Caf&eacute; Townsend
from Chapter&nbsp;1, <i>Comparing Selected Flex Frameworks</i>. For simplicity, the employee data are hard-coded and to run this application you don't
need to do any server-side setup.</p>
<p>This application is an example of a master-detail window with
validators embedded inside a data grid. <a href=
"#debugger_apostrophy_s_view_of_validation" title=
"Figure&nbsp;3.6.&nbsp;Debugger's View of validation errors">Figure&nbsp;3.6,
&ldquo;Debugger's View of validation errors&rdquo;</a> shows the
phone number having the wrong number of digits in the first row of
our <code class="literal">DataGrid</code> component. Embedded
validation rule properly reports an error message that reads "Wrong
length, need 10 digit number".</p>
<div class="figure"><a name="validating_the_phone_datagri" id=
"validating_the_phone_datagri"></a>
<p class="title"><b>Figure&nbsp;3.7.&nbsp;Validating the phone
DataGridColumn</b></p>
<div class="figure-contents">
<div class="mediaobject"><a name="I_mediaobject3_d1e12254" id=
"I_mediaobject3_d1e12254"></a><img src="http://www.insideria.com/riaimages/edwf_0307.png"
alt="Validating the phone DataGridColumn" /></div>
</div>
</div>
<br class="figure-break" />
<p>You can also assign validation rules to the form items that show
details of the selected row. In <a href=
"#validating_the_salary_datagr" title=
"Figure&nbsp;3.8.&nbsp;Validating the salary DataGridColumn">Figure&nbsp;3.8,
&ldquo;Validating the salary DataGridColumn&rdquo;</a> you can see
a validation error message stating that "Salary(9.95) is out of
reasonable range". All fields that have invalid values have red
borders. While examining the source code, please note, the dropdown
box Department that was populated using a resource file.</p>
<div class="figure"><a name="validating_the_salary_datagr" id=
"validating_the_salary_datagr"></a>
<p class="title"><b>Figure&nbsp;3.8.&nbsp;Validating the salary
DataGridColumn</b></p>
<div class="figure-contents">
<div class="mediaobject"><a name="I_mediaobject3_d1e12266" id=
"I_mediaobject3_d1e12266"></a><img src="http://www.insideria.com/riaimages/edwf_0308.png"
alt="Validating the salary DataGridColumn" /></div>
</div>
</div>
<br class="figure-break" />
<p>This version of the Caf&eacute; Townsend application uses the
following custom object Employee_getEmployees_gridFormTest:</p>
<div class="example"><a name="code_of_cafe_townsend_with" id=
"code_of_cafe_townsend_with"></a>
<p class="title"><b>Example&nbsp;3.18.&nbsp;Code of Caf&eacute;
Townsend with validations</b></p>
<div class="example-contents">

<pre style="height: 600px;"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mx:ViewStack height="100%" width="100%" xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:fx="http://www.faratasystems.com/2008/components"  creationPolicy="all"
    creationComplete="fill_onClick()"&gt;
&lt;fx:DataCollection id="collection" destination="com.farata.datasource.Employee"
          method="getEmployees"  collectionChange="<span class=
"bold"><strong>trace</strong></span>(event)"
                                                     fault="<span class="bold"><strong>trace</strong></span>(event)" /&gt;
&lt;mx:Canvas height="100%" width="100%"&gt;
    &lt;mx:Panel title="Employee List" width="100%" height="100%"&gt;
          &lt;fx:DataGrid id="dg"
               <span class=
"bold"><strong>itemRenderer="{new</strong></span>
      <span class=
"bold"><strong>UIClassFactory(com.farata.controls.dataGridClasses.DataGridItemRenderer)}"</strong></span>
          horizontalScrollPolicy="auto" width="100%" dataProvider="{collection}"
               editable="true" height="100%" rowHeight="25"&gt;
             &lt;fx:columns&gt;
               &lt;fx:DataGridColumn dataField="EMP_FNAME"  headerText="First Name"/&gt;
               &lt;fx:DataGridColumn dataField="EMP_LNAME"  headerText="Last Name"/&gt;
               &lt;fx:DataGridColumn dataField="DEPT_ID"   editable="false"
                  headerText="Department"
                  resource="{com.farata.resources.DepartmentComboResource}"/&gt;
               &lt;fx:DataGridColumn dataField="STREET"  headerText="Street"/&gt;
               &lt;fx:DataGridColumn dataField="CITY"  headerText="City"/&gt;
               &lt;fx:DataGridColumn dataField="STATE"  editable="false"
                  headerText="State"
                  resource="{com.farata.resources.StateComboResource}"/&gt;
               &lt;fx:DataGridColumn dataField="ZIP_CODE"  headerText="Zip Code"
                  formatString="zip" &gt;
                     &lt;fx:validators&gt;
                          &lt;mx:ZipCodeValidator /&gt;
                     &lt;/fx:validators&gt;
               &lt;/fx:DataGridColumn&gt;
               &lt;fx:DataGridColumn dataField="PHONE" headerText="Phone Number"
                  formatString="phone"  &gt;
                     &lt;fx:validators&gt;
                          <span class=
"bold"><strong>&lt;mx:Array&gt;</strong></span>
                                <span class=
"bold"><strong>&lt;mx:PhoneNumberValidator  wrongLengthError="Wrong</strong></span>
                                <span class=
"bold"><strong>length, need 10 digit number"/&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;/mx:Array&gt;</strong></span>
                     &lt;/fx:validators&gt;
               &lt;/fx:DataGridColumn&gt;

               &lt;fx:DataGridColumn dataField="STATUS"  headerText="Status"/&gt;

               &lt;fx:DataGridColumn dataField="SS_NUMBER" headerText="Ss Number"
                                                        formatString="ssn" &gt;
                     &lt;fx:validators&gt;
                          &lt;mx:SocialSecurityValidator/&gt;
                     &lt;/fx:validators&gt;
               &lt;/fx:DataGridColumn&gt;

               &lt;fx:DataGridColumn dataField="SALARY" headerText="Salary"
                                 formatString="currency(2)"&gt;
                     <span class=
"bold"><strong>&lt;fx:validators&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;mx:Array&gt;</strong></span>
                            <span class=
"bold"><strong>&lt;fx:ValidationRule</strong></span>
                            <span class=
"bold"><strong>rule="{function(data:Object):Boolean</strong></span>
                                  <span class=
"bold"><strong>{ return (data &amp;amp;&amp;amp;data.SALARY &gt; 10000</strong></span>
                                  <span class=
"bold"><strong>&amp;amp;&amp;amp; data.SALARY &amp;lt; 500000);}}"</strong></span>
                               <span class=
"bold"><strong>errorMessage="Salary ($[SALARY]) is out of reasonable</strong></span>
                                                                          <span class="bold"><strong>range"/&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;/mx:Array&gt;</strong></span>
                     <span class=
"bold"><strong>&lt;/fx:validators&gt;</strong></span>
               &lt;/fx:DataGridColumn&gt;

               &lt;fx:DataGridColumn dataField="START_DATE"  headerText="Start Date"
                itemEditor="mx.controls.DateField" editorDataField="selectedDate"
                formatString="shortDate"/&gt;

               &lt;fx:DataGridColumn dataField="TERMINATION_DATE"
                  headerText="Termination Date" itemEditor="mx.controls.DateField"
                  editorDataField="selectedDate" formatString="shortDate"&gt;
                     <span class=
"bold"><strong>&lt;fx:validators&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;fx:ValidationRule</strong></span>
                                <span class=
"bold"><strong>rule="{afterStartDate}"</strong></span>
                                <span class=
"bold"><strong>errorMessage="End Date ($[TERMINATION_DATE]) must be</strong></span>
                                            <span class=
"bold"><strong>later than Start Date $[START_DATE]"&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;/fx:ValidationRule&gt;</strong></span>
                     &lt;/fx:validators&gt;
               &lt;/fx:DataGridColumn&gt;

               &lt;fx:DataGridColumn dataField="BIRTH_DATE" headerText="Birth Date"
                  itemEditor="mx.controls.DateField" editorDataField="selectedDate"
                  formatString="shortDate"/&gt;

               &lt;fx:DataGridColumn dataField="BENE_HEALTH_INS"  headerText="Health"
                  resource="{YesNoCheckBoxResource}" rendererIsEditor="true"/&gt;

               &lt;fx:DataGridColumn dataField="BENE_LIFE_INS"  headerText="Life"
                  resource="{YesNoCheckBoxResource}"   rendererIsEditor="true"/&gt;

                &lt;fx:DataGridColumn dataField="BENE_DAY_CARE"  headerText="Day Care"
                  resource="com.farata.resources.YesNoCheckBoxResource"
                  rendererIsEditor="true"/&gt;

                &lt;fx:DataGridColumn dataField="SEX"  headerText="Sex"
                  resource="{SexRadioResource}" rendererIsEditor="true"/&gt;
            &lt;/fx:columns&gt;
    &lt;/fx:DataGrid&gt;

    <span class=
"bold"><strong>&lt;fx:DataForm dataProvider="{dg.selectedItem}"&gt;</strong></span>
          &lt;mx:HBox&gt;
               &lt;mx:Form&gt;
                     &lt;fx:DataFormItem dataField="EMP_ID" label="Emp Id:"/&gt;
                     &lt;fx:DataFormItem dataField="EMP_FNAME" label="First Name:"/&gt;
                     &lt;fx:DataFormItem dataField="STREET" label="Street:"/&gt;
                     &lt;fx:DataFormItem dataField="CITY" label="City:"/&gt;
                     &lt;fx:DataFormItem dataField="BIRTH_DATE" label="Birth Date:"
                       formatString="shortDate" required="true"/&gt;
                     &lt;fx:DataFormItem dataField="BENE_HEALTH_INS" label="Health:"
                       resource="{com.farata.resources.YesNoCheckBoxResource}"/&gt;
                     &lt;fx:DataFormItem dataField="STATUS" label="Status:"
                       resource="{com.farata.resources.StatusComboResource}"
                       required="true"/&gt;
               &lt;/mx:Form&gt;

               &lt;mx:Form&gt;
                     &lt;fx:DataFormItem dataField="MANAGER_ID" label="Manager Id:"/&gt;
                     &lt;fx:DataFormItem dataField="EMP_LNAME" label="Last Name:"/&gt;
                     &lt;fx:DataFormItem dataField="STATE" label="State:"
                       resource="com.farata.resources.StateComboResource"/&gt;
                     &lt;fx:DataFormItem dataField="SALARY" label="Salary:"
                       formatString="currency" textAlign="right"&gt;
                         &lt;fx:validators&gt;
                           <span class=
"bold"><strong>&lt;fx:ValidationRule rule="{function(data:Object):Boolean {</strong></span>
                            <span class=
"bold"><strong>return (data &amp;amp;&amp;amp;data.SALARY &gt; 10000 &amp;amp;&amp;amp;</strong></span>
                                   <span class=
"bold"><strong>data.SALARY &amp;lt; 500000);}}"</strong></span>
                              <span class=
"bold"><strong>errorMessage="Salary ($[SALARY]) is out</strong></span>
                                                           <span class="bold"><strong>of reasonable range"/&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;/fx:validators&gt;</strong></span>
                     &lt;/fx:DataFormItem&gt;
                     &lt;fx:DataFormItem dataField="START_DATE" label="Start Date:"
                                    formatString="shortDate"/&gt;
                     &lt;fx:DataFormItem dataField="BENE_LIFE_INS" label="Life:"
                          resource="{YesNoCheckBoxResource}"/&gt;
                     &lt;fx:DataFormItem dataField="SEX" label="Sex:"
                          resource="{SexRadioResource}"/&gt;
               &lt;/mx:Form&gt;
               &lt;mx:Form&gt;
                     &lt;fx:DataFormItem dataField="DEPT_ID" label="Department:"
                          resource="{DepartmentComboResource}"/&gt;
                     &lt;fx:DataFormItem dataField="SS_NUMBER" label="Ss Number:"
                          itemEditor="{com.farata.controls.MaskedInput}"
                                                         formatString="ssn"&gt;
                          &lt;fx:validators&gt;
                                &lt;mx:SocialSecurityValidator/&gt;
                          &lt;/fx:validators&gt;
                     &lt;/fx:DataFormItem&gt;
                     &lt;fx:DataFormItem dataField="ZIP_CODE" label="Zip Code:"
                                    formatString="zip"&gt;
                          &lt;fx:validators&gt;
                                &lt;mx:ZipCodeValidator /&gt;
                          &lt;/fx:validators&gt;
                     &lt;/fx:DataFormItem&gt;
                     &lt;fx:DataFormItem dataField="PHONE" label="Phone Number:"
                        itemEditor="{com.farata.controls.MaskedInput}"
                                    formatString="phone"&gt;
                          &lt;fx:validators&gt;
                                &lt;mx:PhoneNumberValidator
                                         wrongLengthError="keep typing"/&gt;
                          &lt;/fx:validators&gt;
                     &lt;/fx:DataFormItem&gt;
                     &lt;fx:DataFormItem dataField="TERMINATION_DATE"
                       label="Termination Date:" formatString="shortDate"&gt;
                          &lt;fx:validators&gt;
                                &lt;fx:ValidationRule
                                rule="{afterStartDate}"
                                errorMessage="End Date ($[TERMINATION_DATE]) must be
                               later than Start Date $[START_DATE]"&gt;
                             &lt;/fx:ValidationRule&gt;
                     &lt;/fx:validators&gt;
                  &lt;/fx:DataFormItem&gt;
                   &lt;fx:DataFormItem dataField="BENE_DAY_CARE" label="Day Care:"
                       resource="{YesNoCheckBoxResource}"/&gt;
               &lt;/mx:Form&gt;
          &lt;/mx:HBox&gt;
   &lt;/fx:DataForm&gt;
&lt;/mx:Panel&gt;

&lt;mx:HBox horizontalScrollPolicy="off" verticalAlign="middle" height="30"
                                                        width="100%"&gt;
 &lt;mx:Spacer width="100%"/&gt;
 &lt;mx:VRule strokeWidth="2" height="24"/&gt;
 &lt;mx:Button enabled="{dg.selectedIndex != &minus;1}"
            click="collection.removeItemAt(dg.selectedIndex)" label="Remove"
            icon="@Embed('/assets/delete_16x16.gif')"/&gt;
 &lt;mx:Button click="addItemAt(Math.max(0,dg.selectedIndex+1)) " label="Add"
            icon="@Embed('/assets/add_16x16.gif')" /&gt;
 &lt;mx:Label text="Deleted: {collection.deletedCount}"/&gt;
 &lt;mx:Label text="Modified: {collection.modifiedCount}"/&gt;
 &lt;/mx:HBox&gt;
&lt;/mx:Canvas&gt;

&lt;mx:Script&gt;    &lt;![CDATA[
    <span class=
"bold"><strong>import</strong></span> com.farata.controls.dataGridClasses.DataGridItemRenderer;
    <span class=
"bold"><strong>import</strong></span> com.farata.core.UIClassFactory;
    <span class=
"bold"><strong>import</strong></span> com.farata.collections.DataCollection;
    <span class=
"bold"><strong>import</strong></span> mx.collections.ArrayCollection;
    <span class=
"bold"><strong>import</strong></span> mx.controls.dataGridClasses.DataGridColumn;
    <span class=
"bold"><strong>import</strong></span> mx.events.CollectionEvent;
    <span class=
"bold"><strong>import</strong></span> com.farata.datasource.dto.EmployeeDTO;
    <span class=
"bold"><strong>import</strong></span> com.farata.resources.*;
    <span class=
"bold"><strong>import</strong></span> mx.validators.*;

    <span class=
"bold"><strong>private var</strong></span> linkage:EmployeeDTO = <span class="bold"><strong>null</strong></span>;

    <span class=
"bold"><strong>private function</strong></span> fill_onClick():<span class="bold"><strong>void</strong></span> {
          collection.source = Test.data;
          dg.selectedIndex=0;
    }

    <span class=
"bold"><strong>private function</strong></span> addItemAt(position:int):<span class="bold"><strong>void</strong></span>   {
          <span class=
"bold"><strong>var</strong></span> item:EmployeeDTO = <span class=
"bold"><strong>new</strong></span> EmployeeDTO();
          collection.addItemAt(item, position);
          dg.selectedIndex = position;
    }

    <span class=
"bold"><strong>import</strong></span> com.farata.resources.*;
    <span class=
"bold"><strong>import</strong></span> com.farata.controls.*;
    <span class=
"bold"><strong>private function</strong></span> afterStartDate( val: Object) : Boolean {
          <span class=
"bold"><strong>return</strong></span> !val.TERMINATION_DATE || val.TERMINATION_DATE &gt; val.START_DATE;
    }
    ]]&gt;
 &lt;/mx:Script&gt;
&lt;/mx:ViewStack&gt;
</code></pre> 

</div>
</div>
<br class="example-break" />
<p>When you review the code in <a href=
"#code_of_cafe_townsend_with" title=
"Example&nbsp;3.18.&nbsp;Code of Caf&eacute; Townsend with validations">
Example&nbsp;3.18, &ldquo;Code of Caf&eacute; Townsend with
validations&rdquo;</a>, you'll find different flavors of validation
rules inside the data grid columns in this implementation of the
Caf&eacute;. For example, the following rule is defined as an
anonymous function for the data grid column SALARY:</p>
<a name="I_programlisting3_d1e12447" id=
"I_programlisting3_d1e12447"></a>

<pre><code>&lt;fx:DataGridColumn dataField="SALARY" headerText="Salary"
                                 formatString="currency(2)"&gt;
                     <span class=
"bold"><strong>&lt;fx:validators&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;mx:Array&gt;</strong></span>
                            <span class=
"bold"><strong>&lt;fx:ValidationRule</strong></span>
                            <span class=
"bold"><strong>rule="{function(data:Object):Boolean</strong></span>
                                  <span class=
"bold"><strong>{ return (data &amp;amp;&amp;amp;data.SALARY &gt; 10000</strong></span>
                                  <span class=
"bold"><strong>&amp;amp;&amp;amp; data.SALARY &amp;lt; 500000);}}"</strong></span>
                               <span class=
"bold"><strong>errorMessage="Salary ($[SALARY]) is out of reasonable</strong></span>
                                                                          <span class="bold"><strong>range"/&gt;</strong></span>
                          <span class=
"bold"><strong>&lt;/mx:Array&gt;</strong></span>
                     <span class=
"bold"><strong>&lt;/fx:validators&gt;</strong></span>
               &lt;/fx:DataGridColumn&gt;
</code></pre> 

<p>If the data grid is populated and the salary in a particular
cell does not fall into the range between 10000 and 500000, this
function returns <code class="literal">false</code> and this data
value is considered invalid. Such cell(s) will immediately get the
red border and the error message will report the problem in the red
error tip right by this cell.</p>
<p>Some of the validation rules were repeated both in the
<code class="literal">DataGrid</code> and <code class=
"literal">DataForm</code>, but this doesn't have to be the case.
The same instances of the <code class=
"literal">ValidationRule</code> class can be reused as in the
<code class="literal">DataFormValidation</code> application.</p>
<p>The data for this sample application are hardcoded in Test.as,
which starts as follows:</p>
<a name="I_programlisting3_d1e12501" id=
"I_programlisting3_d1e12501"></a>

<pre><code>public class Test{

          public function Test(){
          }
          static public function get data() : Array {
               var e : EmployeeDTO = new EmployeeDTO;
               e.EMP_FNAME = "Yakov";
               e.EMP_LNAME = "Fain";
               e.BENE_DAY_CARE = "Y";
               e.BENE_HEALTH_INS = "Y";
               e.BENE_LIFE_INS = "N";
                ...
</code></pre>

<p>If you'd like to have deeper understanding of how <code class=
"literal">&lt;fx:DataGridColumn&gt;</code> works with embedded
validators, please examine the source code of the classes
<code class=
"literal">com.farata.controls.dataGridClasses.DataGridItem</code>
and <code class="literal">com.farata.controls.DataGrid</code> that
are included with the source code of accompanying this chapter.</p>
<p>We had to jump through a number of hoops to allow Flex
validators to communicate with the <code class=
"literal">DataGrid</code> as the class <code class=
"literal">Validator</code> expects to work only with sublcasses of
the <code class="literal">UIComponent</code> that are focusable
controls with borders. It's understandable &ndash; who needs to
validate, say a <code class="literal">Label</code>?</p>
<p>But we wanted to be able to display a red border around the cell
that has an invalid value and a standard error tip when the user
hovers the mouse pointer over the <code class=
"literal">DataGrid</code> cell. Hence we had to make appropriate
changes and replace the original <code class=
"literal">DataGrid.itemRederer</code> with our own that implements
<code class="literal">IValidatorListener</code> interface. An
<code class="literal">itemRenderer</code> on the <code class=
"literal">DataGrid</code> level affects all its columns.</p>
<a name="I_programlisting3_d1e12545" id=
"I_programlisting3_d1e12545"></a>

<pre><code>&lt;fx:DataGrid id="dg"
    <span class=
"bold"><strong>itemRenderer="{new UIClassFactory(</strong></span>
 <span class=
"bold"><strong>com.farata.controls.dataGridClasses.DataGridItemRenderer)}"</strong></span>
</code></pre>

<p>We've included this replacement of the <code class=
"literal">DataGridItemRenderer</code> in the demo application just
for illustration purposes to show that you can substitute the base
classes from Flex framework with your own. But as a developer of a
business framework, you should hide such code in the base
components, which in this case would have been a constructor of
your enhanced <code class="literal">DataGrid</code>.</p>
<p>Besides validation rules, it worth noting how master-detail
relations are implemented with just one line:</p>
<a name="I_programlisting3_d1e12563" id=
"I_programlisting3_d1e12563"></a>
<pre><code>&lt;fx:DataForm dataProvider="{dg.selectedItem}"&gt;
</code></pre>

<p>A selected row in a <code class="literal">DataGrid</code>
(master) is a <code class="literal">dataProvider</code> for a
<code class="literal">DataForm</code> (detail). With original Flex
<code class="literal">DataGrid</code> and <code class=
"literal">Form</code> components it would take a lot more coding to
properly re-bind the object representing a selected row that is
changing whenever the user selects a different one.</p>
<p>Once again, a well designed framework should allow application
developers to write less code. The code of this version of
Caf&eacute; Townsend is an example of what can be done in only
about 160 lines of code. It implements master-detail relations,
performs lots of custom validations, uses business style sheets.
Adding a couple of dozen lines of code can turn this application
into a CRUD built on the powerful <code class=
"literal">DataCollection</code> class that will be discussed in
Chapter 6.</p>
</div>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name=
"minimizing_the_number_of_custom_events" id=
"minimizing_the_number_of_custom_events"></a>Minimizing the Number
of Custom Events</h2>
</div>
</div>
</div>
<p>Up till now, you've concentrated on building rich components for
a business framework. We Flex architects should also recommend some
coding techniques that serve the same goal as these components:
enabling application developers to write less code. In this section
you'll see how to minimize the number of custom event classes in
any application.</p>
<p>Flex is all about event-driven development. Create loosely
coupled custom components and let them send events to each other as
in the Mediator pattern example from Chapter&nbsp;2,
<i>Selected Design Patterns</i>. You can create new events for
every occasion. If an event does not need to carry any additional
data, just give it a name, specify its type as <code class=
"literal">flash.events.Event</code>, and define the meta-tag to
help Flex Builder list this event in its type-ahead prompts and
dispatch it when appropriate. If your new event needs to carry some
data, create an ActionScript class extending <code class=
"literal">flash.events.Event</code>, define a variable in this
subclass to store application data, and override the method
<code class="literal">clone()</code>.</p>
<p>Currently, for a mid-size Flex application that includes about
30 views, where each view has two components that can send/receive
just one custom event, for example, you face the need to write 60
custom event classes that look pretty much the same. We'll show you
how to get away with just <span class=
"emphasis"><em>one</em></span> custom event class for the
<span class="emphasis"><em>entire</em></span> application.</p>
<p>To illustrate the concept, we've created a simple application
that defines one event class that can serve multiple purposes. This
application consists of two modules (<code class=
"literal">GreenModule</code>, shown in <a href=
"l#the_greenmodule_is_loaded" title=
"Figure&nbsp;3.9.&nbsp;The GreenModule is loaded">Figure&nbsp;3.9,
&ldquo;The GreenModule is loaded&rdquo;</a>, and <code class=
"literal">RedModule</code>) that are loaded in the same area of the
main application on the click of one of the load buttons. It also
has one universal event class called <code class=
"literal">ExEvent</code>.</p>
<div class="figure"><a name="the_greenmodule_is_loaded" id=
"the_greenmodule_is_loaded"></a>
<p class="title"><b>Figure&nbsp;3.9.&nbsp;The GreenModule is
loaded</b></p>
<div class="figure-contents">
<div class="mediaobject"><a name="I_mediaobject3_d1e12629" id=
"I_mediaobject3_d1e12629"></a><img src="http://www.insideria.com/riaimages/edwf_0309.png"
alt="The GreenModule is loaded" /></div>
</div>
</div>
<br class="figure-break" />
<p>Clicking any Send button creates an instance of this event
that's ready to carry an application-specific pay load: a DTO, a
couple of <code class="literal">String</code> variables, or any
other object.</p>
<p><a href="#the_greenmodule_is_loaded" title=
"Figure&nbsp;3.9.&nbsp;The GreenModule is loaded">Figure&nbsp;3.9,
&ldquo;The GreenModule is loaded&rdquo;</a>'s example uses an
ActionScript class called <code class=
"literal">GirlfriendDTO</code>. No Cairngorm-style mapping is
required between the event being sent and the modules. For example,
if you send <code class="literal">Green</code> event to the
<code class="literal">RedModule</code>, nothing happens since the
latter is not listening to <code class="literal">Green</code>
event.</p>
<p>This application and its source code are deployed at <a href=
"http://tinyurl.com/5n5qkg" target=
"_top">http://tinyurl.com/5n5qkg</a>.</p>
<p>Flex Builder's project has a folder called <span class=
"emphasis"><em>modules</em></span> that contains two modules:
<code class="literal">RedModule</code> and <code class=
"literal">GreenModule</code>. The red one is listening for the
arrival of the girlfriend's first and last name packaged in our
single event class as the two separate strings listed in <a href=
"#redmodule.mxml" title=
"Example&nbsp;3.19.&nbsp;RedModule.mxml">Example&nbsp;3.19,
&ldquo;RedModule.mxml&rdquo;</a>.</p>
<div class="example"><a name="redmodule.mxml" id=
"redmodule.mxml"></a>
<p class="title"><b>Example&nbsp;3.19.&nbsp;RedModule.mxml</b></p>
<div class="example-contents">

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    width="100%" height="100%" creationComplete="onCreationComplete(event)"&gt;
    &lt;mx:TextArea id="display" backgroundColor="#FF4949"  width="100%" height="100%"
                                                      fontSize="28"/&gt;
        &lt;mx:Script&gt;
        &lt;![CDATA[
    private function onCreationComplete(evt:Event):void{
        this.addEventListener("RedGirlfriend", onRedGirlfriend);
        }

    private function onRedGirlfriend(evt:ExEvent):void{
        display.text="My girlfriend is "+ evt.fName+ " " + evt.lName ;
        }
        ]]&gt;
    &lt;/mx:Script&gt;
&lt;/mx:Module&gt;
</code></pre>
</div>
</div>
<br class="example-break" />
<p>The green module expects the girlfriend's name in a form of
<code class="literal">GirlfriendDTO</code>.</p>
<div class="example"><a name="greenmodule" id="greenmodule"></a>
<p class="title"><b>Example&nbsp;3.20.&nbsp;GreenModule</b></p>
<div class="example-contents">
<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
       width="100%" height="100%" creationComplete="onCreationComplete(event)"&gt;
    &lt;mx:TextArea id="display" backgroundColor="#9CE29C" width="100%"
                   height="100%" color="#070707" fontSize="28"/&gt;
    &lt;mx:Script&gt;
        &lt;![CDATA[
        import dto.GirlfriendDTO;

        private function onCreationComplete(evt:Event):void{
          this.addEventListener("GreenGirlfriend", onGreenGirlfriend);
        }

        private function onGreenGirlfriend(evt:ExEvent):void{
         var myGirlfriend:GirlfriendDTO=evt["girlfriend"];

         display.text="My girlfriend is "+ myGirlfriend.fName+ " " +
                                                 myGirlfriend.lName ;
         }
        ]]&gt;
    &lt;/mx:Script&gt;
&lt;/mx:Module&gt;
</code></pre>
</div>
</div>
<br class="example-break" />
<p>The <code class="literal">GirlfriendDTO</code> is pretty
straightforward too, as <a href="#girlfrienddto" title=
"Example&nbsp;3.21.&nbsp;GirlFriendDTO">Example&nbsp;3.21,
&ldquo;GirlFriendDTO&rdquo;</a> shows.</p>
<div class="example"><a name="girlfrienddto" id=
"girlfrienddto"></a>
<p class="title"><b>Example&nbsp;3.21.&nbsp;GirlFriendDTO</b></p>
<div class="example-contents">

<pre><code>package dto
/**
 * This is a sample data transfer object (a.k.a. value object)
 */
{
    public class GirlfriendDTO {
         public var fName:String; // First name
         public var lName:String; // Last name
    }
}
</code></pre> </div>
</div>
<br class="example-break" />
<p>The next step is to create a single but universal event class.
It will be based on the <code class="literal">DynamicEvent</code>
class, which allows you to add any properties to the event object
on the fly. For the example, <code class=
"literal">GirlfriendDTO</code> is the object. Here's how dynamic
event can carry the GirlfriendDTO:</p>
<a name="I_programlisting3_d1e12707" id=
"I_programlisting3_d1e12707"></a>
<pre><code>var myDTO:GirlfriendDTO=new GirlfriendDTO();
            myDTO.fName="Mary";
            myDTO.lName="Poppins";

            var greenEvent:ExEvent=new ExEvent("GreenGirlfriend");
            greenEvent.girlfriend=myDTO;
            someObject.dispatchEvent(greenEvent);
</code></pre>

<p>Sending any arbitrary variables with this event will be
straightforward:</p>
<a name="I_programlisting3_d1e12711" id=
"I_programlisting3_d1e12711"></a>
<pre><code>var redEvent:ExEvent=new ExEvent("RedGirlfriend");

            redEvent.fName="Mary";
            redEvent.lName="Poppins";
            someObject.dispatchEvent(redEvent);
</code</pre>

<p>The <code class="literal">ExEvent</code> is a subclass of
<code class="literal">DynamicEvent</code>, which has a little
enhancement eliminating manual programming of the property
<code class="literal">Event.preventDefault</code>:</p>
<a name="I_programlisting3_d1e12724" id=
"I_programlisting3_d1e12724"></a>

<pre><code>package{
    import mx.events.DynamicEvent;
    public dynamic class ExEvent extends DynamicEvent{
        private var m_preventDefault:Boolean;

        public function ExEvent(type:String, bubbles:Boolean = false,
                                         cancelable:Boolean = false)     {
            super(type, bubbles, cancelable);
            m_preventDefault = false;
        }

         public override function preventDefault():void         {
            super.preventDefault();
            m_preventDefault = true;
        }

        public override function isDefaultPrevented():Boolean     {
            return m_preventDefault;
        }
    }
}
</code></pre> 

<p>The function <code class="literal">preventDefault()</code> is
overridden because the class <code class=
"literal">DynamicEvent</code> does not automatically process
<code class="literal">preventDefault</code> in cloned events</p>
<p>The code of the test application below loads modules, and then
the user can send any event to whatever module is loaded at the
moment. Of course, if the currently loaded module does not have a
listener for the event you're sending, tough luck. But the good
news is that it won't break the application either, as shown in
<a href="#an_application_that_tests" title=
"Example&nbsp;3.22.&nbsp;An application that tests generic event ExEvent">
Example&nbsp;3.22, &ldquo;An application that tests generic event
ExEvent&rdquo;</a>.</p>
<div class="example"><a name="an_application_that_tests" id=
"an_application_that_tests"></a>
<p class="title"><b>Example&nbsp;3.22.&nbsp;An application that
tests generic event ExEvent</b></p>
<div class="example-contents">

<pre style="height: 600px;"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="vertical" viewSourceURL="srcview/index.html"&gt;
 &lt;mx:HBox&gt;
    &lt;mx:Button label="Load the Green Module"
          click="loadMyModule('modules/GreenModule.swf')"/&gt;
    &lt;mx:Button label="Load the Red module"
          click="loadMyModule('modules/RedModule.swf')"/&gt;
    &lt;mx:Button label="Send Green Event with Object" click="sendGreen()"/&gt;
    &lt;mx:Button label="Send Red Event Event with two strings" click="sendRed()"/&gt;

 &lt;/mx:HBox&gt;

&lt;mx:Panel width="100%" height="100%" title="A module placeholder"
                                                    layout="absolute"&gt;
  &lt;mx:ModuleLoader id="theModulePlaceholder" width="100%" height="100%"/&gt;
&lt;/mx:Panel&gt;
&lt;mx:Script&gt;
    &lt;![CDATA[
        import dto.GirlfriendDTO;
        //Load the module specified in the moduleURL
        private function loadMyModule(moduleURL:String):void{
            theModulePlaceholder.url=moduleURL;
            theModulePlaceholder.loadModule();
        }

        // Sending generic  ExEvent adding an object that contains
        // the name of the girlfriend
        private function sendGreen():void{

            // Strongly typed DTO - better performance and readability,
            // but its structure has to be known for both parties -
            // the main application and the module
            var myDTO:GirlfriendDTO=new GirlfriendDTO();
            myDTO.fName="Mary";
            myDTO.lName="Poppins";

            if (theModulePlaceholder.child !=null){
                var greenEvent:ExEvent=new
                                          ExEvent("GreenGirlfriend");
                greenEvent.girlfriend=myDTO;

                theModulePlaceholder.child.dispatchEvent(greenEvent);
            }
        }

    // Sending a generic ExEvent that holds the name of the girlfriend
    // as two separate variables
        private function sendRed():void{
                var redEvent:ExEvent=new ExEvent("RedGirlfriend");

                redEvent.fName="Angelina";
                redEvent.lName="YouKnowWho";

                if (theModulePlaceholder.child !=null){
                theModulePlaceholder.child.dispatchEvent(redEvent);
                }
        }
    ]]&gt;
&lt;/mx:Script&gt;
&lt;/mx:Application&gt;
</code></pre> 

</div>
</div>
<br class="example-break" />
<p>The function <code class="literal">sendGreen()</code> sends an
instance of <code class="literal">ExEvent</code> carrying the DTO
inside, while the <code class="literal">sendRed()</code> just adds
two properties <code class="literal">fName</code> and <code class=
"literal">lName</code> to the instance of <code class=
"literal">ExEvent</code>.</p>
<p>Instead of using a DTO, you could've used a weakly typed data
transfer object:</p>
<a name="I_programlisting3_d1e12770" id=
"I_programlisting3_d1e12770"></a>

<pre><code>var myDTO:Object={fname:"Mary",lname:"Poppins"};
</code></pre> 

<p>But this may result in a tiny bit slower performance and the
code would be less readable. On the positive side, there would be
no need to explicitly define and share the class structure of the
DTO between the application (the mediator) and the module. You can
use this technique for creating quick and dirty prototypes.</p>
<p>To summarize, using a single dynamic event spares you from
tedious coding of dozens of similar event classes. On the negative
side, because this solution does not use the metatag <code class=
"literal">Event</code> declaring the names of the events, Flex
Builder won't be able to help you with the name of the event in its
type-ahead help.</p>
<p>In vast majority of RIAs you can afford to lose a couple of
milliseconds caused by using dynamic event. Using a single dynamic
event is one more step toward minimizing the code to be written for
your project.</p>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="summary" id=
"summary"></a>Summary</h2>
</div>
</div>
</div>
<p>In this chapter you learned by example how to start enhancing
the Flex framework with customized components and classes, such as
<code class="literal">CheckBox, ComboBox, DataGrid, DataForm,
DataFormItem, ValidationRule</code>. You also saw how to use these
components in your applications. The source code for this chapter
comes as two Flex Builder projects &ndash; Business Framework that
includes sample applications discussed in this chapter and Business
Framework Library that includes a number of enhanced Flex
components (some of them were shown here in simplified form) that
can be used in your projects too.</p>
<p>The clear.swc component library is offered for free under MIT
license as a part of the open source framework Clear Toolkit&ndash;
just keep the comments in the source code giving credits to Farata
Systems as the original creator of this code. You can find out the
up to date information about all components included into Clear
Toolkit by visiting popular open source repository Sourceforge, or
to be more specific, the following URL: <a href=
"https://sourceforge.net/projects/cleartoolkit" target=
"_top">https://sourceforge.net/projects/cleartoolkit</a>. Make sure
that you've tested theses components thoroughly before using them
in production systems.</p>
<p>In this chapter we reviewed and explained why and how we
extended several Flex components. We started with simpler
<code class="literal">CheckBox</code> and <code class=
"literal">ComboBox</code> components just because it was easier to
illustrate the process of extending of components. But then we did
some heavy lifting and extend such important for every enterprise
developer Flex components as <code class="literal">Form</code> and
<code class="literal">Vailidator</code>. You've seen working
example application that would integrate validators into a
<code class="literal">DataForm</code> and <code class=
"literal">DataGrid</code> componens.</p>
<p>Besides extending components, we've shown you some best
practices (using resources and writing single-even applications)
that greatly minimize the amount of code that application
developers have to write.</p>
<p>You'll see more of extended components in Chapters 6, 9, and 11.
But now let's discuss convenient third party tools that can be
handy for any Flex team working on an enterprise project.</p>
</div>]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2009://34.36127-comment:2070370</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2009://34.36127" type="text/html" href="http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html#comment-2070370" />
    <title>Comment from George on 2009-08-14</title>
    <author>
        <name>George</name>
        <uri>http://hktour.blogspot.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://hktour.blogspot.com">
        <![CDATA[<p>I am facing a problem about cross field validation across 3 text fields, say TEXT_1, TEXT_2 and TEXT_3.</p>

<p>The validation rule is that:</p>

<p>Either<br />
  TEXT_1 must be input<br />
Or<br />
  (TEXT_2 Or TEXT_3) must be input.</p>

<p>I want to know how to use the Class ValidationRule to do that?</p>

<p>thanks<br />
George</p>

<p><br />
</p>]]>
    </content>
    <published>2009-08-14T08:28:13Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2009://34.36127-comment:2070400</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2009://34.36127" type="text/html" href="http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/05/building-an-enterprise-framewo-1.html#comment-2070400" />
    <title>Comment from David Arakea on 2009-08-14</title>
    <author>
        <name>David Arakea</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Got a little confused at embedding validation in data grid. Thanks for the info. It is very handy for my work!</p>

<p><a href="http://www.bukisa.com/articles/76468_skull-and-crossbones-shirt">Skull and Crossbones t-shirt</a></p>]]>
    </content>
    <published>2009-08-14T21:07:53Z</published>
  </entry>

</feed
