Writing components in Flex, part 2
On August 7, 2008, Components,Flex - 8 CommentsIn part two of this tutorial, we’re gonna create the actual component. We left off with a flex library and a folder structure.
If you haven’t read the first part, click here.
Create a new actionscript class and name it after your component. Also, decide wether your class should extend an existing class. In this example it makes sense to extend the textinput class, which will provide the basic functionality. If your component will be part of the interface, you should extend sprite, or any underlying class of sprite. If your component doesn’t have any graphical interface, like a currency converter, you do not need to extend any class.
Creating the watermark
Now, my component needs a text or label to hold the watermark. I choose the Label, because it has build in support for trimming the text if it’s too long. The label will become private, the user doesn’t have to access it directly.
Define the label as private in your class and add it as a child. It’s good practice to add the child in the createChildren() method, like this:
private var _label:Label; override protected function createChildren():void { super.createChildren(); this._label = new Label(); this.addChild(this._label); } |
Don’t forget to call the super! When you create a displayObject after you’ve called the createChildren, it will be inserted on top of all other components, which is exactly what we want.
Next thing to do is provide a way to set the watermark. Now, you could just create a public variable which holds the watermark, but then you prevent users extending your component and adding custom functionalities. Instead, create a getter setter.
private var _watermark:String; public function set watermark(value:String):void { this._watermark = value; } public function get watermark():String { return this._watermark; } |
Of course, we do not only set the _watermark, we also have to set the label’s text property. However, here lies a dilemma. When you set the watermark property by mxml in an application, it will be set before the children are created, thus our label will still be null.
There are two ways around this (or more, but I’ll explain two). The first one is to instantiate the label immediatly after you’ve defined it, like
private var _label:Label = new Label(); |
Or, you check in the watermark setter if label has been instantiated, like this:
public function set watermark(value:String):void { this._watermark = value; if(this._label) this._label.text = value; } |
Note that with the 2nd method you also have to set the label’s text in the createchildren method, otherwise it will won’t have any value as the watermark has allready been set but skipped the part where the label receives it’s text.
We now have a label on top of the textinput.
It’s time to test the component for the first time. Open up the example project we’ve created earlier and add the component:
When we run this, we should see a textinput with ‘Test watermark’ over it….
… and we don’t. The reason we don’t see the watermark is that the label doesn’t have any width or height. You could just set a width and height, but it’s not very nice to have a fixed width. You also could create a getter setter for those properties, but why would a user want to set those properties?
No, the best way is to inherit those properties from the parent component. The best way to do this is to override the updateDisplayList method:
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); this._label.height = this.height; this._label.width = this.width; } |
If you run the example project again, you’ll see the watermark.
Adding the correct behaviour
We now have a label on top of the textinput, next thing to do is making it dissapear when the user clicks the input box. First, we create a getter / setter called watermarkVisible. This way, the user can extend this functionality (eg. by adding a fade to it). We also need to now when the the textinput receives focus. In the constructor of the class, add an eventlistener which listens to the FocusIn event. The eventhandler simply calls the watermarkvisible, which will set the visibility of the label to false.
Next thing to do is to make sure that the watermark will come up again if the focus leaves the textinput, which in essence is almost the same. But take into account that the watermark only needs to be shown when the input is empty. So when watermarkVisible is called and the value is true, also check if the field is empty:
public function set watermarkVisible(value:Boolean):void { this._watermarkVisible = value; this._label.visible = (this.text == "" && value); } |
Conclusion
That’s it for tonight. We now have a basic watermarkTextbox component. In the next tutorial we’ll be tweaking the component further. Also, we’re going to add some metatags, events, styles and documentation.
Here’s an example of the component so far:
Again, please let me know if you have any suggestions or questions!
What others have to say:
Great start to a much needed tutorial!
View source does not show the source but goes directly to your site.
[...] Source [...]
[...] Writing components in Flex, part 2 http://labs.flexperiments.nl/writing-components-in-flex-part-2/ [...]
[...] Writing components in Flex, part 2 http://labs.flexperiments.nl/writing-components-in-flex-part-2/ [...]
is there any way to be able to see the watermark already in flex builder’s design mode (like you can see the text of a label if you use the label component)?
Not sure if that’s possible, I think it’s a build-in feature of flexbuilder. I’m going to investigate it, I’ll let you know when I found something
edit
I stand corrected. The component does show the watermark in design mode, but only if the watermark is hard coded, it will not show bindable properties, not sure why…
[...] Right, it’s been more than a month now, time to round up this tutorial. If you haven’t read the previous parts, here’s part 1, and here’s part 2. [...]
[...] 编写Flex组件, part 2 http://labs.flexperiments.nl/writing-components-in-flex-part-2/ [...]
Leave a Reply