Switch On The Code RSS Button - Click to Subscribe
Sep
11

Flex DataGrid Selected Row Styling

flex icon

So in my previous tutorial I had an example on how to change a selected row's styling. At the end of that article I said there is a better way to do this, well today I am going to show that better method. This tutorial is going to to show a good method for changing just about anything on a selected row in any list based component.

In the demo application below you can see the functionality that we are building today. Really, we could have done just about anything with the selected row that we wanted. The basic idea is that we are going to build a custom item renderer to handle updating styles when the row is selected. For more info on item renderers you can read my post on Using Item Renderers. You can also grab the source for this example if you would like.



To get things started here we are going to build the basic interface structure for this example. All we have is a simple DataGrid with a few columns and that is it.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
  xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="absolute" width="300" height="125">

  <mx:DataGrid width="100%" height="100%">
    <mx:columns>
      <mx:DataGridColumn
        headerText="First Name" dataField="firstName"/>

      <mx:DataGridColumn
        headerText="Last Name" dataField="lastName"/>

      <mx:DataGridColumn
        headerText="Age" dataField="age"/>

      <mx:DataGridColumn
        headerText="Sex" dataField="sex"/>

    </mx:columns>
  </mx:DataGrid>
</mx:Application>

Next up, getting some dummy data into our grid. To do this I hook into the creationComplete event of the application and call my own function named init. I add a Script tag to put my function in and then inside I add a variable for the data and the function. All this can be seen below.

First my update root application tag.

<mx:Application
  xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="absolute" width="300" height="125"
  creationComplete="init()">

Then the Script tag.

<mx:Script>
<![CDATA[
  import mx.collections.ArrayCollection;
 
  [Bindable]
  private var peeps:ArrayCollection;

  private function init():void
  {
    peeps = new ArrayCollection();
    peeps.addItem({
      firstName: "Handsome", lastName: "Dude",
      age: 24, sex: "male"
    });
    peeps.addItem({
      firstName: "Red", lastName: "Bloke",
      age: 25, sex: "male"
    });
    peeps.addItem({
      firstName: "Tall", lastName: "Guy",
      age: 25, sex: "male"
    });
    peeps.addItem({
      firstName: "Cute", lastName: "Girl",
      age: 24, sex: "female"
    });
    peeps.addItem({
      firstName: "Hot", lastName: "Chick",
      age: 24, sex: "female"
    });
    peeps.addItem({
      firstName: "Lazy", lastName: "Man",
      age: 25, sex: "male"
    });
  }
]]>
</mx:Script>

To get the data to show up in the grid all we need now is to update the DataGrid tag and set the dataProvider property. This will be set to the variable we just created.

<mx:DataGrid dataProvider="{peeps}" width="100%" height="100%">

On to the interesting part, to actually get our selected rows to do something we need to build a custom item renderer. In this case I simply created a custom component based on a Label. Now to get this working again we override the set data function. In the set data function I set the text of the label equal to the value of the dataField property on the value passed in as the data for the renderer. I get the dataField property name from the listData property on our renderer. The start of this custom renderer follows.

<?xml version="1.0" encoding="utf-8"?>
<mx:Label
  xmlns:mx="http://www.adobe.com/2006/mxml"
  width="100%" height="100%">

  <mx:Script>
    <![CDATA[
      import mx.controls.dataGridClasses.DataGridListData;
     
      override public function set data(value:Object):void
      {
        super.data = value;
       
        if(value)
        {
          var dglistData:DataGridListData =
            listData as DataGridListData;
          if(value[dglistData.dataField])
            this.text = value[dglistData.dataField];
        }
      }
    ]]>
  </mx:Script>

</mx:Label>

Really, all that we have done is create the basic item renderer here. In order to tell if this renderer is in the selected row we are going to check if the data for this renderer is equal to the selected row of the DataGrid that is the owner of this renderer. In order to do this we are going to hook into the creationComplete event of our custom renderer which will call the function init. Go ahead and check out the complete code for the renderer here and I will explain the rest after.

<?xml version="1.0" encoding="utf-8"?>
<mx:Label
  xmlns:mx="http://www.adobe.com/2006/mxml"
  width="100%" height="100%" creationComplete="init()">

  <mx:Script>
    <![CDATA[
      import mx.events.ListEvent;
      import mx.controls.DataGrid;
      import mx.controls.dataGridClasses.DataGridListData;
     
      private var dg:DataGrid;
     
      private function init():void
      {
        dg = listData.owner as DataGrid;
        dg.addEventListener(ListEvent.CHANGE, updateSelected);
      }
     
      override public function set data(value:Object):void
      {
        super.data = value;
       
        if(value)
        {
          var dglistData:DataGridListData =
            listData as DataGridListData;
          if(value[dglistData.dataField])
            this.text = value[dglistData.dataField];
          updateSelected();
        }
      }
     
      private function updateSelected(e:Event = null):void
      {
        if(!data || !dg)
          return;
       
        if(dg.selectedItem == data)
        {
          //This row is selected update stuff
          setStyle("fontWeight", "bold");
        }
        else
        {
          //This row is not selected reset stuff
          setStyle("fontWeight", "normal");
        }
      }
    ]]>
  </mx:Script>

</mx:Label>

First you can see I added a variable for the owner (DataGrid), dg of the renderer. In the init function we set our grid variable equal to the owner of this renderer using the previously mentioned listData. Then we add an event listener for the change event on our owning DataGrid which will call a new function called updateSelected. The updateSelected function checks to see if this is part of the selected row and then updates the style for this renderer or could do just about anything. The last thing we need to do is call this when the data is set so we can make sure the styles are correct when scrolling and such. The main thing to remember is renderers are reused so this is why we need to check when the data is set because it can change.

Well, that takes care of this tutorial. I hope that this helps explain some of the things you can do using Item Renderers and the data they have access to. Specifically this tutorial answers a few comments in a previous tutorial. If anyone has any questions on this or anything else feel free to leave a comment.



Posted in Flex, All Tutorials by The Fattest |

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Powered by WP Hashcash