Posted by admin at 17 February 2010

Category: programming

Logging to the firebug console from a Flex App is easy. A quick google search turns up loads of goodies… but you don’t really need a full fledged logging API for simple Flex Apps. Additionally, the example in the Adobe Flex Cookbook pisses off Internet Explorer as there is no check to see if window.console is even available.

At any rate, I wrote a small static class for logging to firebug from a Flex app. Use it however you wish:

package ctz.util
{
	import flash.external.ExternalInterface;

	public final class ConsoleLog
	{
		public function ConsoleLog()
		{
			throw new Error("static methods only");
		}

		public static function log(o:Object):void
		{
			if (o is Array)
				ConsoleLog.logArray(o as Array);
			else if (o is String)
				ConsoleLog.logString(o as String);
			else
				ConsoleLog.logObject(o);
		}

		public static function logString(msg:String):void
		{
			if (ExternalInterface.available)
				ExternalInterface.call("function log(msg){ if (window.console) { console.log(msg); } }", msg);
		}

		public static function logObject(obj:Object):void
		{
			var s:String = "";
			for (var k:String in obj)
				s += k + ": " + obj[k];
			ConsoleLog.logString(s);
		}

		public static function logArray(arr:Array):void
		{
			var s:String = "Item Count: " + arr.length + " || ";
			for (var i:int = 0; i < arr.length; i++)
				s += i + ": " + arr[i] + " ";
			ConsoleLog.logString(s);
		}
	}
}

File can be downloaded here.

Posted by admin at 4 February 2010

Category: programming

Tags: ,

Accomplishing a programming task with as few lines of code as possible is typically a good thing. At the same time, keeping the readability of your code at a reasonable level is also a good thing – especially if other developers will be maintaining your code in the future.

When writing custom components in Flex (and more or less writing anything to do with DisplayObjects in Flex) you find yourself writing a lot of the same, boring code. Basically, you instantiate a new DisplayObject, set some common properties on it, and then add it to a container. For example, take the following piece of code:

private function createUI():void
{
    var vbox:VBox = new VBox();
    vbox.percentWidth = 100;
    vbox.percentHeight = 100;
    vbox.name = 'My name is vbox';

    var txt:TextInput = new TextInput();
    txt.text = 'I am a TextInput';
    txt.setStyle('borderStyle', 'solid');
    txt.setStyle('borderThickness', 1);

    vbox.addChild(txt);
}

Pretty boring stuff, right?

Enter ctz.util.FlexUtils. With FlexUtils, you can cut down on writing all that boring code – like the snippet above. While there is nothing too complex or ground-breaking in this class, I find it to be quite helpful… and you may too:

package ctz.util
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.utils.*;

	import mx.collections.ArrayCollection;

	public final class FlexUtils
	{
		public function FlexUtils()
		{
			throw new Error('static methods only');
		}

		/**
		 * Create a Display Object and add some atts
		 */
		public static function createDisplayObject(typeName:Class, atts:Object=null):DisplayObject
		{
			try {
				var o:DisplayObject = new typeName();
				if (atts != null) {
					for (var k:String in atts) {
						if (o.hasOwnProperty(k)) {
							o[k] = atts[k];
						} else {
							typeName(o).setStyle(k, atts[k]);
						}
					}
				}
			} catch (e:Error) {
				trace('Error in FlexUtils.createDisplayObject: ' + e.message);
			}
			return o;
		}

		/**
		 * Given a root display object, get all children of the same type, recursively
		 */
		public static function getChildrenByType(collection:ArrayCollection, typeName:Class, rootObject:DisplayObjectContainer):void
		{
			var dobj:DisplayObject;
			for (var i:int = 0; i < rootObject.numChildren; i++) {
				dobj = rootObject.getChildAt(i);
				if (dobj is typeName)
					collection.addItem(dobj);
				if (dobj is DisplayObjectContainer)
					FlexUtils.getChildrenByType(collection, typeName, dobj as DisplayObjectContainer);
			}
		}

		public static function objDump(o:Object):String
		{
			var s:String = '';
			for (var key:String in o)
				s += key + ' => ' + o[key] + '\n';
			return s;
		}
	}
}

Note, I should probably update the two custom components I have published to use this class, but I really don’t have the time these days.

The createUI() method from the snippet above is magically transformed into the snippet below using FlexUtils.createDisplayObject()…

private function createUI():void
{
    var atts:Object = {percentWidth: 100, percentHeight: 100, name: 'My name is vbox'};
    var vbox:VBox = FlexUtils.createDisplayObject(VBox, atts) as VBox;

    atts = {text: 'I am a TextInput', borderStyle: 'solid', borderThickness: 1};
    var txt:TextInput = FlexUtils.createDisplayObject(TextInput, atts) as TextInput;

    vbox.addChild(txt);
}

I hope someone finds this remotely useful.

You can download the file here.

Posted by admin at 5 August 2009

Category: programming

Tags: ,

If you are not a seasoned Javascript developer (like myself), and you start writing Javascript classes which include jQuery event bindings, you may become stumped on the issue I am about to describe. On the contrary you are most likely more intelligent than I and realize that what you are trying to do is wrong and you consult the jQuery documentation to find the answer within the first 2 minutes of stumbling upon this problem.

Anyways, the issue at hand is setting up event bindings via jQuery inside of a class. This is easier explained with a simple code example. Take the following class:

function Page()
{
	var msg  = 'weeeeeeee';

	this.bindElements = function(elementOne, elementTwo)
	{
		$(elementOne).click(function() {
			this.elementOneStuff('yoyo');
		});
		$(elementTwo).click(this.elementTwoStuff);
	}

	this.elementOneStuff = function(a)
	{
		alert(a);
	}

	this.elementTwoStuff = function()
	{
		alert(this.msg);
	}
}

var p = new Page();
p.bindElements('#btnOne', '#btnTwo');

When you instantiate a new Page object and invoke the bindElements method you get barked at:

this.elementOneStuff() is not a function.

My initial reaction was that it was a scoping issue with my privileged class methods. After changing the architecture of my class to use public methods the same issue was there.

Solution / Answer

The this keyword that is being used in both of the callbacks will refer to the DOM element that dispatched the event…. not an instance of the Page Class. This is in fact the correct behavior as it will almost always be what is desired.

jQuery.bind( type, [data], fn ) to the rescue! Straight from the jQuery documentation:

data (Optional) Object
Additional data passed to the event handler as event.data

We can simply pass an object as the data parameter to the bind method and then invoke our class methods through event.data. So the updated, correct code would be:

function Page()
{
	var msg  = 'weeeeeeee';

	this.bindElements = function(elementOne, elementTwo)
	{
		$(elementOne).bind('click', this, function(evt) {
			evt.data.elementOneStuff('yoyo');
		});
		$(elementTwo).bind('click', this, function(evt) {
			evt.data.elementTwoStuff();
		});
	}

	this.elementOneStuff = function(a)
	{
		alert(a);
	}

	this.elementTwoStuff = function()
	{
		alert(this.msg);
	}
}

This took me more time to figure out than I would like to admit. I am posting this in the hopes that it saves someone some time and frustration.

Posted by admin at 2 June 2009

Category: programming

Tags: , , ,

Edit: This project is now on github: git://github.com/danjarvis/DateTimeChooser.git

The Flex UIComponents for Dates, namely DateField and DateChooser let you easily collect date information from the users of your application(s). However, and I’m not exactly sure why, but these components lack an interface for choosing time. The application I’m currently working on deals heavily with Date/Time – thus this was a major issue for me.

A quick search on Google returns a bunch of custom components which solve the issue of choosing Date/Time in Flex. While a few of the components I found would have been fine for my use I decided to roll my own, mainly for educational purposes.

This component can be customized in several different ways. Additionally, all of the children (e.g. NumericSteppers) are exposed so that styles can be applied. Let me know if you have any questions on some of the properties as I am only showing the basics here.



This movie requires Flash Player 9


Source can be downloaded here.

Enjoy!

Posted by admin at 1 June 2009

Category: programming

Tags: , , ,

Most of the Flex Containers have the cornerRadius attribute. This is a lovely attribute which allows you to round the corners of layout objects. Better yet, the Panel and TitleWindow components let you round the just top corners – YAY! So… why the HELL didn’t Adobe implement the rounding of SPECIFIC corners on any component that had a cornerRadius attribute?!

Anyways, I wanted something like this that I could use in applications for aesthetic purposes. I found a few solutions here and there which would have been adequate. However, for educational purposes, I decided to just roll out my own. Now, there are a few quirks here and there, but overall I am satisfied with the outcome. Just be careful if you are placing children inside ( take into account padding if you are giving the box heavily rounded corners ). Additionally, when rounding the corners and using a height / width that scales ( percentage ), it is important to find and use a minHeight and minWidth or else the box WILL become all wacked out when it gets small. It is all relative to the amount of corner radius you specify. Use the style explorer to see what I mean.

Below is a screen shot of what can be created using this component.

A style explorer can be found here ( with a link to source ).

Source can be downloaded here.

Enjoy!

Posted by admin at 24 March 2009

Category: programming

Tags: , ,

I was recently working with an AdvancedDataGrid that was in charge of presenting a large amount of data to the user. I was presented with a minor issue (go figure) due to the fact that the max real estate this component could use was about 20% of the total page height.

The issue:
When scrolling through the data with the mouse wheel, the scroll bar was ’stepping’ to far and some rows were getting cut off. For example, if there were 40 rows of data and the amount of visible rows was 5, using the mouse wheel to scroll one notch would move the scroll index from position 0 to 7. This is a problem because it forces the user to either use the scroll arrows or drag the scroll bar to see every row. Which sucks because mouse wheels rule and make everyone’s life easier.

The solution:
Intercept the mouse wheel events that are fired and tell the component how to scroll. It’s quite simple actually. The first thing to do is register 2 event listeners on the Component, like so:

private function init():void
{
	this.adg.addEventListener(Event.RENDER, this.updateScroll, false, 0, true);
	this.adg.addEventListener(MouseEvent.MOUSE_WHEEL, this.handleMouseWheel, false, 0, true);
}

In the function above, adg references an AdvancedDataGrid, but that’s not really important. The Event.RENDER event is dispatched when the display list is about to be updated and rendered (the keyword being ‘about’). Consult the API Docs for a better description of this event. The MouseEvent.MOUSE_WHEEL is dispatched whenever the user scrolls with the Mouse Wheel.

The next part to look at is the method invoked after Event.RENDER is dispatched: updateScroll(). This method simply updates a variable with the vertical scroll position of the Component:

private function updateScroll(event:Event):void
{
	this.scrollPos = this.adg.verticalScrollPosition;
}

The last part to look at is the method invoked after MouseEvent.MOUSE_WHEEL is fired: handleMouseWheel(). This method uses the scrollPos variable that is constantly being updated via updateScroll() and intercepts mouse wheel events in order to override the behavior of vertical scrolling:

private function handleMouseWheel(event:MouseEvent):void
{
	var num:int = event.delta / Math.abs(event.delta);
	if( ( this.scrollPos - num ) <= 0)
		this.adg.scrollToIndex(0);
	} else if( ( this.scrollPos - num ) >= this.adg.maxVerticalScrollPosition ) {
		this.adg.scrollToIndex( this.adg.maxVerticalScrollPosition );
	} else {
		this.adg.scrollToIndex( this.scrollPos - num );
	}
}

This is also very straight forward: evaluate the current scroll position and proceed accordingly without causing wacky behavior. In other words, if the result of (scrollPos – num) is <= 0 or >= to the max vertical scroll position, send (or keep) the scroll wheel to the appropriate extreme, else scroll 1 unit in the appropriate direction.

Note: eventually I’ll start adding interactive examples here… someday.

Posted by admin at 27 February 2009

Category: random

Today a couple of co-workers of mine discovered the best website ever created:

thefuckingweather.com

That is all.

Oh and this.

Posted by admin at 25 February 2009

Category: apps

Tags: ,

Well I guess I can finally feel good about buying a blackberry and spending $29.99 a month for an unlimited data plan.

Slacker Mobile is a great FREE streaming radio service for the blackberry. Simply type in an artist / band of your choice and you are instantly taken to your own personalized radio station where your chosen band will be played as well as several similar bands (a great way to discover new music). You can also choose from hundreds of ‘expert programmed’ stations. Better yet, you are given instant access to album info and band bios.

Perhaps the best feature is the ability to cache radio stations to your device’s memory card. This way you can listen to music pretty much anywhere… as long as your device’s battery isn’t dead.

Open up your device browser and go to http://www.slacker.com/mobile/blackberry/ to download and install.

Posted by admin at 12 February 2009

Category: programming

Tags: , , ,

If you try to use the logical AND operator inside of an MXML attribute to determine its value, the compiler will throw this error:

The entity name must immediately follow the ‘&’ in the entity reference

The error message is sketchy, especially given the fact that the logical OR operator is allowed.
The ampersand needs to be html-encoded (after all, MXML is an XML-based markup language!)

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
		[Bindable] private var arg1:Boolean;
		[Bindable] private var arg2:Boolean;

		private function validate():Boolean {
			return (this.arg1 && this.arg2);
		}
		]]>
	</mx:Script>

	<!-- bad -->
	<mx:Button enabled="{(this.arg1) && (this.arg2)}" />

	<!-- good -->
	<mx:Button enabled="{(this.arg1) &amp;&amp; (this.arg2)}" />

	<!-- also good, but more code -->
	<mx:Button enabled="{this.validate()}" />
</mx:Application>

Posted by admin at 20 January 2009

Category: programming

Tags: , , ,

Filling out electronic forms is loads of fun… everyone can agree on that. However, when the focus is placed on the first input control, the fun level increases exponentially.

Why?

Because moving your hand from the keyboard to the mouse requires work… and nobody likes that.

In MXML and ActionScript, setting the focus to an input control is extremely easy. For example take the following component:

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="abolute" width="400" height="300">
	<mx:Form>
		<mx:FormItem label="Username:">
			<mx:TextInput id="uname" />
		</mx:FormItem>
		<mx:FormItem label="Password:">
			<mx:TextInput id="pwd" displayAsPassword="true" />
		</mx:FormItem>
	</mx:Form>
</mx:TitleWindow>

Typically, Title Window components are viewed as Pop Ups. When the Pop Up is launched via the PopUpManager the Title Window component gains focus within Flash player (I’ll get to why this is important later). To set the focus to a text input control, add code to the creationComplete event of the Title Window, like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="horizontal" width="400" height="300"
	creationComplete="{onLoad(event)}">

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

		private function onLoad(event:Event):void{
			focusManager.setFocus(this.uname);
		}
		]]>
	</mx:Script>

	<mx:Form>
		<mx:FormItem label="Username:">
			<mx:TextInput id="uname" />
		</mx:FormItem>
		<mx:FormItem label="Password:">
			<mx:TextInput id="pwd" displayAsPassword="true" />
		</mx:FormItem>
	</mx:Form>
</mx:TitleWindow>

Additionally, you can bypass the call to the focusManager object and call the setFocus() method of the Text Input component:

this.uname.setFocus();

Now, to the PROBLEM…

If you want to give a Text Input control focus that is part of an Application File, e.g. a Login Page, you will run into a minor problem. When you call setFocus() you will see that your component will in fact GET focus, however the cursor will not be present. Once you click in the Browser window (and not even inside of the Text Input!), the cursor will become available.

Before you can place the focus on a component within Flash Player, you need to first give focus to the Flash Player Application. This can be done via JavaScript.

The more common approach would be to add a JavaScript function to your html-wrapper and then call that function via ExternalInterface.call() Note, if you are using Flex Builder to generate your html-wrappers, add the function to the index.template.html file.

The function needed is shown below:

function setBrowserFocus(){
	document.getElementById('${application}').focus();
}

To invoke this function, use ExternalInterface.call():

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute" creationComplete="onLoad(event)">

	<mx:Script>
		<![CDATA[
		import flash.external.ExternalInterface;

		private function onLoad(event:Event):void {
			ExternalInterface.call('setBrowserFocus');
			this.uname.setFocus();
		}
		]]>
	</mx:Script>

	<mx:VBox>
		<mx:HBox>
			<mx:Label text="Username:" />
			<mx:TextInput id="uname" />
		</mx:HBox>
		<mx:HBox>
			<mx:Label text="Password:" />
			<mx:TextInput id="pwd" displayAsPassword="true" />
		</mx:HBox>
	</mx:VBox>
</mx:Application>

The other approach is to place the JavaScript function directly inside of the ExternalInterface.call() method (replace \’Login\’ with the name of your .mxml application file):

ExternalInterface.call('function browserFocus(){document.getElementById(\'Login\').focus();}');

Launch the application and the cursor should be blinking inside of the Text Input.