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