Posts Tagged ‘textArea’
In working toward a simple, Flex-based CMS, I wanted to be able to load external html content without having to write numerous URLRequests in the main Flex project file, so I decided to just extend the TextArea component with a method for loading an external file.
Flex doesn’t handle html very well at all at this point, yet there are numerous ways to extend its capabilities and many others have already done just that. For sake of simplicity, I kept the functionality as it is and basically, whatever the Flex RichTextEditor component can output, this extendedTextArea can accept as input.
<?xml version="1.0" encoding="utf-8"?> <mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ [Inspectable(defaultValue="")] private var _url:String = ""; public function set url (requestedURL:String):void { urlLoad(requestedURL); } public function get url ():String { return _url; } private function urlLoad(requestedURL:String):void { var request:URLRequest = new URLRequest(requestedURL); var loader:URLLoader = new URLLoader(); loader.load(request); loader.addEventListener(Event.COMPLETE, onComplete); } private function onComplete(event:Event):void { var loader:URLLoader = URLLoader(event.target); //replace linefeed characters since Flex displays them otherwise this.htmlText = loader.data.toString().replace(/\r|\n/gm,""); } ]]> </mx:Script> </mx:TextArea>
And here we have an example application of the above externalTextArea which loads a simple index.html file located in the same directory as the swf.
TextArea
{
cornerRadius: 5;
}
Application
{
backgroundColor: #FFFFFF;
}Example: dm_external_TextArea.swf
Flex Project: dm_external_TextArea.zip
On my way to building my own Flex-based chat application, I came to learn that displaying smileys, or emoticons as they’re often known, is one of the most difficult things to achieve in Flash/Flex. I scoured Google once again searching for a ready-made component and found no such thing. I began a tedious endeavor to do it myself and I offer my rough stab at it here, open source and free for all.
So, the method I chose to display the smileys was to use a standard Flex Canvas which receives the smiley images as children and itself contains a child TextArea which receives the text and grows in height depending upon the size of the text. The TextArea thereby lies in back of the smileys. The Canvas’ scrollbar is set to auto and when the TextArea grows past the display height of the Canvas, the scrollbar is then displayed, allowing the text and smileys both to be scrolled simultaneously, an otherwise difficult task that actually came very easily given the method used.
There are many things I’ve overlooked and possibly bugs to be found, but in general, it works rather well. I’ve used an extended CoolRichTextEditor component which allows the controlbar to be arranged above the text area rather than below it. The component was developed by someone else and for the life of me, I can’t seem to find the developer’s site again. If someone finds it, I’d be awfully gracious if they might post a link to the site so that I might give the author proper credit. I also included a set of smileys which I assume to be under a creative commons license since the only reference I could find was on Wikimedia Commons.
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="#FFFFFF" width="100%" height="100%" creationComplete="init()" xmlns:ns1="*" viewSourceURL="srcview/index.html"> <mx:Script> <![CDATA[ import mx.controls.Image; import flash.events.KeyboardEvent; import mx.core.mx_internal; use namespace mx_internal; public var smiles:XML; public function init():void { //we want the textArea control to grow in height with its content textArea.height = textArea.textHeight + 10; textInput.addEventListener(KeyboardEvent.KEY_DOWN, keyDown); textInput.textArea.setFocus(); //we'll define smileys here, though these can be read in from xml file smiles = <smiles> <smile file="angry.gif" code=":{" width="20" height="20" /> <smile file="smile.gif" code=":)" width="20" height="20" /> <smile file="smile.gif" code=":-)" width="20" height="20" /> <smile file="biggrin.gif" code=":D" width="20" height="20" /> <smile file="ohmy.gif" code=":O" width="20" height="20" /> <smile file="sad.gif" code=":(" width="20" height="20" /> <smile file="sad.gif" code=":-(" width="20" height="20" /> <smile file="tongue.gif" code=":p" width="20" height="20" /> <smile file="wink.gif" code=";)" width="20" height="20" /> </smiles>; //set some initial text textInput.textArea.htmlText="Smileys example.
Available smileys: :{,:),:D,:O,:(,;),:p."; //run the smileyHandler routine right at the start smileyHandler(); } private function keyDown(event:KeyboardEvent):void { // Check to see if ENTER pressed. if (event.keyCode == Keyboard.ENTER) { smileyHandler(); } } public function smileyHandler():void { var smileyIndex:int = -1; var searchIndex:int = -1; var testSearchIndex:int = -1; var testString:String; var searchString:String = textInput.htmlText; //recurse through all smileys to see if they occur in searchString for (var x:int = 0; x < smiles.child("*").length(); x++) { //setup testString by escaping various punctuation marks before search testString = smiles.smile[x].attribute("code").toString().replace(/(\)|\()/, "\\$&"); searchIndex = searchString.search(testString); if (searchIndex >= 0) { //occurrence of this smiley found. test for previous occurence //and see if it's earlier in the text than this occurence if (testSearchIndex < 0) { //no previous smiley found, this is the first testSearchIndex = searchIndex; smileyIndex = x; } else { //previous smiley found. test if this occurrence is earlier //in text than previous occurence if (testSearchIndex > searchIndex) { testSearchIndex = searchIndex; smileyIndex = x; } } } } searchIndex = testSearchIndex; var newText:String = ""; var oldText:String = textArea.htmlText; //if no smiley found, add textInput to textArea if (searchIndex < 0) { newText = textInput.htmlText; } //recurse until no smileys found in searchString while (searchIndex >= 0) { //set replacement string as text smiley with background color so that it's semi-invisible var smileyReplaceString:String = '<FONT COLOR="#' smileyReplaceString += chatCanvas.getStyle("backgroundColor").toString(16); smileyReplaceString += '"> '; smileyReplaceString += smiles.smile[smileyIndex].attribute("code"); smileyReplaceString += ' </FONT>'; //slice searchString at index where smiley occurs and put that in textArea for operation //notice: +1 is added to searchIndex here to compensate for smiley at index 0 textArea.htmlText = oldText + newText + searchString.slice(0, searchIndex + 1); textArea.validateNow(); //get necessary coordinates and display smiley var numLines:int = textArea.mx_internal::getTextField().numLines; var smiley:Image = new Image(); smiley.source = "assets/" + smiles.smile[smileyIndex].attribute("file"); smiley.x = textArea.getLineMetrics(numLines - 1).width; smiley.y = textArea.textHeight - textArea.getLineMetrics(numLines - 1).height; chatCanvas.addChild(smiley); newText += searchString.slice(0, searchIndex) + smileyReplaceString; var codeLength:int = smiles.smile[smileyIndex].attribute("code").toString().length; searchString = searchString.slice(searchIndex + codeLength); //begin with smiley search again searchIndex = -1; testSearchIndex = -1; smileyIndex = -1; for (x = 0; x < smiles.child("*").length(); x++) { //setup testString by escaping various punctuation marks before search testString = smiles.smile[x].attribute("code").toString().replace(/(\)|\()/, "\\$&"); searchIndex = searchString.search(testString); if (searchIndex >= 0) { //occurrence of this smiley found. test for previous occurence //and see if it's earlier in the text than this occurence if (testSearchIndex < 0) { //no previous smiley found, this is the first testSearchIndex = searchIndex; smileyIndex = x; } else { //previous smiley found. test if this occurrence is earlier //in text than previous occurence if (testSearchIndex > searchIndex) { testSearchIndex = searchIndex; smileyIndex = x; } } } } searchIndex = testSearchIndex; if (searchIndex < 0) { newText += searchString; } } textArea.htmlText = oldText + newText; textArea.validateNow(); //set height of textArea to height of new text content textArea.height = textArea.textHeight + 10; //clear textInput textInput.htmlText = ""; //scroll to bottom of canvas chatCanvas.validateNow(); chatCanvas.verticalScrollPosition = chatCanvas.maxVerticalScrollPosition; } ]]> </mx:Script> <mx:VBox x="0" y="0" width="100%" height="100%"> <mx:Canvas id="chatCanvas" width="100%" height="90%" horizontalScrollPolicy="off" backgroundColor="#FFFFFF" borderStyle="solid"> <mx:TextArea width="100%" id="textArea" editable="false" fontSize="12" verticalScrollPolicy="off" borderStyle="none"> </mx:TextArea> </mx:Canvas> <ns1:CoolRichTextEditor width="100%" height="147" id="textInput" cornerRadius="5" headerHeight="0" roundedBottomCorners="true" verticalScrollPolicy="off" fontSize="12" controlBarPosition="top"/> </mx:VBox> </mx:Application> |
Example: dm_smileys.swf
Flex Project: dm_smileys.zip