Last week we looked at how Widget Properties work. This week we’ll see how to use them, and I’ll show you what Widget Properties process I use in my widgets.
How to Write Widget Properties
As we learnt last week, Widget Properties can only be created in the Properties Dialog mode, and the saveProperties() Template Method is usually the best place to do this as it is called just before Captivate requests the Widget Properties from the widget.
To create a new Widget Property, you must access the Widget Properties object (through the ‘properties’ property) and create a new property on it. I know, I know, there was an awful lot of ‘properties’ in the last sentence. It sounds complicated, and to a certain extent the concept can be, but the code is dead simple.
I’ll refer to Widget Properties as WP from now on, hopefully that will cut down the propertying
The property on the WP object will hold the data you save to it. Though initially that property will not exist on the WP object, once you create it, it will still be there when you check the WPs again.
Enough talk. Time for examples! Say the user had writen something in a text field in your interface, and you wanted to save this data to a WP called asdfasdf. Here is how you’d create that property.
1 | properties.asdfasdf = textField.text; |
I can assure you that asdfasdf is not an existing property on the WP object. In fact, I’d be pretty surprised if it’s an existing property on any object. However, just by assigning it a value, you create it.
Some of you may be raising your hands and asking about the good old 1119 error. You know the one you get when you misspell a property and the Flash compiler crashes the party saying:
Access of possibly undefined property asdfasdf through a reference with static type ClassName.
Well it’s true, this code usually would lead to that error. However, the WP object is special. It’s not one of those ‘static types’ it’s a ‘dynamic type’. Dynamic objects allow you to create properties on them that don’t naturally exist. Some dynamic objects you would have used before would be Arrays, Objects, and MovieClips.
There is no limit to how many properties you can create on a dynamic object. So you can create as many WPs as you like.
1 2 3 4 5 6 7 8 | override protected function saveProperties():void { properties.textFieldText = textField.text; properties.aNumberProperty = 72; properties.aStringProperty = "Greetings World"; properties.aBooleanProperty = true; properties.anArrayProperty = [1,2,3]; } |
WPs can only hold certain data types. Make sure you only save those data types to the object. If you tried saving a reference to the textField as a Widget Property instead of the textField’s text, that’s not going to work. Your whole WPs will probably fail as a result.
1 2 3 4 | override protected function saveProperties():void { properties.myDynamicTextHoldingProperty = textField; // This won't end well } |
These are the types of data that you can save as Widget Properties.
- Objects,
- Strings,
- Numbers,
- Booleans (true and false),
- Arrays, and
- Null.
Also, the items inside the Arrays and Objects must not fall outside the above list.
How do I Access Widget Properties?
Once a Widget Property has been created, it can be accessed in any of the other modes that receive Widget Properties (see last week’s post)
So say we were in the enterPropertiesDialog() Template Method and wanted to set our textField back to what it was in the previous Properties Dialog session, then you’d set textField’s text equal to the WP you stored its data in, like so:
1 2 3 4 | override protected function enterPropertiesDialog():void { textField.text = properties.textFieldText; } |
The Widget King Widget Properties Method
The problem with WPs is that they don’t come with defaults. When the Captivate Author opens up the Widget Properties interface for the first time, the WP object will be blank. In this case you need defaults set up. I like to have a variable for each of my WPs that holds its default value, then set my interface element equal to that variable. So for example, if we were using the textField example above, then the code would look like this.
1 2 3 4 5 6 | private var textFieldDefaultText:String = "Default Text"; override protected function enterPropertiesDialog():void { textField.text = textFieldDefaultText; } |
When the Widget’s Properties Dialog opens up, the textField will be given the default text. However, before I set up the textField, I’ll insert a call to a function called checkProperties(), then go down and define that function.
1 2 3 4 5 6 7 8 9 10 11 12 | private var textFieldDefaultText:String = "Default Text"; override protected function enterPropertiesDialog():void { checkProperties(); textField.text = textFieldDefaultText; } private function checkProperties():void { } |
There I will put in an if statement that checks if the setBefore WP equals true. If so, then I’ll set the textFieldDefaultText variable equal to the textField’s Widget Property.
1 2 3 4 5 6 7 8 | private function checkProperties():void { if (properties.setBefore == true) { textFieldDefaultText = properties.textFieldText; } } |
Then in my saveProperties() Template Method, I’ll extract the data from my interface and save it to WPs. Then at the end I’ll set the setBefore WP to true. So all up the code would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | private var textFieldDefaultText:String = "Default Text"; override protected function enterPropertiesDialog():void { checkProperties(); textField.text = textFieldDefaultText; } private function checkProperties():void { if (properties.setBefore == true) { textFieldDefaultText = properties.textFieldText; } } override protected function saveProperties():void { properties.textFieldText = textField.text; properties.setBefore = true; } |
Let’s run through the process and see how it works. The first time around, there is no setBefore property, so the if statement comes back false and the textFieldDefaultText property stays at its default value. When the properties are saved, the setBefore property is created with a true value. That means for every time afterwards the if statement returns true and the default variable’s value is swapped out with the saved property’s value. Then when that variable is applied to the interface, it’s the saved value, not the default value, which is assigned.
To add another property, create another default variable, set its associated interface element equal to that variable in enterPropertiesDialog(), associate the variable with its WP in the checkProperties() method, and save the interface element’s value to the WP in the saveProperties() Template Method.
This gives you a water tight properties system. I keep the code in the checkProperties() method separate so I can use it in other Widget Modes.
There are many different ways to handle Widget Properties. If you have your own particular method, by all means feel free to share it with us.

