sexta-feira, 1 de julho de 2011

Using commas instead of dots to represent decimal numbers in Flex NumericStepper

When we need to specify a decimal number here in Brazil (and in many other countries) we usually do not use dots. We use commas. So, instead of writing U$1.26 to represent one dollar and twenty-six cents, we write U$1,26.

The problem is that when we're using a Flex NumericStepper there isn't a place to set this. The only way I've found to get NumericStepper working with commas was to change the behaviour of the NumericStepper's TextInput. So I've created a different TextInput, called BrazilianNumberTextInput. Here it is:

package com.blogspot.wagnermezaroba.components
{
import mx.controls.TextInput;

public class BrazilianNumberTextInput extends TextInput {

override public function get text():String {
var t:String = super.text;
if ( t != null )
t = t.replace(/\./g, '').replace(/,/g, '.');
return t;
}
}
}


What I've done is simple. I replaced all the dots for nothing (that was the desired effect that we needed) and all the commas for dots. So NumericStepper will be able to parse the values. But we need to set NumericStepper to use our new TextInput component. I've done this in my css file:

mx|NumericStepper {
textInputClass: ClassReference("com.blogspot.wagnermezaroba.components.BrazilianNumberTextInput");
}


It's an ugly solution. But I haven't found any solution on the internet and so far I do not believe there is a different way to go.

And that's it. If you're going to use it, it would be good to set the restrict property, to constrain the user input and allow just numbers and commas.

terça-feira, 31 de maio de 2011

Enter working as Tab in a Flex DataGrid

If you're using a Flex DataGrid with the editable property set to true, the default behaviour of the Tab key is moving from one editable cell to another one while the Enter key move from one row to another one. There isn't any DataGrid option to easily make Enter key behaves like Tab key. And you can't override the KEY_DOWN event handler method of the DataGrid directly. However, you can register your own handler with a higher priority than the default DataGrid handler. By doing this, your handler will be called before DataGrid handler giving you the possibility to customize the action of the pressed keys. That's what we're going to do.


In your own handler you can check if the pressed key is Enter and than simply stop the propagation of the KeyboardEvent. Ok, this disables the default Enter event. But how can we make Enter works as Tab? We can just dispatch a fake KEY_FOCUS_CHANGE event. And that's it! Let's see the code:



public class CustomDataGrid extends DataGrid {

public function CustomDataGrid() {
super();
}

/*
* After Flex register its own handler in the createItemEditor method,
* we register our event listener with a higher priority (100).
*/
override public function createItemEditor(colIndex:int, rowIndex:int):void {
super.createItemEditor(colIndex, rowIndex);
DisplayObject(itemEditorInstance).addEventListener(KeyboardEvent.KEY_DOWN, onEditorKeyDown, false, 100);
}

/*
* If the pressed key is Enter, stop the propagation and
* dispatch a fake Tab Event.
*/
protected function onEditorKeyDown(event:KeyboardEvent):void {
if (event.charCode == Keyboard.ENTER && event.keyCode != 229) {
event.stopImmediatePropagation();
dispatchEvent(new FocusEvent(FocusEvent.KEY_FOCUS_CHANGE, true, false, null, event.shiftKey, Keyboard.TAB));
}
}
}


Be careful with itemRenderers and itemEditors

If you are using a custom itemRenderer or itemEditor, I recommend you to pay attention to the events they dispatch. They can dispatch extra events that make your Enter key not behaves exactly like the Tab key, specially if you're listening to the ITEM_EDIT_END event. It depends on the case, but if you're having problems with this use the same technique to interrupt not convenient events on your itemEditor or itemRenderer.



And that's it!