« Avalon: Microsoft's Answer to Flash? MovableType problems »

November 01, 2003

FMX2k4: Rendering html in a ListBox

I'm currently in the middle of a project that uses the new ListBox component in Flash MX 2004. So far things were going good, until I wanted to display part of the list entries in bold. I thought it might be as simple as changing the label field when adding items to include the html tags, but of course life usually isn't that easy. However, after a little reading and digging around I eventually came up with a solution that I'm sharing with you today.

Below is the end result, and you can re-create this in just a few easy steps.



This effect was achieved by creating a custom cellRenderer instead of using the default rendering of the ListBox. A Cell Renderer is any class that implements the Cell Renderer API and is used to display the contents of a row in List-based components (List, DataGrid, Tree, and Menu). You can find more information about Cell Renderers in the Help Panel - look in Using Components -> Components Dictionary -> CellRenderer API.

To re-create the example above, follow these simple steps.

  1. Download my LabelCellRenderer and extract it to somewhere in your classpath (the directory of the .fla file is good).
  2. Insert a new MovieClip symbol, and call it "LabelCellRenderer" without the quotes. Leave it as an empty symbol.
  3. Right click on LabelCellRenderer in the library and select "Linkage..." from the menu. Click "Export for ActionScript" and use "com.darronschall.LabelCellRenderer" as the AS 2.0 Class. Also make sure that "LabelCellRenderer" is the indentifier name.
  4. Add the Label component to your library. This is necessary as the LabelCellRenderer uses it for display.
  5. Drag a ListBox onto the stage and give it an instance name. I'll use "myList" as an example. Adjust it's size to be 250 x 90 for this example.
  6. Copy and paste this code to use the LabelCellRenderer and see it in action:
    // generic event handler
    function change(eventObj) {
     	trace(eventObj.target.selectedItem.data);	
    }
    
    // populate the list box - note the html in the "label" string
    myList.addItem({label:"<b>Apples</b> ... <font color=\"#FF0000\">are <u>red</u></font>", data:"apple"});
    myList.addItem({label:"<b>Oranges</b> ... <font color=\"#FF9900\">are <u>orange</u></font>", data:"orange"});
    myList.addItem({label:"<b>Bananas</b> ... <font color=\"#FFCC00\">are <u>yellow</u></font>", data:"banana"});
    myList.addItem({label:"<b>Pears</b> ... <font color=\"#009900\">are <u>green</u></font>", data:"pear"});
    
    // turn off the vertical scrollbar to get
    // rid of the "empty box" that appears when
    // there isn't enough content to scroll
    myList.vScrollPolicy = "off";
    
    // use the LabelCellRenderer to display the label
    // in the listbox and allow for html
    myList.cellRenderer = "LabelCellRenderer";
    
    myList.addEventListener("change", this);
    
    // just use a default gray style, as the haloGreen
    // doesn't look quite right with our colors in the list
    _global.style.setStyle("themeColor", 0xCCCCCC);

... and that should do it! Good luck with this example. I hope that I've shown you how to use a CellRenderer effectively without having to hack apart a List component to get it to display what you need.

Comments

  • Hey Darren. Wondering if you could help? I'm currently working on a project using the listbox component. I'm trying to add a rollover description to the listbox. So far, it's not working. You can view what i've done so far at:

    http://dev.illinoislawhelp.org/devmikespace/listbox_rollover.html

    Thanks in advance for any help,
    Mike

  • Mike --

    Use this line of code to see the label of the item rolled over:

    this.highlight_mc.onRollOver = function() {
    trace("rollover -- " + this.controller.getItemModel().label);
    }

    I hope that helps!

  • Hi Darren,

    is it possible to use this cellrenderer with a datagrid?

    I'm trying to wrap text in a datagrid but so far haven't manged to - switching the text to htmltext seems like the best way to achieve this.

    Thanks,

    Stuart

  • I'm trying to render a cell to say "View Details" on each row. When that cell/text is clicked, an external page is loaded into the browser. Any ideas?

  • Brandon - I'm not sure why that would be happening. What do you have defined as the event handler, and can you paste the code used? I'll need some more details to be able to help out...

  • Can you give me an example of a cellrenderer that mimics the code that the is displayed by the dg_1 example that shows a a datagrid. when the user clicks on the combobox column, a combobox appears and has the data loaded into it. after the combobox loses focus, it reloads the data back into the datagrid

  • Any pointers on applying this to a datagrid instead of a list?

    Thanks in advance

  • LabelCellRenderer can be used unmodified for rendering cells in DataGrid.

    Macromedia's DataGrid v2 derives all the functionality from List component.

    To apply custom CellRenderer class to the particular column (first, for example)
    in DataGrid use command:

    myDataGrid.getColumnAt(0).cellRenderer = "LabelCellRenderer"

  • Good Demo Darron, at least I thought so, I tried your example and followed your steps, all I get is a blank listbox. It appears there are four lines of data there, ( the halo effect highlights 4 lines, 4 blank lines ) but I not seeing any data as in your demonstration. Did you leave something out?

  • Darren,
    Is it possible to display swf's as
    ({label:"", data:some_mc})
    to create a scrolling list of swf's? I am new to actionscript and i would like to create a scrolling list of movieclips that display a title and short description. A basic index of article titles and description that link to long description pages. I realize that there may be a better way to build this as well, but as i said i am a newbe.. please advise...
    Thanks so much!!
    - Timothy.

  • @Ray - Make sure you have the LabelCellRenderer in your library, with the correct linkage as "LabelCellRenderer" and the correct class as "com.darronschall.LabelCellRenderer" -- also, make sure that it has "export in first frame" checked so that the asset is available before it is attempted to be used. If that doesn't work, make sure com.darronschall.LabelCellRenderer is in your classpath (just extracting it to the directory where your .fla is saved will work).

    If that doesn't work, double check your instance name, and that you have a Label component in the library. I followed the steps that I outlined just to make sure it works.. and it does. So it's probably something simple - maybe even a typo in the Linkage properties?

  • @Timothy - You'd have to create a CellRenderer for that. It would need to attach the movie clip with the linkage id.. and shouldn't be too hard to create. I'll try to work that in an example sometime soon on my site.. but for now you might want to consider using a ScrollPane and setting the contentPath to a movieClip that you manually create, or check out the following links:

    http://www.markme.com/nigel/archives/004196.cfm
    http://www.flash-db.com/Tutorials/cellrenderer/
    http://chattyfig.figleaf.com/ezmlm/ezmlm-cgi?1:mss:97890:hopdiamihfinkpalnnfm

    Good luck!

  • Hy.. please... I need your Help...

    I use Flash Mx 2004 , datagrid componet, and i bindings the data with a Webserver ... this Ok... my problem is when i want to replace a value in colunns to Image (.jpg).. i dont know how do
    ========================

    import mx.services.*

    stockservice = new WebService("XXXXXXX.asmx?wsdl");
    stockResultObj = stockservice.TrxVolCadastro(2003);
    stockResultObj.onFault = function(e){ // erro handler
    for (a in e) trace(e + " " + e[a])
    }
    stockResultObj.onResult = function(resul){
    var tes:XML = new XML(resul["diffgram"]);
    var nodeLengths:Number = tes.firstChild.firstChild.childNodes.length;
    var tempxml = tes.firstChild.firstChild.childNodes;
    var arrayDP:Array = new Array();
    for(var a =0;a<nodeLengths;a++) {
    var ano:String = tempxml[a].childNodes[1].firstChild.nodeValue;
    var mes:String = tempxml[a].childNodes[2].firstChild.nodeValue;
    var total:String = tempxml[a].childNodes[3].firstChild.nodeValue;
    var tendencia:String = tempxml[a].childNodes[0].firstChild.nodeValue;
    if (tendencia==1)
    {
    /////// MY PROBLEM......
    //////// ??????????????????????
    tendencia = "loyalty.jpg";
    }
    arrayDP.addItem({ano:ano,mes:mes,total:total,tendencia:tendencia});
    }

    _root.teste.dataProvider = arrayDP
    }


    Tk´s.....

  • Thank you very much for your example

    I was looking for such an example to use with combobox and it is just two lines to add :

    myCombo.textField.html = true; //so that the combobox's label displays html

    myCombo.dropdown.cellRenderer = "LabelCellRenderer"; //to replace myList.cellRenderer = "LabelCellRenderer";

  • hi i wat complete code of datagrid nad tree scrollbar simulation

  • hi i want to know how to simulate scrollbar in between DataGrid and Tree.i.e. if tree scrllbar move than datagrid bar also move.

  • Well, I have followed all the instructions as listed and am getting the same response as Ray Wong with everything showing up except the text.

    Additionally, when i run it, I get 8 errors complaining about class names conflicting with other class names.

    I really wish you would have taken a bit more time to give very well detailed instructions because this seems like it would be very useful. Just not very useful when you waste 6 hours trying to figure it out.

  • Thx for this great piece of code:-),
    I got it working on the first Collumn of a data grid called "label". But say my 2e collumn is called "time1". What do i have to change in the LabelCellRenderer.as script to make the Column "time1" working too?

  • Nice solution

  • Hi,

    I have written a cellrenderer for Tree component... But somehow after defining a cell renderer, my 'textSelectedColor' property fails to have any impact....... ne Clues?... Help wud b deeply appreciated... :)

    Pulkit

  • can anyone upload to the web one simple fla with a the working demo of above? the code doesn´t work , i get in the list box [object Unobject] or similar, i don´t remember...

    Please upload the fla with labelcellrender class in. just to comppile and see the demo

    sorry for my english

  • I would like to display the icon(some picture) with the listed items in the list component. Can anyone pls help me regarding this ? Is there any relationship between this requirement and cellRenderer API ?

  • Just wanted to say thanks a lot for you cell renderer tutorial, it helped break the ice as well as provide some examples around the gotchas!

  • An awesome example. Really helped me break into using a cell renderer.

    Just one issue I'm trying to tackle... how to get the row to remain highlighted when using HTML text that is wrapped in an anchor tag.

  • Nothing better than posting to a couple-year-old post, right?

    Well, I'm just echoing Pulkit's frustration. How do we get the label to use the textRollOverColor style?

  • If you're having problems with Flash loading the class (i.e. "The Class LabelCellRenderer could not be loaded") change the Class declaration in the .as file to read:

    class LabelCellRenderer extends UIComponent

    instead of:

    class com.darronschall.LabelCellRenderer extends UIComponent

    This is the only way I could get it to load. I thought the class filenames had to match the class declaration, so I'm not sure why Darren declared it the way he did. Is it possible to use a dot notation like that for classes? I'm new to dealing with linking classes so I'm not sure. Has anyone had success with the class being loaded with the original declaration? I know this is an old thread, but it's helping me out.

    Thanks Darren for the example.

  • Great work. Thanks also to Anne for the one line adaptation for comboboxes.

  • Excellent example. I too had same problem as Ray getting blanks until you mentioned to check for UI Label component. Once I dragged Label to the .fla file. The demo works perfectly. I was able to adjust the demo at the basic level to my own project with only one line: listResult.cellRenderer = "LabelCellRenderer"; Thanks!