Displaying html content inside Flex labels is not as straight forward as it was in Flex 3 by simply setting the 
htmlText property.  Here are the 3 Spark controls used for displaying text:
- Label - lightweight plain text only
- RichText - as the name says it provides support for rich text.
 Also allows html content to be imported (anchor tags <a> don't work)
- RichEditableText - provides the same rich text support as the RichText control.
 Allows editing and anchor html tags work properly
Here is a list of the 
supported HTML tags: 
<div>, <p>, <a>, <span>, <img>, <br>.
As noted above, if you want to use anchor 
<a> tags, you must use a 
RichEditableText control.  In this case you'd most likely want to also set the 
editable="false" property.
The anchor 
href property can be set to a relative path like
<a href="index.html">index</a>
Or an absolute one like
<a href="http://google.com" target="_blank">google</a>
Note that you can set the 
target property to control whether the link is opened in a new window or not.
If you want to listen for when the user clicks on an anchor it is possible, but involves a lot more work.  Basically you import the html string into a 
TextFlow object.  Then you iterate through all the child elements until you find the 
LinkElement (which represents the anchor tag), and then add a 
FlowElementMouseEvent.CLICK event listener.
Here is some sample code that I use to achieve this:
   | /*** Converts the html string (from the resources) into a TextFlow object
 * using the TextConverter class. Then it iterates through all the
 * elements in the TextFlow until it finds a LinkElement, and adds a
 * FlowElementMouseEvent.CLICK event handler to that Link Element.
 */
 public static function addLinkClickHandler(html:String,
 linkClickedHandler:Function):TextFlow {
 var textFlow:TextFlow = TextConverter.importToFlow(html,
 TextConverter.TEXT_FIELD_HTML_FORMAT);
 var link:LinkElement = findLinkElement(textFlow);
 if (link != null) {
 link.addEventListener(FlowElementMouseEvent.CLICK,
 linkClickedHandler, false, 0, true);
 } else {
 trace("Warning - couldn't find link tag in: " + html);
 }
 return textFlow;
 }
 
 /**
 * Finds the first LinkElement recursively and returns it.
 */
 private static function findLinkElement(group:FlowGroupElement):LinkElement {
 var childGroups:Array = [];
 // First check all the child elements of the current group,
 // Also save any children that are FlowGroupElement
 for (var i:int = 0; i < group.numChildren; i++) {
 var element:FlowElement = group.getChildAt(i);
 if (element is LinkElement) {
 return (element as LinkElement);
 } else if (element is FlowGroupElement) {
 childGroups.push(element);
 }
 }
 // Recursively check the child FlowGroupElements now
 for (i = 0; i < childGroups.length; i++) {
 var childGroup:FlowGroupElement = childGroups[i];
 var link:LinkElement = findLinkElement(childGroup);
 if (link != null) {
 return link;
 }
 }
 return null;
 }
 | 
A simple control that I've created and use frequently is called 
HtmlLabel which extends the 
RichEditableText class to provide simple support for html text:
   | <?xml version="1.0" encoding="utf-8"?><s:RichEditableText xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/mx"
 focusEnabled="false"
 selectable="false"
 editable="false">
 
 <fx:Script>
 <![CDATA[
 import flashx.textLayout.conversion.TextConverter;
 
 override public function set text(value:String):void {
 super.textFlow = TextConverter.importToFlow(value,
 TextConverter.TEXT_FIELD_HTML_FORMAT);
 }
 ]]>
 </fx:Script>
 
 </s:RichEditableText>
 | 
2 comments:
Thanks for writing up the example.
Thank your for this well structured code. We are upgrading to TLF to support arabic language and this was a huge time saver
Post a Comment