My ‘Flex’ible Experiments

HTML Tables in Flex

with 4 comments

Most of the flex develpors a face a common problem to render html tags . Flex do not have the abillity to render complex html tags like <table> tags , but  Adobe Air is having a HTML control for rendering the html. I think the full html rendering ability is not included in flash player inorder to keep it light weight .

I faced a similar problem to render html tables in flex. I have a tried  a third party html component inorder to render html . That component is working well , but the hmtl is a appearing as a layer on top of the swf giving scrolling issues always.

Then i tried to create component based on the Grid Component in flex which is similar to the HTML Table .  The component will accept an html string containing table tags and will use regular expressions to parse the string to create Grid rows and columns. 

The component is working correctly for simple tables , now need to include the ability to render style attributes .

Here is the Code of the component .

Subeesh


<?xml version="1.0" encoding="utf-8"?>
<mx:Grid  xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"   creationComplete="gridCreated()">
 <mx:Script>
  <![CDATA[
   import mx.controls.Alert;

   import mx.controls.Text;
   import mx.containers.GridItem;
   import mx.containers.GridRow;

   private var tableExpression:RegExp = new RegExp("
<table[^>]*>(.*?)</table>
","s");
   private var headerExpression:RegExp = new RegExp("
<th[^>]*>(.*?)</th>
");
   private var rowExpression:RegExp = new RegExp("
<tr[^>]*>(.*?)</tr>
","gs");
   private var columnExpression:RegExp = new RegExp("
<td[^>]*>(.*?)</td>
","gs");

   private var initializedf:Boolean = false;

   //Property whic

   private var _htmlString:String;
   public function get htmlString() : String {
    return _htmlString;
   }

   public function set htmlString(value:String) : void {
    _htmlString = value;

   } 

   private function gridCreated() : void {
    createTable();
   }

   /* override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
    super.updateDisplayList(unscaledWidth,unscaledHeight);

   } */

   private function createTable() : void {
    _htmlString = getTableProperties(_htmlString);
    var tableResult:Array = _htmlString.match(tableExpression) as Array;
    var rowResult:Array = ( tableResult[1] as String).match(rowExpression) as Array;
    //this.setStyle("borderStyle","solid");
    //this.setStyle("borderColor","#666666");
    this.setStyle("verticalGap",0);
    this.setStyle("horizontalGap",0);

    var columnWidth:int = getColumnWidth(rowResult,width );
    for( var i: int = 0 ; i < rowResult.length ; i ++ ) {

     var gridrow:GridRow = new GridRow();
     //gridrow.percentWidth = 100;
     this.addChild(gridrow);
     var columnResult:Array = ( rowResult[i] as String).match(columnExpression);

     for( var j:int = 0; j < columnResult.length ; j++ ) {
      var griditem:GridItem = new GridItem();
      griditem.setStyle("borderStyle","solid");
      griditem.setStyle("borderColor","#666666");
      gridrow.addChild(griditem);
      var text:Text = new Text();
      text.width = columnWidth;
      text.truncateToFit = true;
      text.htmlText = removetd(columnResult[j] as String);
      griditem.addChild(text);
     }
    }

   }

   private  static  function removetd(str:String): String {
    str = str.replace("
<td>","");
    str = str.replace("</td>
","");
    return str;
   }

   private function removetbody(str:String) : String {
    str = str.replace("
<tbody>","");
    str = str.replace("</tbody>
","");
    return str;
   }

   private function getTableProperties(str:String) : String {

    //clean the table from div tags and tbody tags
    var startIndex:int =  str.indexOf("
<table");
    str = str.substr(startIndex);
    var endIndex:int =  str.indexOf("</table>
");
    str = str.substring(0,endIndex + 8);
    str = removetbody(str);
    str = str.replace("\\r","");
    str = str.replace("\\n","");

    //store the table property information for appyling styles
    var tableTag:String = str.substring(0,str.indexOf(">") + 1);

    var contents:String = str.substr(str.indexOf(">") + 1);

    return "
<table>" + contents;

   }

   private function getColumnWidth(rowResult:Array,_width:int) : int {
     var maxColumns:int = 0;
     for( var i: int = 0 ; i< rowResult.length ; i ++ ) {
     var columnResult:Array = ( rowResult[i] as String).match(columnExpression);
     if(maxColumns < columnResult.length)
      maxColumns = columnResult.length;
     }
     return Math.floor((_width - 100)/maxColumns);
   }

  ]]>
 </mx:Script>
</mx:Grid>

Written by subeesh

February 16, 2008 at 9:02 am

4 Responses

Subscribe to comments with RSS.

  1. I am interested in how to create html table to display in grid, but not sure what you are talking about. You are parsing out the html table tags and then displaying?
    Not sure what this means…
    Craig

    Craig

    May 22, 2008 at 2:45 am

  2. I think the html table structure you are trying to show it in flex will be similar to this structure

    row 1 column 1
    row 1 column 2

    row 2 column 1
    row 2 column 2

    I have used regular expression for filtering the required html table sections.

    First i have used a regular expression to filter the tag. When that regex is applied to the string, the string will contain only the table information like the above one. This is the table expression to match the table tag from the rest of the html tags.

    Once we parse out the table structure, now we can look for the Rows( tags ). Again we use a regular expression on the string obtained ( this time an expression to filter rows). Now we will get an array of tags. In this case an array of length 2. The length of the array is the number of rows in the table.

    Now we have to loop through this array and again apply a regular expression to parse the tags . If we do that we will get an array conating the tds in that row. This contains the table data.

    You can store these arrays in a nested structure and use that structure to populate the flex grid component.

    I will try to post a code snippet next time so that you will get a better idea of what i am talking about

    subeesh

    May 22, 2008 at 4:53 am

  3. Subeesh, the problems you describe have been my life for the past month. After paying the $150 for HTMLComponent I decided to dump it because I could not overcome the focus issues with flex textboxes and HTMLComponent+FCKEditor in the same window

    I am currently scouring the internet for a solution like you mention to parse a html table to a flex grid. I would love to see yours. email: chris@clickonchris.com

    And I have to wonder if this is the same Craig who posted to this mailing list: http://www.mail-archive.com/flexcoders@yahoogroups.com/msg92856.html

    Chris Johnson

    September 23, 2008 at 8:32 pm

  4. Hi Chris,

    Take a look at the code

    Subeesh

    subeesh

    September 24, 2008 at 8:58 am


Leave a Reply