Displaying the remaining characters available for a Flex 4 TextInput or TextArea
Posted by Ian Serlin | Tweet This | Filed under Adobe Flex, problem solution
Problem
There are many instances where I need to allow a user to enter free-form text but the amount of text they can enter is limited to a certain number of characters, obviously it is good user experience design to provide feedback to the user on how many characters they have left available to enter so they can plan accordingly. Twitter anyone?
Solution
The following component takes any target derived from SkinnableTextBase and attaches an event listener to the KeyboardEvent.KEY_UP event. It calculates the available characters left by inspecting the maxChars property of the target input you register with it. To cancel watching of a target so the component can be garbage collected properly call dispose(), to reset the display call reset(). Easy peasy but nice to have one component to do this for you and in Flex 4 you can target the styling of the character count down display using regular CSS selectors.
CharacterCountDown.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <?xml version="1.0" encoding="utf-8"?> <s:Label xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" fontSize="14" fontWeight="bold" right="0" bottom="0" addedToStage="reset()"> <fx:Script> <![CDATA[ import spark.components.supportClasses.SkinnableTextBase; /** * If true, the CharacterCountDown will look something like "123". * If false, the CharacterCountDown will look something like "123 characters left". * * @default true */ public var onlyNumbers:Boolean = true; [Bindable] private var _target:SkinnableTextBase; /** * Set the component that this CharacterCountDown instance will watch. */ public function set target( value:SkinnableTextBase ):void { _target = value; if( _target != null ){ _target.addEventListener( KeyboardEvent.KEY_UP, handleKeyUp ); } } public function get target():SkinnableTextBase { return _target; } public function reset():void { this.text = ""; } private function handleKeyUp( e:KeyboardEvent ):void { var characters_left:int = (target.maxChars - target.text.length); this.text = String( characters_left ); if( !onlyNumbers ){ this.text += " character" + ( characters_left != 1 ? 's' : '' ) + " left"; } } /** * Causes the CharacterCountDown to stop watching any previously assigned target. */ public function dispose():void { if( _target != null ){ _target.removeEventListener( KeyboardEvent.KEY_UP, handleKeyUp ); _target = null; } } ]]> </fx:Script> </s:Label> |
If you have a better way to solve this problem or you want to improve the CharacterCountDown component write it up and let me know by linking to it in the comments.