Macromedia Flex Macromedia Flex
Hyperlink component
  Home

Jan 11, 2007 - Hyperlink component
Extends Text, uses htmlText, uses custom event

While a "hyperlink" is soooo html, it is nevertheless familiar to web users, and I need one to mimic a certain look.  There are plenty of other ways to do this, but i decided to extend the Text control, and to use the htmlText property.  While this at first looked like the simplest way, in retrospect, the difficulty in styling the contents of htmlText suggests that it might not have been the best way.  Whatever, here it is, along with a test app showing its usage.  See the comments in the individual files for more info.

This example consists of 3 files: Hyperlink_test.mxml, Hyperlink.as, and HyperlinkEvent.as.  I hope someone finds it useful.

Tracy Spratt

<?xml version="1.0" encoding="utf-8"?>
<!-- This app shows the usage of the Hyperlink.as component and HyperlinkEvent.as custom event.
  Both of those files must either reside in the same folder as this file, or must be in
  a source-path folder. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns="*" layout="vertical" horizontalAlign="left">

<mx:Script><![CDATA[
  import Hyperlink;
  import HyperlinkEvent;
 
  /** run by bubbling custom event from Hyperlink component */
  private function onLinkClick(oEvent:HyperlinkEvent):void
  {
    txtDataUrl.text = oEvent.data.toString();
  }//init 
 
]]></mx:Script>
  <mx:Text text="This app shows the usage of the Hyperlink component and HyperlinkEvent custom event." width="300" fontSize="12" />
  <mx:Text text="This repeater  sets launchUrl=true, so clicking on a Hyperlink launches the specified url in a separate browser." width="200" />
  <mx:Repeater id="rpUrl" dataProvider="{xmlData.item}">
    <Hyperlink launchUrl="true" colorNormal="#0000FF" colorHover="#00FF00"
        linkText="{rpUrl.currentItem.@linkText}"
        dataUrl="{rpUrl.currentItem.@dataUrl}" />
  </mx:Repeater>

  <mx:Text text="This repeater sets launchUrl=false, so the Hyperlink component emits a bubbling custom event, which is handled by a listener in the main app.&#13;&#13;It also uses different text colors." width="200" />
  <mx:Repeater id="rpEvent" dataProvider="{xmlData.item}">
    <Hyperlink launchUrl="false" onClick="onLinkClick(event)"
        colorNormal="#0FF0FF" colorHover="#FAAAFF"
        linkText="{rpEvent.currentItem.@linkText}"
        dataUrl="{rpEvent.currentItem.@dataUrl}" />
  </mx:Repeater> 
  <mx:Label text="You clicked:"  />
  <mx:Text id="txtDataUrl" fontSize="16" color="white" />
   
  <!-- Sample data -->
  <mx:XML id="xmlData" xmlns="">
    <data>
      <item linkText="Google" dataUrl="http://www.google.com" />
      <item linkText="NPR" dataUrl="http://www.npr.org" />
      <item linkText="MSN" dataUrl="http://www.msn.com" />
      <item linkText="Yahoo" dataUrl="http://www.yahoo.com" />           
    </data>
  </mx:XML> 
</mx:Application>

/**
 * Hyperlink
 * This control displays a Text control that looks like an HTML hyperlink.
 * See public var / property declarations
 *
 *
 */
package
{
 import mx.controls.Text;
 import flash.events.Event;
  import flash.events.TextEvent;
  import HyperlinkEvent;
  import flash.net.*;
 
 [Event(name="onClick", type="HyperlinkEvent")]

 public class Hyperlink extends Text
 {
  public var colorNormal:String = "#0000FF";   //Link text color.
  public var colorHover:String = "#00FF00";    //Link hover text color.
  public var dataUrl:String = "";         //Any string if launchUrl="false" and using event, must be valid url if launchUrl="true";
  public var linkText:String = "";        //Displayed Hyperlink text
  public var launchUrl:Boolean = true;      //controls whether a click on a link launches the dataUrl, or emits a DLink event.
 
  /**
   * Run by creation complete.  This is here to initialize this control
   */   
  private function onCreationComplete(oEvent:Event):void
  {
   if (linkText && linkText.length > 0)  {              //only do this if we have link text
    setHtmlText();
   }
   else  {
     htmlText = "!!!!!!Property 'linkText' is REQUIRED!!!!!!";
   }
  }//onCreationComplete
  
  /**
   * Concatenates the htmlText value and assigns it to the property
   */
  private function setHtmlText():void
  {
   var sHTML:String = '<font color="' + colorNormal + '">';
   sHTML += '<a href="event:myEvent" ><u>';  
   sHTML += linkText;
   sHTML += '</u></a';
   sHTML += '</font>';
   this.htmlText = sHTML;
   this.toolTip = "Click to show " + linkText;
  }//setHtmlText
  
    
  /** called by the mouseOver and mouseOut events of the control.
   *  Toggles the color of the linkText
   */
  private function hover(oEvent:Event):void{
   if (oEvent.type == 'mouseOver')  {
    this.htmlText = String(this.htmlText).replace(colorNormal,colorHover);
   }
   else  {
    this.htmlText = String(this.htmlText).replace(colorHover,colorNormal);
   }
  
  }//hover  
  
  /**
   * Run by user click of the Hyperlink control.
   * Conditionally launches the dataUrl in a browser, or emits a HyperlinkEvent containing the xmlData
   */   
  private function onLinkClick(oEvent:TextEvent):void
  {
   if (launchUrl)  {
    var ur:URLRequest = new URLRequest(dataUrl);
    navigateToURL(ur,"_blank");
   }
   else  {
    dispatchEvent(new HyperlinkEvent("onClick",dataUrl,true,true));
   }
   
  }//onLinkClick   
  
  /**
   * Constructor
   */    
  public function Hyperlink(xmlData:XML=null)
  {
   this.addEventListener("mouseOver",hover);
   this.addEventListener("mouseOut",hover);
   this.addEventListener("creationComplete",onCreationComplete);
   this.addEventListener("link", onLinkClick);
   super();
  }//Constructor
  
 }//class Hyperlink
}//package

/**
 * This simple custom event works with the Hyperlink component. 
 * Actually, it could be easily adapted for other uses as well.
 */
package
{
 import flash.events.Event;

 public class HyperlinkEvent extends Event
 {
  public var data:Object;
  
  /** Constructor */
  public function HyperlinkEvent(type:String, data:Object, bubbles:Boolean=false, cancelable:Boolean=false)
  {
   super(type, bubbles, cancelable);
   this.data = data;
  }//Constructor

    /** Override the inherited clone() method. */
    override public function clone():Event {
      return new HyperlinkEvent(type, data, this.bubbles, this.cancelable);
    }//clone  
  
 }// class HyperlinkEvent
}//package

File Details
Created On Jan, 11, 2007 by Tracy Spratt
Last Modified On Jan, 11, 2007 by Tracy Spratt
Group: Tips and Articles
Flex Versions: 2.0
Category: Components
Type: Complete Lesson
Difficulty: Intermediate
Keywords: