Archive

Archive for August, 2009

Currency TextInput

August 29, 2009 2 comments

In my project, i needed to create some action as below for TextInput:

  • Focus Out: Automatically format the inputted value as currency
  • Focus In: Remove all currency characters and display as normal Number
  • Text attribute: always return as normal number characters string (Without [,]  and [$])

One more requirement is that, it must be a components for later use.
currency

I think it’s enough introduction. Actually, this can be done easily by creating a class that extends TextInput class. I also override focusOutHandler() and focusInHandler() to process the display data as i want before showing it on TextInput. The last thing is Text property,  because i must use CurrencyFormatter to format data each time the focus is out, so if user call the Text attribute, the result which user can receive is a formatted string and cannot insert into a number column in database. To do that, i must remove all [,] and [$] out of the string.

Here is my source:

package components {

import flash.events.FocusEvent;
import mx.controls.TextInput;
import mx.formatters.CurrencyFormatter;

/**
*  Currency TextInput component
*
*/
public class CurrencyTextInput extends TextInput {

private var reg:RegExp = /[,$]/g;
private var formatter:CurrencyFormatter = null;

override public function get text():String {
return super.text.replace(reg, "");
}

/**
* Constructor
*/
public function CurrencyTextInput() {
// create new formatter
formatter = new CurrencyFormatter();
// set defafult currency symbol
formatter.currencySymbol = "$";
}

/**
* Format data before lost focus event happen
*
* @param    event
*/
override protected function focusOutHandler(event:FocusEvent):void {
text = formatter.format(text);

super.focusOutHandler(event);
}

/**
* Flush out [,] and [$] characters
* before getting focus
*
* @param    event
*/
override protected function focusInHandler(event:FocusEvent):void {

text = text.replace(reg, "");

super.focusInHandler(event);
}
}
}

And then, how to use it in mxml

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:custom="components.*">
<custom:CurrencyTextInput id="unit_price" width = "150"/>
</mx:Application>

This is still simple but you can add other attributes to allow user to control the format pattern more easily.

Hope this help!

Categories: Adobe Flex/Air Tags:

Get selected cell value of DataGrid in FLex

August 26, 2009 6 comments

In the DataGrid control of Flex, it doesn’t support any property related to the selected column index so we cannot get its value directly. Instead, we have to use other way. DataGrid supports events called [ItemClick] or [ItemDoubleClick], when using these events, we can retrieve the column index of the clicked item.

To demonstrate this action, i created an sample that includes a DataGrid and a PopupWindow. When user click on an item of DataGrid, it’ll get the selected column value and display on the PopupWindow. (the two forms must be put at the same directory)

The first is MainForm.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
<![CDATA[
import flash.events.Event;
import mx.controls.DataGrid;
import mx.events.ListEvent;
import mx.collections.ArrayCollection;
import mx.containers.TitleWindow;
import mx.events.DataGridEvent;
import mx.managers.PopUpManager;
import PopupForm;</code>

[Bindable]
private var dgArrayCollection:ArrayCollection =
new ArrayCollection([
{id:'1', name:'John'},
{id:'2', name:'Alex'},
{id:'3', name:'Peter'},
{id:'4', name:'Sam'},
{id:'5', name:'Alis'},
{id:'6', name:'Robin'},
{id:'7', name:'Mark'},
{id:'8', name:'Steave'},
{id:'9', name:'Fill'},
{id:'10', name:'Abraham'},
{id:'11', name:'Hennery'},
{id:'12', name:'Luis'},
{id:'13', name:'Herry'},
{id:'14', name:'Markus'},
{id:'15', name:'Flip'}
]);

private var newPopUp:PopupForm;

private function showPopUp(event:ListEvent):void {
var newPopUp:PopupForm = PopupForm(PopUpManager.createPopUp(this, PopupForm, true));

// Get the target of this event (Datagrid)
var dataGrid:DataGrid = event.target as DataGrid;
// Get selected column index
var dsColumnIndex:Number = event.columnIndex;
// based on the selected column index
// Get the DataGridColumn object to get the selected column name
var col:DataGridColumn = dataGrid.columns[dsColumnIndex];
// Get selected cell value from the selected row and column name
var newValue:String = dataGrid.selectedItem[col.dataField];

newPopUp.txtFromOutSide = newValue;

PopUpManager.centerPopUp(newPopUp);
}
]]>
</mx:Script>
<mx:VBox width="300" height="100%" horizontalAlign="center" verticalAlign="middle">
<mx:DataGrid id="dg" width="50%" height="100%" borderStyle="none"
dataProvider="{dgArrayCollection}" doubleClickEnabled="true" itemDoubleClick="showPopUp(event)" >
<mx:columns>
<mx:DataGridColumn dataField="id" headerText="ID"/>
<mx:DataGridColumn dataField="name" headerText="Name"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>

The second form is PopupForm.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
width="200" height="150" borderStyle="solid"
borderColor="0xCCCCCC" cornerRadius="5">

<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;

[Bindable]
public var txtFromOutSide: String;

private function onClose():void {
PopUpManager.removePopUp(this);
}

]]>

</mx:Script>

<mx:VBox width="100%" horizontalAlign="center" verticalAlign="middle">
<mx:Label id="lbl" text="{txtFromOutSide}" textAlign="center"/>
<mx:Button label="OK" click="onClose()"/>
</mx:VBox>
</mx:TitleWindow>

Hope this help!

Categories: Adobe Flex/Air Tags:

NVL() function in Postgre SQL

August 25, 2009 10 comments

Do Postgre have any function that equals to NVL() of Oracle? of course, it do have the same function but with different name. Below is the systax:

coalesce(expr1, expr2, expr3,....)

this function’ll returns the first non-null expression that is passed to it.

Ex:  
SELECT coalesce(<column name 1>, <New value>), <Column name 2> 
FROM <Table name> 
WHERE <Some Condition>

If <Column name 1> is NULL, it’ll be replaced by <New value>

Categories: PostgreSQL Tags:

Simple login form with Flex and XML as database

August 17, 2009 4 comments

I want to create a simple login form to learn how to work with Validation and XML database (based on E4X) in Flex.

login

Fist we need an XML file which contains our login information, i call it [data.xml]. We have two [user] elements (but you can add as much as you want), each element contains one user’s data includes user id and password. This file must be put at the same folder as the compiled source file. To learn more about XML, visit the W3Schools’ XML Tutorial at http://w3schools.com/xml/.

<?xml version=”1.0″ encoding=”utf-8″ ?>
   <data>
      <user>
         <userid>UI0001</userid>
         <password>123</password>
         <username>Nguyen Van A</username>
      </user>
      <user>
         <userid>UI0002</userid>
         <password>456</password>
         <username>Tran Van B</username>
      </user>
</data>

The next step is to create an mxml file called login.mxml. This file is used to control login form’s layout and handle event. The controls do not have anything paticularly complex. We start with a panel , inside it we add two Textinput controls for user id, password and a button to submit data. Finally, we have two StringValidators used for [Required], [MinLength], [MaxLength] validation.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”  layout=”absolute”>
   <!-- Validation -->
   <mx:StringValidator id=”useridValidator” required=”true”
          minLength=”6” maxLength=”25″
          source=”{userid}” property=”text”
          trigger=”{btnLogin}” triggerEvent=”click” />

   <mx:StringValidator id=”passwordValidator” required=”true”
          minLength=”6” maxLength=”25″
          source=”{password}” property=”text”
          trigger=”{btnLogin}” triggerEvent=”click” />

   <!-- Main form controls -->
   <mx:Panel title=”Login Form” horizontalCenter=”0″ verticalCenter=”0″>
      <mx:Form>
         <mx:FormItem label=”User ID”>
            <mx:TextInput id=”userid” />
         </mx:FormItem>
         <mx:FormItem label=”Password”>
            <mx:TextInput id=”password” displayAsPassword=”true” />
         </mx:FormItem>
         <mx:FormItem>
            <mx:Button id=”btnLogin” label=”Login”  />
         </mx:FormItem>
      </mx:Form>
   </mx:Panel>
</mx:Application>

We finished the layout. Now we’re going to start building the action script to hanle screen related events. At the initialization stage, we’ll add two validators into an array for later validation. (Remember to add creationComplete=”init()” into <mx:Application>)

[Bindable]
private var validatorArr:Array;

/**
* Initialization method
*/
public function init():void {
   // Add validators to array for validating all at one time
   validatorArr = new Array();
   validatorArr.push(useridValidator);
   validatorArr.push(passwordValidator);
}

then when user click on [Login] button we must call the inserted validators to validate user’s inputted data. If the result is valid, start loading data from XML and loop through it to find if the inputted data exist.

/**
* User's information checking
* based on the inputted data
*/
public function loginCheck():void  {
   // Starting to validate
   var errorArr:Array = Validator.validateAll(validatorArr)
   // if the error array contain any data, =&gt; error
   var isValid:Boolean = errorArr.length == 0;

   if (isValid) {
      // Load user data
      doLogin();
   }
}

private function doLogin():void {
   // Point to the data file's path
   var request:URLRequest = new URLRequest("data.xml");

   loader = new URLLoader();
   try {
      loader.load(request);
   } catch (error:SecurityError) {
      trace("A SecurityError has occurred.");
   }

   // If error, go to errorHandler function
   loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
   // once the load action was complated, go to loaderCompleteHandler() for
   // checking user information
   loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
}

private function loaderCompleteHandler(event:Event):void {
   var logged:Boolean = false;
   try {
      // Convert data into E4X class for easy access to elements
      externalXML = new XML(loader.data);

      // Loop through the user list to check
      // if the inputted user id and password are valid
      for each (var user:XML in externalXML.elements()) {
         if (user.userid == userid.text && user.password == password.text) {
            // user has an valid account
            logged = true;
            // Don't need to continue
            break;
         }
      }
      if (logged) {
         Alert.show('Congratulation, you logged in!', 'Information');
         // you could redirect user to main form here
      } else {
         Alert.show('User ID or Password is not correct, please try again!', 'Error');
      }

   } catch (e:TypeError) {
      trace("Could not parse the XML file.");
   }
}
private function errorHandler(e:IOErrorEvent):void {
   Alert.show("Had problem loading the XML File.");
}

The final step is to add click event for Login button [click=”loginCheck()”].

Reference resources

Working with XML in Flex 3 and Java-part1
URLLoader

Hope this help!

※All comments or improve ideas will always be appreciated.

In the next article, I’ll show you how to make login form using Flex and AMFPHP (a remote object access method)

Categories: Adobe Flex/Air Tags:

Error: unable to resolve ‘image name’ for transcoding

August 14, 2009 3 comments

i needed to find some sample about how to customize default flex PreLoader and found two great tutorials

Custom Flex 3 Lightweight Preloader with source code
Flex Custom Preloader

When i tried to add into my project and built it, the [Error: unable to resolve ‘image name’ for transcoding] was thrown. Because i’m using FlashDevelop so it might be a little difference from Flex Builder. Maybe the image path cannot be regconized. The original source code as below:

[Embed("Assets/Pathfinder_Logo_Blue.png") ]
[Bindable] public var Logo:Class;

To handle the error, the solution is kind of simple. Just add [/] before the path that points to the image.

[Embed("/Assets/Pathfinder_Logo_Blue.png") ]
[Bindable] public var Logo:Class;
Categories: Adobe Flex/Air Tags: ,

Convert Westen datetime to Japanese calendar

August 11, 2009 9 comments
using System;
using System.Globalization;

class WarekiSample1 {
   static void Main() {
      DateTime 日付 = new DateTime(2003, 7, 1, 12, 34, 56);
      JapaneseCalendar カレンダー = new JapaneseCalendar();
      Console.WriteLine(カレンダー.GetEra(日付));
      // 出力:4
      string [] 元号名 = { "明治", "大正", "昭和", "平成" };
      Console.WriteLine(元号名[カレンダー.GetEra(日付) - 1]);
      // 出力:平成
      Console.WriteLine(カレンダー.GetYear(日付));
      // 出力:15
   }
}
Categories: Visual C# Tags:

Add auto increment column in PostgreSQL

August 10, 2009 13 comments

In PostgreSQL, we cannot just add an column and mark it as auto increment like in MySQL or SQL Server. Instead, we have to create an sequence and link it to the specified column.

1. Assume that we have a table called [testtbl] with an unique column called [id]

2. Generate sequence

CREATE SEQUENCE <Sequence name>

=>

CREATE SEQUENCE <testtbl_id_seq>

※After the sequence’s already created, we can call NEXTVAL(‘<Sequence name>’) to generate a new value automatically.


3. Link the sequence to the unique column

ALTER TABLE <Table name>
ALTER COLUMN <Column name>
SET DEFAULT NEXTVAL(<Created sequence name>);

=>

ALTER TABLE testtbl
ALTER COLUMN id
SET DEFAULT NEXTVAL('testtbl_id_seq');

That’s all what we have to do.

Categories: PostgreSQL Tags:

Flex custom Alert message

August 6, 2009 4 comments

How do you feel about the default Flex Alert box? i think it’s kind of simple, don’t you?

Udayms give us an amazing customize of it from here. His example works fine except with Confirm message. Even if yes or no is selected, nothing seem to happen. I don’t know if i missed something but after trying to look around finally i figured it out.

public static function confirm(message:String, parent:Sprite=null, closehandler:Function=null):void{
   //show(message, "Confirmation", Alert.YES | Alert.NO, null, closehandler, iconConfirm);
   show(message,  'Confirmation',  Alert.OK| Alert.CANCEL, null,  closehandler,  iconConfirm, Alert.OK);
}

By replacing Alert.YES/Alert.No by Alert.OK/Alert.CANCEL it seems work in my case.

Information
Confirmation
Error
Click here to download source code.

Categories: Adobe Flex/Air Tags:

HTTPService result remains previous loaded data

August 6, 2009 Leave a comment

I have a form with a Datagrid and an add new button (Original from http://learn.adobe.com/wiki/display/Flex/CRUD+-+Dynamic). When this form is launched, it’ll load all data and display on grid. After first call, although i tried to add new records to database, the display content of Datagrid is still the same as before.

This problem took me a lot of time before i figured out how to solve. It seems that the HTTP response had been cached by IE because the request URL remains the same each time the form is loaded.

So the key is how to change the request content when a request is launched? The answer is that we can use timestamp as a request parameter. This’s because the value of timestamp keep changing each time we have a request, so it’ll always be different.

<mx:HTTPService
   id="employeesService"
   url="http://localhost/flex/php/1/employees.php?{new Date().toDateString() + new Date().toTimeString()}"
   resultFormat="e4x"
   useProxy="false" />
Categories: Adobe Flex/Air Tags: