Random assortment of Flex tips

The challenge in learning a new language is that you don’t know what you don’t know. Very often when I look at older code I’ve written I realize that there’s a far better way of solving the problem, I just wasn’t aware of it at the time.

The purpose of this post is to cover a bunch of random things about Flex that I’ve learned along the way. For many of you I’m sure this list will be more of a review, but if you’re new to Flex hopefully you’ll find something which you didn’t know you were looking for.

mx_internal

Essentially, it’s a namespace (similar to public, private, protected and internal) used by the framework to protect code.

Some properties and methods in the framework need to be accessible from other places while still being hidden from the casual user. Using ‘protected’ would require that the class is a subclass, and ‘internal’ requires that it’s in the same package. This way any class can access a ‘hidden’ property or method of another class.

While this can be used to hack the framework, in general using the mx_internal namespace to access hidden properties should be avoided as it’s very easy to cause unexpected side effects (the property/method is probably hidden for a reason).

more info…

callLater()

Let me start by saying if using this function is fixing your problem but you’re not sure why you’re probably doing something else wrong. The callLater function is used to tell the Flash Player to call the function on the next frame.

Here’s a valid use of this function. If you set the dataProvider property of a list and then want to set an item as being selected you’d want to use the callLater. This gives the Flash Player a chance to setup the new dataProvider before you select your item.

So… why is this. When you set most properties the values aren’t actually set right away. The component will generally store the new value and mark that it’s been changed. It will then wait until the next validation to actually set the new value.

Using the callLater gives the component a chance to validate itself first. Because of this, you can often call validateNow instead of using a callLater but by doing so you’re forcing the class validate sooner than it’d like which could introduce performance issues.

This topic touches upon a key Flex idea, work with the framework not against it. The framework has a specific order in which things happen, the more familiar you are with how the framework operates the better off you’ll be.

more info…

initialize vs creationComplete

This topic is a good follow up to the last one. To really understand the difference you need to study up on the component lifecycle . In a nutshell initialize is called when the component’s children exist but aren’t yet measured/positioned, while creationComplete is called once the component has finished setting itself up.

The take away point here is you want to avoid placing code which will change the size/layout of a component’s children in the creationComplete handler. Doing so will force the Flash Player to size/layout the children a second time (which decreases the performance).

It’s good to be able to spot this issue by looking at how your application renders itself. Ideally, when the window is shown it should already be fully created but if you use creationComplete event handler on a slower machine you can visibly see the application resize its children.

more info…

masks

When I started to learn Flex I read all of the Flex books I could get my hands on, what I was missing however were the ActionScript books. Being an expert in Flex requires two sets of knowledge: the Flex Framework as well as a good understanding of ActionScript.

I obviously can’t cover all the cool things that you can do with ActionScript in this post but one item that I find handy is the mask property. This can be used to define a section of a component to be visible. Before I knew about masks I was adding white boxes to my applications to cover up the parts that I wanted to hide. Masks are a much more elegant solution to this problem.

more info…

suspendBackgroundProcessing

One of the greatest aspects of Flex is how easy it is to create really cool effects (as a side point, remember to use them where they make sense… every item on the screen doesn’t need to slide into place). The catch is sometimes the effects can get slowed down by other things happening in the background. I find that hurky-jurky effects can be somewhat painful to watch.

A possible solution is to set the suspendBackgroundProcessing property to true. This will tell the Flash Player to focus all of it’s resources on making the effect run smoothly. Another technique which I’ve found sometimes helps is to delay the effect slightly.

more info…

relatedObject

There are a number of different event types in Flex which each have their own special properties. It’s a good idea to glance at the full list to see what’s out there but here’s one property which I find particularly useful.

The FocusEvent class has a property called relatedObject which will tell you where the focus is going to/coming from. This can be really handy when creating focus event handlers.

more info…

ObjectUtil.toString()

Next to the trace function, this is the single most important function for debugging. This will dump an object to a string. While debugging I’ll very often write something like.

trace( ObjectUtil.toString( myVariable ) );

more info…

DefaultListEffect

This one’s just eye candy. Using this effect will cause the list to fade in/out items which are added or removed. When using this effect you need to remember to set variableRowHeight property on the List component to true.

more info…

That about wraps it up. Hopefully you learned something new while reading the post, or at the very least feel good about yourself because you were already familiar with everything mentioned here.

Best,
Hillel

Flex AutoComplete: Version 0.98.2

Note: The interface for the component has been changed a fair bit in this version. If you’re upgrading, please refer to this post to determine the changes you’ll need to make.

Latest version

I’ve found that I very often need to use the component as a basic autocomplete combobox, without all the extra jazz. To simplify things, I’ve split the component into two classes: AutoComplete and AdvancedAutoComplete.

I’ve moved a lot of the extra features (such as browsing and ordering) to the AdvancedAutoComplete component. The demo and documentation provide breakdowns of which features are where.

The catch with this approach is if you need one of the features from the advanced component you have to take them all. It looks like Gumbo will implement changes to the component framework which will enable implementing a better solution. I’m planning to rework the component once it’s officially released.

Additionally, I’ve changed the names of a number of properties to better follow the conventions used throughout the Flex framework.

Old Name New Name
isMultiSelect allowMultipleSelection
multiSelectLayout selectionLayout
isStrict allowNewValues (note: logic is reversed)
areNewItemsEditable  allowEditingNewValues
isBrowseable showBrowseButton
isOrderable showOrderButtons
styleName selectedItemStyleName (note: now a style)

Here’s what’s new…

  • Created inlineButton feature: You can now set a button to appear at the end of the combobox.
  • Added Actions Menu: I’ve used the new inlineButton feature to implement an actions menu in the AdvancedAutoComplete component. The feature is enabled by setting a value for the actionsMenuDataProvider property. I’ve added the option to the advanced tab in the demo.
  • Support for skins: The selected items have been changed to buttons which has enabled me to rework the MacMail and Facebook styles as skins. I’ve created a CustomSkin example application which demonstrates how to create your own skin. If you end up creating any nice skins please send them my way. One note here, if you’re using the source you’ll need to include the defaults.css file in your app.
  • Added autoSelectEnabled property: One of the most common questions posted is how to prevent the component from automatically selecting a match. You used to have to create a function which always returned false for the isEqualFunction property. You can now simply set autoSelectEnabled to false. If you’d like to implement a custom function you can set it in the autoSelectFunction property.
  • Bug fixes and tweaks: As always, I’ve gone through all of the comments and fixed any bugs which people have spotted.

Lastly, I wanted to thank Demetri for convincing me to create it, creating the icons and guiding the UI decisions along the way and Tarak for allowing me to share it (and introducing me to Flex). Thanks guys!

Flex AutoComplete: Version 0.98.1

At this point I’m spending most of my time cleaning up the code. I started working on the component about six months ago and I find that when I look back on some of the older parts of the code I realize I’ve learned far better ways of handling things.

Latest version

Here’s what’s new:

  • Added browserFields property: This property enables you to specify which fields to display in the browser DataGrid.
  • Reworked selectedItems: Adding/removing items from the selectedItems property will now update the values displayed in the AutoComplete.
  • Added “search” method: If you’re using the component with a dynamic dataProvider, you can use the search function to display the dropDown if there are any matches.
  • New demo: I’ve added two more tabs to the demo to show other examples of the component in action.
  • Bug fixes: As always, I’ve gone through all the comments on the blog and made sure any issues found have been resolved.

I can’t thank the community enough for the enormous amount of support I’ve received. I’ve learned a tremendous amount from the fixes people have submitted. Please keep it coming…

Thanks,
Hillel

Flex AutoComplete: Bug fixes

The last version of the component had a number of major changes, as a result a couple of bugs slipped in. Thanks to e/o who posted comments documenting the issues on the blog.

Latest version

Keep the feedback coming,
Hillel

Flex AutoComplete: New batch of changes

If you’ve come straight to this post I’d recommend checking out the previous posts for this component for more info on using it.

Latest version

Here’s what’s new:

  • Ability to add new items: You can now select items which aren’t in the data provider. To enable this feature you need to set the isStrict property to false. I’ve also added an allowDuplicates flag which controls whether or not you can add an item more than once
  • Added style property: I’ve added a style property which lets you control how the selected items are displayed. There are currently 3 choices: Mac Mail, Facebook and underlined.
  • Created some documentation: It’s not great but at least it’s a start. You can find it in the zip file in the doc folder
  • A bunch of other small tweaks and bug fixes: I’ve tried to incorporate the changes suggested in comments in the blog but I’m sure I missed some things. Please let me know if you suggested a change which didn’t make it in and I’ll get it in a future release.
  • Changed component name to AutoComplete: I’ve decided that for clarity’s sake it’s better to call it AutoComplete (rather than Chooser). I’m sorry for the refactoring this will require (hopefully it should be pretty minimal)

I’ve put the codebase on Google Code. If you’re interested in getting involved in the project please let me know.

Thanks,
Hillel

Flex AutoComplete: Almost there… (or so I thought)

If you’ve come straight to this post I’d recommend checking out the first and second posts for this component for more info on using it.

Latest version

Here’s what’s new:

  • Created new demos: I’ve added two more demos which demonstrate some common ways to use the component. The source for the demos is included in the zip.
  • Added support for a horizontal multiselect: The previous version of the component had a multiSelect mode but it took up a fair amount of screen real estate. I’ve added a multiSelectLayout property which can be set to either “vertical” or “horizontal”. Vertical makes it behave the same as it used to, while horizontal enables you to select multiple items within the TextInput component. I’ve added this option to the demo. I’m still working on this feature, in the next version I’d like to change the style to make it look like the multiselect in Facebook and Mac Mail
  • Improved support for selecting items not in the dataprovider: The best practice to accomplish this is to add a keyDown listener to the component. If the user clicked enter then check if the text property is set and the selectedItem property is null
  • Fixed minor bugs: I’ve gone through all the comments on the blog and tried to address any open issues. I’m sure I’ve missed some things, if you’ve made a suggestion in the past which didn’t make it in to this release please re-suggest it and I’ll try to get it into the next version

One last thing, I’ve added the component to the Adobe Flex Exchange. It’s a relativley new component so it doesn’t have any rating or reviews. If you’re using this component and find it useful it’d be very much appreciated if you could rate it on the site (or even better… write a review).

Thanks very much,
Hillel

Flex AutoComplete: Latest version

First off, I just wanted to thank everyone for their comments and support. It’s really nice to know that the component is being used in other people’s applications.

If you’ve come directly to this page I’d recommend checking out the post for the original version for more info on using the component.

Latest version

Here’s what’s new:

  • Fixed minor bugs: I’ve gone through all the comments/emails I received and have made sure any issues found have been resolved.
  • Icon to clear text: Now when there’s text in the chooser and the mouse is over the component a little icon appears to clear the text (ala Mac OS X).
  • Added matched part underlining: The default dropDownLabel function now shows that matched part of the text with an underline (ala Firefox 3).
  • Changed property name: Initially I went with “chosenItems” rather than “selectedItems” (b/c the component is called The Chooser). I’ve decided it’d be better to follow convention so I’ve changed any references to “chosen” to “selected” (sorry for the refactoring this will require).
  • Added a matchType parameter: There are 3 choices: match beginning, word or anyPart. “beginning” matches, as the name implies, the beginning of the string. “word” matches the beginning of any word in the string. “anyPart” matches any part of the string. I’ve added this to the demo to hopefully make this a bit clearer.

Thanks again for all the feedback

Best,
Hillel

Flex AutoComplete Component: a new take on an old standard…

While there are a couple of other AutoComplete components out there (most notably the ones from the Flex Team and kuwamoto.org), neither of them had the features we were looking for. I struggled for a while trying to extend them but it just wasn’t working.

One of the main features we needed was for the component to show the part of the string which matches the search term. We also needed it to support selecting multiple items as well as creating an ordered list.

Latest version

As you can see in the demo, there are four main boolean properties which control how the chooser works:

  • isBrowseable: This will display a ‘Browse’ button to the right of the TextInput. If the user clicks it they will be presented with either a searchable DataGrid or a list builder (see below).
  • isMultiSelect: This enables selecting multiple values.
  • isOrderable: This makes the items in the list orderable. It provides buttons to reorder them as well as enabling drag-and-drop.
  • useListBuilder: If this is set to true, when clicking the browse button the user gets a List Builder rather than the DataGrid (note: this requires isBrowseable and isMultiSelect to be true).

Here are the other main properties:

  • labelField: Which property of the data objects to use when displayed in the TextInput and the Lists.
  • labelFunction: In place of the labelField you can specify a function for determining the string to display.
  • dropDownLabelFunction: A reference to the function used to display the matched items in the dropdown. It supports using HTML (which can be used to highlight the part of the string which matches the search pattern).
  • prompt: The message which is initially displayed in the TextInput.
  • filterFunciton: A reference to the function used to search when entering text into the TextInput. The function is passed the object being checked along with the search string
  • isEqualFunction: A reference to a function which can be used to determine if the search string should be considered equal to the object (if it returns true it will automatically select the item).

The bare minimum required to use the component is to set the dataProvider property to an ArrayCollection of objects and specify a value for labelField.

The code for the demo is pretty straight forward.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	xmlns:hc="com.hillelcoren.components.*"
	width="550" height="400"
	initialize="init()">

	<mx:Script>
		<!&#91;CDATA&#91;
			import mx.collections.ArrayCollection;

			&#91;Bindable&#93;
			public var colors:ArrayCollection;

			private function init():void
			{
				colors = new ArrayCollection(
				&#91;
					{ "name":"Almond", "hex":"#C5E17A" },

					...

					{ "name":"Yellow Orange", "hex":"#FFAE42" }
				&#93; );
			}			

			private function handleChange():void
			{
				var color:Object = chooser.chosenItem;

				if (color != null)
				{
					setStyle( "backgroundColor", color.hex );
				}
			}
		&#93;&#93;>
	</mx:Script>

	<mx:Panel width="100%" height="100%" title="Chooser Demo"
			paddingBottom="20" paddingTop="20" paddingLeft="20" paddingRight="20">
		<mx:HBox>		

			<mx:VBox horizontalAlign="left">
				<mx:CheckBox id="browesable" label="Browesable"/>
				<mx:CheckBox id="multiselect" label="Multiselect"/>
				<mx:CheckBox id="orderable" label="Orderable" enabled="{ multiselect.selected }"/>
				<mx:CheckBox id="listBuilder" label="List Builder" enabled="{ multiselect.selected }"/>
			</mx:VBox>		

			<hc:Chooser id="chooser" dataProvider="{ colors }" labelField="name"
				prompt="Choose your favorite Crayola crayon" width="300" change="handleChange()"
				isBrowseable="{ browesable.selected }" isMultiSelect="{ multiselect.selected }"
				isOrderable="{ orderable.selected }" useListBuilder="{ listBuilder.selected }"/>					

		</mx:HBox>
	</mx:Panel>
</mx:Application>

I consider this to be a version 0.9. It seems to work pretty well but I’m sure there’s a bug or two hiding in there. There are also a couple of more features I’d like to implement.

There’s no copyright… please use the code freely. I just ask that if you come up with any improvements you email them back to me.

Hope you find this component useful,
Hillel

Flex Tip: How to get all items (ignoring the filter) in an ArrayCollection

If you have an ArrayCollection with a filter function set and you loop through the items, you’ll only see the items which match the filter. The catch is sometimes you want to see them all. Initially I was doing the following.

var filterFunction:Function = arrayCollection.filterFunction;
arrayCollection.filterFunction = null;
arrayCollection.refresh();
			
for each (var obj:Object in arrayCollection)
{
	// do stuff
}
			
arrayCollection.filterFunction = filterFunction;
arrayCollection.refresh();

This worked but was pretty ugly. Here’s a nicer approach:

for each (var obj:Object in arrayCollection.source)
{
	// do stuff
}

What I keep finding in Flex is that I’m able to come up with complex code to solve simple problems but when I revisit it months later there’s usually a more straight-forward solution.

Hope this helps,
Hillel

Flex DataGrid: Click once to select, click twice to edit

In the application I’m working on there’s a datagrid which when the user selects a row we update the info on the side page. The catch was we also enabled editing in the datagrid. It was strange to click the row to see the details on the side and then immediately be in edit mode.

Initially we required that the user double-click a field to edit it. The solution was based on the comment provided by Jana in this post.

The concern was that a user may not realize that you needed to double-click to edit the field. In the code provided below the user can select a row by clicking it. If they then click a field in the selected row it will switch in to edit mode.

<?xml version="1.0" encoding="utf-8"?>
<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml">
	
	<mx:Script>
		<!&#91;CDATA&#91;
			import mx.controls.listClasses.IListItemRenderer;
			import mx.events.ListEvent;
			
			private var _selectedRow:int = -1;
			private var _clickCount:uint;
			
			override protected function mouseUpHandler( event:MouseEvent ):void 
			{
				editable = (_clickCount == 2);
				
				super.mouseUpHandler( event );													
			}
			
			override protected function selectItem( item:IListItemRenderer, shiftKey:Boolean, ctrlKey:Boolean, transition:Boolean=true ):Boolean
			{
				var returnValue:Boolean = super.selectItem( item, shiftKey, ctrlKey, transition );
				
				if (selectedIndex == _selectedRow)
				{
					_clickCount = 2;
				}
				else
				{
					_selectedRow = selectedIndex;
					_clickCount = 1;
				}
				
				return returnValue;			
			}
			
		&#93;&#93;>
	</mx:Script>

</mx:DataGrid>

Hope you find this helpful,
Hillel