Welcome!

ColdFusion Authors: Maureen O'Gara, Hovhannes Avoyan, Yakov Fain, Pat Romanski, Liz McMillan

Related Topics: ColdFusion, Adobe Flex

ColdFusion: Article

Adobe Flex 2: Advanced DataGrid

Drop-in RadioButtonGroupBox; runtime computed styles vs itemRenderers; masked input and numeric input controls

Like for all other components in this series of articles, we have added a MaskedInput to theriabook.swc and registered it in the component manifest file - theriabook-manifest.xml. The only modifications we made to the original MaskedInput were changing the original packaging of MaskedInput to com.theriabook.controls and overriding the implementation of the TextInput data setter to accommodate its use in the DataGrid:

public override function set data(data:Object):void {
    super.data = data;
    var dgListData:DataGridListData = DataGridListData(listData);
    text = data[dgListData.dataField];
}

The complete code for com.theriabook.controls.MaskedInput as well of all other samples from this article are available at http://samples.faratasystems.com/AdvancedDataGrid/index.html .

The second mask that we present in this section is NumericInput. It doesn't control the insertion point so typing and pasting is not restricted. However, it blocks any typing or pasting that contains invalid characters. Listing 10 shows the first iteration of NumericInput code.

As you can see in the listing, we listen to TextEvent.TEXT_INPUT, which corresponds to a character or a sequence of characters (paste) entered by the user. Whatever has been entered comes as an event.text and we test it with a regular expression, trying to find illegal characters. The string literal that we used for RegExp reads as "anything but characters in the range 0-9 or comma or dot or minus." If an illegal character is found, we reject the typing or pasting by cancelling the default behavior of the event with:

event.preventDefault();

That's all it takes to bullet proof your input fields from undesired characters. Two more small patches before we leave the NumericInput, though.

In the course of marshalling the Java data across the wire, chances are your numeric data will come as Number.NaN, a direct counterpart of Java Double.NaN or Float.NaN. In general, unless you use special DTOs with embedded null indicators; this is the natural way to marshal numeric nulls. No one would appreciate the lettering NaN staring at the user instead of the empty cell. Following the established pattern, we are going to make our NumericInput cognizant of the value, then have it produce the appropriate text as required for the presentation. Hence the following addition to NumericInput code:

private var _value:*;
[Bindable("change")]
public function set value(v:*):void {
   _value = v;
    if ((isNaN(v)) || (v==null /*null or undefined*/)) {
     text="";
    } else {
     text = String(v as Number);
    }
}

public function get value():* {
   // Preserve NaN | null | undefined, when nothing has been entered
     if (((_value!=null )&& (String(_value)!="NaN")) || (text!="") ) {
     _value = Number(text.replace(/,/g,"")); // deformat first
     }
     return _value;
   }

   public override function set data(item:Object):void {
if (listData && listData is DataGridListData) {
     var dgListData:DataGridListData = DataGridListData(listData);
     value = item[dgListData.dataField];
    }
    super.data = item;
   }

In the code fragment above we intervened in the setter for data property for when NumericInput is embedded in the DataGrid as a renderer. There we modify the value and let the value, in turn, modify the text.

In the value getter we return the original content: null, undefined, or Number.NaN, provided the user has not entered anything. Otherwise, we use a regular expression to convert the text to a Number, globally eliminating the spaces and the thousand separators first:

_value = Number(text.replace(/,/g,""));

Strictly speaking, we should have operated with a locale-specific thousands separator character instead of ",". For reference, U.S. English-specific definitions of String constants decimalSeparator and thousandsSeparator ("." and ",") are located in the file Flex SDK/ 2/frameworks/locale/en_US/validator.properties.

If you are delivering your application to Brazil, you could create a similar or smaller file in the Flex SDK/ 2/frameworks/locale/pr_BR folder, where you would redefine decimalSeparator as "," and thousandsSeparator as ".". Supposedly you would keep the original name - validators.properties. Then you would modify the compiler options for theriabook.swc to specify the pr_BR locale and rebuild NumericInput after adding the following code:

     import mx.resources.ResourceBundle;

   import mx.resources.ResourceBundle;

public class NumericInput extends TextInput {

. . . .

[ResourceBundle("validators")]
private static var rb:ResourceBundle;

public static var decimalSeparator:String;
public static var thousandsSeparator:String;

// Load resources during class definition loading
loadResources();

private static function loadResources():void {
     decimalSeparator = rb.getString("decimalSeparator");
     thousandsSeparator = rb.getString("thousandsSeparator");
}
}

Let's move on and present the testing application - NumericInputDemo. When you run it, try to type anything but digits, a comma and dot into the "Number" column; you won't be able to. Again, please make no mistake: NumericInput is a light-weight mask and it does not replace a need for validation. In particular, if you like regular expressions as much as we do, you may base the validation of the currency field on the mx.vaidators.RegExpValidator applying the regular expression which is the best match for your use case, for instance, something like:

^\$?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}[0-9]
{0,}(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)

Another feature to notice while running the demo app is how NaN, null, and undefined values are preserved in the absence of a meaningful input in the corresponding cells (see Figure 6).

The code of the testing application is shown in Listing 11, and the helper class NumberScope.as is presented in Listing 12.

Finally, Listing 13 depicts the complete code for NumericInput.

Summary
In this article we've continued our journey into not so obvious techniques of working with Adobe Flex DataGrid. In the final version of the article, we'll talk about data grids with dynamically computed item editors, data-driven programming and pivoted data grid.

More Stories By Victor Rasputnis

Dr. Victor Rasputnis is a Managing Principal of Farata Systems. He's responsible for providing architectural design, implementation management and mentoring to companies migrating to XML Internet technologies. He holds a PhD in computer science from the Moscow Institute of Robotics. You can reach him at vrasputnis@faratasystems.com

More Stories By Yakov Fain

Yakov Fain is a Managing Director of Farata Systems, consulting, training and product company. He has authored several Java books, dozens of technical articles. SYS-CON Books released his latest co-authored book , Rich Internet Applications with Adobe Flex and Java: Secrets of the Masters in Spring 2007. Sun Microsystems has nominated and awarded Yakov with the title Java Champion. He leads the Princeton Java Users Group. He is an Adobe Certified Flex Instructor. Currently Yakov works on the book for O'Reilly "Enterprise Application Development with Flex". He twits at twitter.com/yfain.

More Stories By Anatole Tartakovsky

Anatole Tartakovsky is a Managing Principal of Farata Systems. He's responsible for creation of frameworks and reusable components. Anatole authored number of books and articles on AJAX, XML, Internet and client-server technologies. He holds an MS in mathematics. You can reach him at atartakovsky@faratasystems.com

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
CFDJ News Desk 12/17/06 11:15:01 PM EST

In Part 1 (CFDJ, Vol. 8, issue 10) we introduced the destination-aware grid, formatters, and renderers. In this article we are continuing our discussion about datagrid renderers and...