Thursday, October 23, 2008

Icon on Grouped Column of Advanced Data Grid


In Flex, On a GroupingCollection as a DataProvider to my AdvancedDataGrid, i wanted to have an icon (itemRenderer) only on the leaf nodes of my AdvancedDataGrid (grouped data). This is how my initial code was: -> Script block of my ActionScript->
   import mx.collections.ArrayCollection;
   
   [Bindable]
   private var collection:ArrayCollection = new ArrayCollection([{group:'group1', id:'1', name:'name1'}, 
                    {group:'group1', id:'2', name:'name2'}, 
                    {group:'group2', id:'3', name:'name3'}]);
   private function setDP():void
   {
    gc.refresh();
    adg.expandAll();
   }



 
  
 

 
  
   
    
     
      
     
    
   
  
  
   
   

      
       
        
         
          
         
        
       
       
  
 





And my surprising output was -
I then removed inline item renderer and used external renderer (thanks to Srinivas Annam).


 
  private var obj:Object;
  
  override public function set data(value:Object):void
  {
   super.data=value;
   obj=value;
   apply(value);
  }
  
  private function apply(data:Object):void
  {
   if(data == null)
    return;
   
   img.source="";
   if(data.name)
   {
    img.source="assets/test.png";
   }
  }
  
 

And I added the itemrederer for the column as :


And I got the output i wanted:

labelFunction on GroupingCollection of Advanced Data Grid

Probably this is little simpler, or there may be more simpler solution. I was trying to hit upon an requirement which looks like this -

  • A Class Book which contains information about bookId, bookName
  • A Class BookShelf which contains information about bookshelfId and book (object of Book)
  • There is an array of BookShelf objects that form dataprovider for Advanced data grid where i want to show books grouped by BookShelfId and show the Book Information in the Advanced Data Grid.

 

package
{
 public class Book
 {
  private var _id:int = 0;
  private var _name:String = '';
  
  public function Book()
  {   
  }

  public function set id(val:int):void
  {
   this._id = val;
  }

  public function get id():int
  {
   return this._id;
  }

  public function set name(val:String):void
  {
   this._name = val;
  }

  public function get name():String
  {
   return this._name;
  }

 }
}
package
{
 public class BookShelf
 {
  private var _id:int = 0;
  private var _book:Book = new Book();
  
  public function BookShelf()
  {
  }

  public function get id():int
  {
   return _id;
  }

  public function set id(val:int):void 
  {
   _id = val;
  }

  public function get book():Book
  {
   return _book;
  }

  public function set book(val:Book):void 
  {
   _book = val;
  }
 }
}
   import mx.collections.ArrayCollection;
   
   [Bindable]
   private var dataCollection:ArrayCollection = new ArrayCollection();
   
   private function setDP():void
   {
    var book1:Book = new Book();
    book1.id = 1;
    book1.name = 'Book Name 1';
        
    var book2:Book = new Book();
    book2.id = 2;
    book2.name = 'Book Name 2';

    var book3:Book = new Book();
    book3.id = 3;
    book3.name = 'Book Name 3';

    
    var bookshelf1:BookShelf = new BookShelf();
    bookshelf1.id = 100;
    bookshelf1.book = book1;
    
    var bookshelf2:BookShelf = new BookShelf();
    bookshelf2.id = 100;
    bookshelf2.book = book2;

    var bookshelf3:BookShelf = new BookShelf();
    bookshelf3.id = 101;
    bookshelf3.book = book3;
    
    dataCollection.addItem(bookshelf1);
    dataCollection.addItem(bookshelf2);
    dataCollection.addItem(bookshelf3);
    
   }



 
  
 


 
  
   
    
     
      
     
    
   
  
  
   
   
  
 



Change the BookShelf.as to contain the following getter function that retrieves the property of internal object..

  private var _bookName:String = '';

  public function get bookName():String
  {
   return this._book.name;
  }

Change your MXML to use the new property that lies outside now! (Not an efficient solution but that works for time being)