Truncating HTML Text

With Flex truncating text within a Label control is easily done by setting the property “truncateToFit” to true. This parameter doesn’t do much when using the Text or TextArea controls in Flex. To truncate text in these controls you would have to build your own function to count characters and add the ellipses. There is one good example of creating your own custom Text control that truncates the text in the same manner as the Label control based on size of the control.

Now if you want to truncate HTML text within a Text or TextArea control thinks become more complicated. Currently in Flex doing anything with HTML is pretty dismal as there are not many ways to control the display of HTML or capture user interaction with HTML text. This seems to be changing with the upcoming release of Flash Builder 4 and the new spark components for displaying text and also the new Text Layout Framework . In the mean time you still might like to truncate HTML text in Text and TextArea controls.

I did find one blog post describing one method for truncating HTML text based on the size of the control. However, I wanted more restriction of the length of my HTML displayed and also wanted a way to better handle links that use the TextEvent to fire events from links clicks. There seem to be plenty of examples of HTML truncation within JavaScript and Java. I am lucky to have a girlfriend who also develops Java (and is also good looking :D). I asked her for an example of HTML truncation and then translated that code in to working Flex code, which was surprisingly easy to convert.

Below is an example application that will truncate HTML text to any character length given. The truncation will not occur mid-link tag, only the text inside the links is counted you have the option to put a “… more” link at the end of the truncation to expand the text to its full length. I also gave the HTML a little extra formatting to distinguish links from regular text and add some rollover behavior for HTML links (something also missing from Flex). If the text Some limitations include image tags, break tags, and wrapping the entire block of text into a tag (However there is an easy work around that you can see in source code). The reason these limitations exist is because I only needed to truncate text that contain links. So the example will have to be expanded to include other tags.

Example

Complete Code


<![CDATA[

import flash.net.navigateToURL;

// string data to play with
 private var loremIpsum:String = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
 "Curabitur ultrices orci non felis luctus non sollicitudin magna aliquet." +
 " Curabitur lacinia dignissim <a>accumsan</a>. " +
 "Mauris ac dui in enim tristique egestas eu ac arcu. " +
 "Quisque scelerisque, odio et luctus tempus, felis ante euismod felis, quis laoreet quam " +
 "turpis in diam <a>http://www.google.com</a>. " +
 "Integer ut lectus id justo feugiat posuere. Vestibulum tempor porttitor " +
 "justo, sed consequat dui lobortis ut. <a>Aliquam</a> " +
 "a posuere diam. Vestibulum turpis purus, " +
 "dapibus id sagittis nec, volutpat ultricies leo. <a>Pellentesque</a> tempus pulvinar ornare. " +
 "Cras vel sapien vitae mauris tincidunt <a>http://www.google.com</a>" +
 " laoreet quis congue nisl. Aliquam pharetra nunc " +
 "quis tortor adipiscing quis <a>elementum</a> nulla venenatis. " +
 "Suspendisse potenti. Mauris " +
 "vitae enim sed nisl viverra venenatis <a>http://www.google.com</a>. " +
 "Proin auctor <a>mattis</a> mollis. Phasellus ultrices " +
 "ornare ullamcorper. Sed <a>turpis</a> quam, tempus eget luctus eget, posuere vitae lorem. " +
 "In vitae sem id lorem aliquam <a>viverra</a>."

private function init():void
 {
 this.destinationText.styleSheet = this.getTextStyle();
 this.destinationText.addEventListener(TextEvent.LINK, handleLinkClick);
 this.destinationText.htmlText = "" + loremIpsum + "";
 this.sourceText.addEventListener(TextEvent.LINK, handleLinkClick);
 this.sourceText.styleSheet = this.getTextStyle();
 this.sourceText.htmlText = "" + loremIpsum + "";
 return;
 }

private function truncateText():void
 {
 var limit:Number = limitStepper.value;
 this.destinationText.htmlText = "" + this.truncateHTMLText(loremIpsum, limit, true) + "";
 this.destinationText.styleSheet = this.getTextStyle();
 return;
 }

/**
 * Handle the click action on links within the html text using TextEvent.
 * */
 private function handleLinkClick(event:TextEvent):void
 {
 var prefix:String = event.text;
 var split:Array = prefix.split(":");
 var type:String = split[0];
 var id:String = split[1];

if(split.length > 2) id = split[1] + ":" + split[2]; // recreate the http link

if(type == "more"){
 this.destinationText.htmlText = "" + loremIpsum + ""; // reset to original text length
 this.destinationText.styleSheet = this.getTextStyle();
 return;
 } else {
 var request:URLRequest = new URLRequest(id);
 navigateToURL(request,"_blank");
 }

return;
 }

/**
 * Truncate html text.
 * @param value The original text value
 * @param limit The maximum number of characters to show
 * @param ellipses Boolean value to show elipses at the end of truncation.
 * */
 private function truncateHTMLText(value:String, limit:Number, ellipses:Boolean = true):String
 {
 if(limit == 0)
 return "";

var original:String = value;

value = value.replace("[\\t\\n\\x0B\\f\\r\\u00A0]+", "");

var isTag:Boolean = false;
 var count:int = 0;
 var position:int = 0;
 var limitLength:int = value.length - 1;
 var closeTag:Boolean = false;

for(var i:int = 0; i ') {
 isTag = false;
 if(closeTag || i == limitLength) {
 position = i;
 break;
 }
 continue;
 } else {
 continue;
 }
 } else {
 if(c == '<') {
 isTag = true;
 } else {
 count++;
 if(i == limitLength || (count == limit)) {
 if(((i+1) < limitLength) && ((i+2) < limitLength)) {
 if(value.charAt(i+1) == '= value.length) ? ' ' : value.charAt(length);

if(last != ' ' && last != '>' && nextChar != ' ' && nextChar != '<')
 result = result.substring(0, result.lastIndexOf(' ') + 1);
 var lastStartTag:int = result.lastIndexOf('<');

if(lastStartTag != -1) {
 var ch:String = result.charAt(lastStartTag + 1);
 if(ch != '/') {
 result = result.substring(0, lastStartTag);
 }
 }

if(original.length == result.length)
 return original;

if(result.length == 0)
 return result;

var pattern:RegExp = new RegExp("(.*?)(\\s*\.\.\.\\s*)([\\\s*$]+)", "i");

if(result.search(pattern) == -1 && ellipses)
 result += "...";

return (result + "<a>[more]</a>");
 }

/**
 * Let's add a little style to the HTML text and mouse roll-over actions.
 * */
 private function getTextStyle() : StyleSheet
 {
 var fonts:String = "Arial, _sans";
 var textStyle:StyleSheet = new StyleSheet();
 textStyle.setStyle(".body", {fontFamily:fonts, fontSize:"12", fontWeight:"normal", color:"#222222", textDecoration:"none"});
 textStyle.setStyle("a", {color:"#245290", textDecoration:"none"});
 textStyle.setStyle("a:link", { textDecoration: "none", color: "#245290" });
 textStyle.setStyle("a:hover", { textDecoration: "underline" });

return textStyle;
 }
 ]]>

Download: TextTruncation Flex Project File

- Mister

About these ads

13 thoughts on “Truncating HTML Text

  1. Hi Mr thank you mister,
    I am very new to flex.I find there are so many complex tutorials on the web for flex 3.I just wanted to know how to add an html file or a text file from an asset folder to the text area component in flex.i can’t find any.Because i want to be able to edit this file outside of the application….your help will be greatly appreciated….
    Thanks.

    • With AIR you just load the file from the local directory just like you load an XML file. From Flex in a browser you need a URL to load the file and again, load it like XML but with text format instead of e4x.

  2. Hi,

    That was cool! Am actually looking for Java code to truncate HTML. Can you publish that if you still have it?

    Thanks

    • The Java code was created by my spouse, my own personal in-house Java developer. I don’t believe we saved the code as she only created the example for me to convert to Flex. You can change the current class back to Java easily enough though.

  3. Very cool script you made there!
    I’m trying to implement it to a TextField that can truncate given a max width and height, and it works almost perfectly.

    I do seem to have problems with a text that start with a paragraph tag and ends with one. I get returned at the result.length == 0.

    Is it a special case or a natural limitation in the script?

    Thanks for the great code though!

  4. Hi Mister,

    This code doesn’t completely work for me. I am using Flex builder 3.

    Methods::

    getTextStyle() and
    truncateHTMLText()

    are not working.

    Can you please let me know. Why they are NOT working?

    Cheers,
    Naveen

  5. @Naveen,

    I just copied the code, created a new Flex 3 application, pasted the code in the main MXML file and it ran just fine. Not sure what you are doing wrong, but it works.

  6. Hey Mister,

    truncateHTMLText() is working. Actually some how getTextStyle() is not working. i have commented getTextStyle() throughout the code. Everything works fine.

    don’t know why getTextStyle() is not working for me

  7. I uploaded a Flex Project file with the working example, you can see if this works for you. Just refresh the blog page to get the new project file link.

  8. Still styles(underline and blue color. But hover is working when mouse over on the link it shows hand symbol and when i click on it it takes me to google page) not working. But it is Ok Mister because i was looking for only truncate htmlText and it is working for me. Now i will try to use this method in my project. I hope it works there also.

    Anywayz Thanks a lot Mister.

    Thank you.

    Naveen

Comments are closed.