Archive for category flex

Substitution Tokens in Resource Bundle Strings in Flex

There’s many times where you want to use a Resource Bundle String in-conjunction with variable data. People often breakup the RB String into 2 pieces like so:

part1=My name is
part2=and I like

And then put it back together in AS like:

var part1:String = ResourceManager.getInstance().getString('Labels', 'part1');
var name:String = "Brian Riley";
var part2:String = ResourceManager.getInstance().getString('Labels', 'part2');
var likes:String = "beer.";

var myStr:String = part1 + " " + name + " " + part2 + " " + likes;

Which works, but it’s a lot of unnecessary code. Take advantage of the tokens allowed in RBs and do the following:

likes=My name is {0} and I like {1}

var likes:String = ResourceManager.getInstance().getString('Labels', 'likes', ["Brian Riley", "beer."]);

The ResourceManager class will automatically substitue the tokens {0} and {1} in order and replace them with the array of strings provided as the last param in the getString() method.

Much simpler, right?

Post to Twitter Tweet This Post

, , , , ,

No Comments

Flex & ActionScript Regex List

I’m not great with regex since I don’t use it a ton so I constantly find myself looking up simple, reusable regex statements…thought I’d just start listing them as I use them in case someone else finds them useful. This will start with just a couple examples that we’ll continue to add to.

Assume the following vars:

var myString:String;
var pattern:RegExp;
var resultString:String;
var isSuccess:Boolean;

Remove All Spaces

myString = "The quick brown fox.";
pattern = /\s+/g;
resultString = myString.replace(pattern, "");
trace(resultString); // Thequickbrownfox.

Remove Special Characters & Spaces

myString = "The 123 quick 456 brown !@#$% fox.";
pattern = /\W/g;
resultString = myString.replace(pattern, "");
trace(resultString); // The123quick456brownfox

Remove Special Characters & Numbers & Spaces

myString = "The 123 quick 456 brown !@#$% fox.";
pattern = /[^a-zA-Z]+/g;
resultString = myString.replace(pattern, "");
trace(resultString); // Thequickbrownfox

Test URL String

myString = "http://yahoo.com";
pattern = /^http(s)?:\/\/((\d+\.\d+\.\d+\.\d+)|(([\w-]+\.)+([a-z,A-Z][\w-]*)))(:[1-9][0-9]*)?(\/([\w-.\/:%+@&=]+[\w- .\/?:%+@&=]*)?)?(#(.*))?$/i;
isSuccess = pattern.test(myString);
trace(isSuccess); // true
myString = "htt://yahoo.com";
isSuccess = pattern.test(myString);
trace(isSuccess); // false

Trim String (With Tabs & Returns): Courtesy of Jeff Channel

myString = myString = "The quick brown fox.                   		";
pattern = /^\s+|\s+$/gs;
resultString = myString.replace(pattern, "");
trace(resultString); // "The quick brown fox."

Post to Twitter Tweet This Post

, , ,

4 Comments

Set Flex to Focus on Application Load

By default a Flex application is not in focus in the browser when it loads. This can be especially frustrating if you have say a login view and would like the username field to be in focus when the application starts cranking. However, with some simple JavaScript we can set the Flash object to focus when the application loads.

NOTE: This will not work in Safari, Chrome, or any other browser that leverages Webkit, as it doesn’t allow the focus to be set on embedded objects. If you’re targeting IE and Firefox the proposed solution below will work.

For example purposes, let’s assume we want to make our username TextInput field have focus when the Flex app starts rocking.

First, set the focus to the username field — assume a ViewMediator is doing this:

this.view.userNameTextInput.setFocus();

Create a simple JavaScript method to set the focus of the browser to your Flex application. Create this method in the index.template.html file in your Flex project — just drop it right before the closing HTML tag at the bottom of the file:

<script type="text/javascript">
function onFlexInitialized()
{
	//alert("onFlexInitialized");

	<!-- Force the browser to set flex app with focus -->
	document.getElementById("${application}").focus();
}
</script>

Next catch the application complete event and call the JS method we just created — I put in how to remove the event handler for the app complete for both Flex 3 and 4:

/**
 * Constructor.
 */
public function AppController()
{
	FlexGlobals.topLevelApplication.addEventListener(FlexEvent.APPLICATION_COMPLETE, onAppComplete); // Flex 4
        //Application.application.addEventListener(FlexEvent.APPLICATION_COMPLETE, onAppComplete); // Flex 3
}

/**
 * Handles the application complete event.
 */
protected function onAppComplete(e:FlexEvent):void
{
	FlexGlobals.topLevelApplication.removeEventListener(FlexEvent.APPLICATION_COMPLETE, onAppComplete); // Flex 4
        //Application.application.removeEventListener(FlexEvent.APPLICATION_COMPLETE, onAppComplete); // Flex 3

	if(ExternalInterface.available)
	{
		ExternalInterface.call("onFlexInitialized");
	}
}

And that’s it. Again, it doesn’t work in Safari and Chrome. Here are the 2 defects logged for each brower’s bug-base respectively: Chrome, Safari.

Post to Twitter Tweet This Post

, , , , ,

7 Comments

Unable to export SWC oem

Been switching environments a bit lately from Flash Builder to Flex Builder and back and using different SDKs.

When importing a new project that someone had checked in from a different version, the .flexLibProperties file was causing this issue.

After much scouring, I found something that worked.

Open .flexLibProperties and find the section <includeResource/>. Remove everything in that section.

Made the problem disappear.

Post to Twitter Tweet This Post

, , ,

No Comments

Dynamic Classes Gotcha!

We recently started using dynamic classes to assist with unknown data formats. It’s a pretty powerful feature of the language. It comes with a price in that you don’t get strong typing nor intellisense on the dynamic properties. But, there are cases where it can serve great purpose.

One of the things you have to keep in mind though is that since the class is dynamic, the compiler can’t provide the linkage for you to do something like:

var someValue:SomeClass = someObject as SomeDynamicClass;

The compiler won’t complain, but, you will as you scratch your head trying to understand why someValue == null all the time. The lack of information at compile time is the obvious culprit.

But, I have found a decent workaround. Provide a constructor for the dynamic class that takes and Object as an optional parameter. If you pass in a parameter, call the helper function to populate the object. Here I’m using a form of reflection to do this dynamically so I don’t have to hand write all the properties.


dynamic public class SomeDynamicClass

public function SomeDynamicClass(obj:Object=null)
{
if ( obj )
this.populateMe(obj);
}

private function populateMe(source:Object):void
{

var destinationList:XML = describeType(this);

for each ( var propName:XML in destinationList..variable )
{
if ( source.hasOwnProperty( propName.@name ) )
{
var cls:Class = getDefinitionByName(propName.@type) as Class;
this[propName.@name] = source[propName.@name] as cls;
}
}
}

Later on, when you get some generic Object, like from ArrayCollection.getItem, you don’t do the normal cast but instead create a new instance passing in the Object.

var someValue:SomeClass = new SomeDynamicClass(someObject);

Hope that helps.

Post to Twitter Tweet This Post

, ,

No Comments

Reusable Numeric Sort Method for Flex DataGrid Columns

I can’t take full credit for this since I found some version of this function out there somewhere, but since it’s not that easy to find I thought I’d repost it.

If you need to numerically sort multiple columns in a DataGrid without creating a separate method for each based on its dataField, then use this:

/**
 * Numerically sorts a column in the DataGrid.
 *
 * @param	fieldName	The string name for the dataField in the column that you want to sort.
 */
private function numericSortByField(fieldName:String):Function
{
	return function(obj1:Object, obj2:Object):int
	{
		var value1:Number = (obj1[fieldName] == '' || obj1[fieldName] == null) ? null : new Number(obj1[fieldName]);
		var value2:Number = (obj2[fieldName] == '' || obj2[fieldName] == null) ? null : new Number(obj2[fieldName]);
		return ObjectUtil.numericCompare(value1, value2);
	}

}

By default, the DataGrid’s sort converts your data to strings so this ensures it’s really doing a numeric sort (and is a generic one at that).

Finish it off by making sure to set the sortCompareFunction for your columns like so:

myColumn.sortCompareFunction = this.numericSortByField("myDataField");

Post to Twitter Tweet This Post

, , , , ,

5 Comments

FlexUnit 4 Testing Services In Flash Player Issue

We’ve created a number of FlexUnit 4 (FU4) tests for our current, large project and the suite of tests that seems to be of the most importance to both us and our client is the one that tests the services. Our client’s back-end services are simple JSPs that return XML payloads for a number of CRUD operations on various objects in the system, so we’d like to test sending good required data as well as bad required data to our delegate before hitting the service directly.

The issue we ran into was quite frustrating and it took me some time to figure it out — I actually had to explain the system of tests to my partner before it dawned on me what was going wrong. In order to actually hit the services and get data back, you need to be logged into our client’s system…except this isn’t done through a Flex login, but rather via the larger application’s HTML login in which our smaller app lives (SSO)…once you’re logged in, a cookie is sent back and forth between the client and server…such is the security design of our client’s application framework and there wasn’t any wiggle room to change this.

SWF Browser Association

Change SWF to Open With Browser

Now think about FU4 and how it actually runs the tests (when using Ant and not building and running with FlexBuilder)…it simply opens up a TestRunner.swf in the Flash Player to execute it’s tests…this means no browser wrapper for our SWF and thus no access to cookies…and ultimately no working services in my tests…grrrr.

So here’s a simple solution (on Mac)…open up Finder and locate your TestRunner.swf, right-click on it and select “Get Info”. Find the section “Open with” and change the application to your browser (I use FireFox), but don’t click the button change for all, as we just want to change this for this file and this file only. Voila! Now your TestRunner.swf will run in thr browser when your Ant buld runs and you will have access t cookies (assuming you’ve already logged into the system you need access to in the same browser session).

Post to Twitter Tweet This Post

, , , , , , ,

6 Comments