Quick Tip (Flex 4): Using asfunction in TLF (Text Layout Framework)

Do you remember the very old school global function called asfunction? It was used to call custom ActionScript methods clicking an HTML link. The definition in HTML was something like this: < a href='asfunction:myFunction' >my link< /a > .

Since ActionScript 3 asfunction has been deprecated and was replaced with a new event handling using TextEvent.LINK and 'event:myEventType' defined at the HTML link. For example < a href='event:myEventType' >my link< /a > . In this case you have to add just one event listener to handle all(!!) events.

Flex 4 + Text Layout Framework + asfunction?

But what happens if you want to call an ActionScript method clicking an HTML link and using the Text Layout Framework (TLF) in Flex 4?

RichEditableText is the TLF component to embed a clickable HTML text, but it does not support an event handler for a TextEvent.LINK event. Today I ran into this issue and I couldn’t find any solution (either at official Flex doc or not at Google).

Anyway, the solution it is pretty easy. Just define your HTML links as before in Flex 3 and add an event listener for every (!!) event to a TextFlow of a RichEditableText

ASFunctionExample.mxml ( Download code )

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:VGroup
  3.     xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:s="library://ns.adobe.com/flex/spark"
  5.     xmlns:mx="library://ns.adobe.com/flex/halo"
  6.     >
  7.     <fx:Script>
  8.         <![CDATA[
  9.             import flashx.textLayout.conversion.TextConverter;
  10.             import flashx.textLayout.events.FlowElementMouseEvent;
  11.            
  12.             import mx.events.FlexEvent;
  13.  
  14.             /**
  15.              * HTML string
  16.              * Note the anchor using ‘event:myEventType’ to call an ActionScript method
  17.              */
  18.             protected static const HTML: String =   "<p>Hello, here is a link to "
  19.                                                     + "<a href=’event:myEventType’>run my custom method</a>"
  20.                                                     + "</p>";
  21.    
  22.             /**
  23.              * Adding listener to for event:myEventType defined in HTML
  24.              * at a TextFlow of RichEditableText
  25.              *
  26.              */   
  27.             protected function richtext1_initializeHandler(event:FlexEvent):void
  28.             {
  29.                 myText.textFlow.addEventListener( ‘myEventType’, customMethodHandler );
  30.             }
  31.  
  32.             /**
  33.              * Custom event handler for event:customMethod defined in HTML
  34.              *
  35.              */    
  36.             protected function customMethodHandler( event:FlowElementMouseEvent ):void
  37.             {
  38.                 result.text += "run custom method\n";
  39.             }
  40.  
  41.         ]]>
  42.     </fx:Script>
  43.    
  44.    
  45.     <s:RichEditableText
  46.         id="myText"
  47.         width="100%"
  48.         selectable="false"
  49.         editable="false"
  50.         initialize="richtext1_initializeHandler(event)"
  51.         textFlow="{ TextConverter.importToFlow( HTML, TextConverter.TEXT_FIELD_HTML_FORMAT ) }"
  52.         />
  53.        
  54.     <s:TextArea
  55.         id="result"
  56.         />
  57.  
  58.    
  59. </s:VGroup>

Some notes:

  • To have an clickable HTML link using RichEditableText, its property selectable and editable has to be ‘false’
  • Anchors defined in HTML will be a LinkElements at the TLF
  • All events will be dispatched from this LinkElement as a FlowElementMouseEvent. Its type is a ‘custom’ type and will be the same as defined in HTML.
  • Any ‘asfunction’ call has to be defined in HTML using ‘event:myEventType’. The LinkElement will check itself if the link includes an url or just an ‘asfunction’ call.
  • To listen all events you have to add different listeners for each event type to a TextFlow of a RichEditableText.

-Jens

Flex

 

12 Comments

  • Hussein says:

    have you got any idea how to do that in flash cs4?
    Thats a Snipped from my project:
    function createTxtLayout(X, Y, W, TXT)
    {
    //trace(“Pages ——- createTxtLayout”);
    var containerFormat:ContainerFormat;
    var xmlTXT:XML;
    xmlTXT = XML(TXT);
    = new TextLayout()
    addEventListener(“event”, customMethodHandler);//@ADDED
    addChild(TXTLayout);
    TXTLayout.xmlText = xmlTXT;
    TXTLayout.x = X;
    TXTLayout.y = Y;
    popupSprite = new Sprite();//@ADDED
    addChild(popupSprite);//@ADDED
    popupSprite.name = “popupSprite”;//@ADDED

    }
    function customMethodHandler( event:FlowElementMouseEvent ):void
    {
    trace(“customMethodHandler”);
    }
    Snippet From XML:

    The estrogens are a class of hormone. The three most important estrogens are < a href="{DELI} a protein, usually in the cell membrane, to which other proteins (called ligands) bind, altering the activity of biochemical pathways in that cell" rel="nofollow" >estrone< /a >,< a href="#" rel="nofollow" >estradiol< /a >, and < a href="#" rel="nofollow" >estriol< /a >. These are often referred to as E1, E2 and E3 respectively. Estradiol is the most potent and the most important component of HT while estriol is the weakest and least important. One type of estrogen can be converted to another type in the body.Estradiol – also known as 17?-estradiol – is the key ingredient in the Estradot patch. More details can be found in Module 2 – Estradot: the product

  • Chris says:

    Thanks for the helpful article; as more users migrate to FP 10, we’ll be focusing more dev time on the TLF as it seems to be an excellent tool for multi-locale type deliverables. I was wondering if, in your travels, you have found any resources/tutorials on the TLF particularly helpful?
    Thanks again,
    Chris

  • sectore says:

    @Hussein: Please check the code example “ASFunctionExample.mxml” (incl. its HTML link definitions) and the notes above. BTW: You have to add a listener method for a FlowElementMouseEvent to a Textflow ;)

    @Chris: A very helpful tutorial I have found is called “How to use Text Layout Framework in Flex 3.2 or AIR 1.5″ by Mihai Corlan.

    -Jens

  • Hussein says:

    Cheers Mate,
    I’m stuck on this last thing to do to wrap up my project.I’m new to Textlayout framework, the only reason i have used it because of the support of super/subscript.
    Then the client asked for popup from hyperlinked.as my html content is in XML i didnt run in any problem while doing the popup through normal textfield.
    But i cant get my head round it how to do the same in textlayout as my textflow is defined inside the XML.
    I have tried applying the same concept that i have done for the texfield without anyluck.

    NORMAL TEXTFIELD SNIPET:
    function createDesc(X, Y, W, TXT, CSS):void
    {
    //trace(“Page —— createDesc”);
    var _txt:TextField;
    var _str:String;
    _str= TXT;
    _txt= new TextField();
    _txt.styleSheet = CSS;
    _txt.multiline = true;
    _txt.condenseWhite = true;
    _txt.htmlText = _str;
    _txt.selectable = false;
    _txt.width = W;
    _txt.autoSize = TextFieldAutoSize.LEFT;
    _txt.wordWrap = true;
    //_txt.embedFonts = true;
    _txt.x = X;
    _txt.y = Y;
    addEventListener(TextEvent.LINK, linkHandler);
    addChild(_txt);
    popupSprite = new Sprite();
    addChild(popupSprite);
    popupSprite.name = “popupSprite”;
    return;

    }
    //——————————-linkHandler——-
    function linkHandler(linkEvent:TextEvent):void
    {
    trace(“Page —— linkHandler”);
    var _strTitle:String;
    var _strMeaning:String;
    var glossaryArray:Array = linkEvent.text.split(“{DELI}”);
    _strTitle = glossaryArray[0];
    _strMeaning = glossaryArray[1];

    //Clearning Sprite from old popups
    for(var i:int=0;i<popupSprite.numChildren; i++)
    {

    popupSprite.removeChild(popupSprite.getChildAt(i));
    }
    if(popupSprite.numChildren == 0)
    {
    //trace("Sprite is Empty");
    createPopup(_strTitle,_strMeaning);
    }

    }

    //TEXTLAYOUT FUNCTION
    function createTxtLayout(X, Y, W, TXT)
    {
    //trace("Pages ——- createTxtLayout");
    var containerFormat:ContainerFormat;
    var xmlTXT:XML;
    xmlTXT = XML(TXT);
    //TXTLayout = new TextLayout()
    addEventListener("event", customMethodHandler);//@ADDED
    addEventListener(MouseEvent.CLICK, customMethodHandler);
    addEventListener(MouseEvent.MOUSE_DOWN, customMethodHandler);
    addEventListener(MouseEvent.MOUSE_MOVE, customMethodHandler);
    addEventListener(MouseEvent.MOUSE_UP, customMethodHandler);
    addEventListener(MouseEvent.ROLL_OVER, customMethodHandler);
    addEventListener(MouseEvent.ROLL_OUT, customMethodHandler);

    addChild(TXTLayout);
    TXTLayout.xmlText = xmlTXT;
    TXTLayout.x = X;
    TXTLayout.y = Y;
    popupSprite = new Sprite();//@ADDED
    addChild(popupSprite);//@ADDED
    popupSprite.name = "popupSprite";//@ADDED

    }
    //@ADDED
    function customMethodHandler( event:FlowElementMouseEvent):void
    {
    trace("customMethodHandler");
    }

    Can You enlighten me please?

  • Hussein says:

    Any help?

    Cheers.

  • Michael says:

    Hi , You code doesn’t work. Tried this example and the custom even is not dispatched at all.

  • MotionMaker says:

    I am noticing that if the binding value to RichEditableText changes the event listener for textFlow no longer works. Perhaps it is removed.

  • Pieter Bos says:

    Hi maybe its new to textflow but you just can handle the click event on the textflow object.

    Example here (with inline textflow and with a external xml file)
    http://www.flashaction.nl/tlflink/TextFlowLinkHandler.html
    Source here
    http://www.flashaction.nl/tlflink/srcview/index.html

  • JC says:

    Great sample. Thanks

    Is there a way to send parameter(s) like asfunction?
    eg.

    How you put the parameter r3_1_1 in the event and sent that to the function openSupport?
    Thanks

  • JC says:

    Found a better solution that support paramters too.
    Just override the click event handler of the textflow.

    tf.addEventListener(FlowElementMouseEvent.CLICK,rtClickHandler);

    Once you catch the event, parse the href that have parameter and do what ever you want depends on the href text.

    Thanks

  • Ron says:

    Do you have any idea, how to find the id of the link that was clicked or the text it said?

 

Leave a comment

*