The following example shows how you can set alternating column background colors on a Flex DataGrid control by setting the backgroundColor style for each DataGridColumn object.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/09/24/setting-background-colors-on-a-datagrid-column-in-flex/ -->
<mx:Application name=""
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:XML id="xmlDP" source="data/dp.xml" />

    <mx:DataGrid id="dataGrid"
            dataProvider="{xmlDP.children()}"
            verticalScrollPolicy="on">
        <mx:columns>
            <mx:DataGridColumn dataField="@c1"
                    backgroundColor="haloSilver" />
            <mx:DataGridColumn dataField="@c2"
                    backgroundColor="white" />
            <mx:DataGridColumn dataField="@c3"
                    backgroundColor="haloSilver" />
        </mx:columns>
    </mx:DataGrid>

</mx:Application>

View source is enabled in the following example.

Due to popular demand, here is the “same” example in a more ActionScript friendly format:

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/09/24/setting-background-colors-on-a-datagrid-column-in-flex/ -->
<mx:Application name=""
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        initialize="init();">

    <mx:Script>
        <![CDATA[
            import mx.core.ScrollPolicy;
            import mx.controls.dataGridClasses.DataGridColumn;
            import mx.controls.DataGrid;

            private var xmlDP:XML;
            private var xmlLoader:URLLoader;
            private var dataGrid:DataGrid;
            private var dgc1:DataGridColumn;
            private var dgc2:DataGridColumn;
            private var dgc3:DataGridColumn;

            private function init():void {
                dgc1 = new DataGridColumn("@c1");
                dgc1.setStyle("backgroundColor", "haloSilver");

                dgc2 = new DataGridColumn("@c2");
                dgc2.setStyle("backgroundColor", "white");

                dgc3 = new DataGridColumn("@c3");
                dgc3.setStyle("backgroundColor", "haloSilver");

                dataGrid = new DataGrid();
                dataGrid.verticalScrollPolicy = ScrollPolicy.ON;
                dataGrid.columns = [dgc1, dgc2, dgc3];
                addChild(dataGrid);

                xmlLoader = new URLLoader();
                xmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
                xmlLoader.addEventListener(Event.COMPLETE,
                            xmlLoader_complete);
                xmlLoader.load(new URLRequest("data/dp.xml"));
            }

            private function xmlLoader_complete(evt:Event):void {
                var xmlObj:XML = new XML(evt.currentTarget.data);
                dataGrid.dataProvider = xmlObj.children();
            }
        ]]>
    </mx:Script>

</mx:Application>
 
Tagged with:
 
About The Author

Peter deHaan

Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.

12 Responses to Setting background colors on a DataGrid column in Flex

  1. pierre says:

    Hello,

    I found your exemple very interesting.
    I have a demand.

    Can your show an example, with arraycollection (A,B), in which you add :
    - a column that calculated the total of each row of the columns before.
    - a footer that calculated the total of each columms.

    |---- A -----|---- B -----|---- C -----|
    |------------|------------|---(A+B)----|
    |------------|------------|---(A+B)----|
    ..
    |------------|------------|---(A+B)----|
    |- TOTAL A --|- TOTAL B --|- TOTAL C---|
    

    Best Regards

  2. peterd says:

    pierre,

    Fortunately, the first part of the problem is pretty easy. You simply need to create a DataGridColumn and specify a labelFunction which adds the values from Column A to Column B and return the sum. It gets marginally tricker since you may also have to specify a custom sortCompareFunction so the column sorts correctly if the user clicks on the header. Something like the following should get you started:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    
        <mx:Script>
            <![CDATA[
                import mx.controls.Label;
                import mx.controls.dataGridClasses.DataGridColumn;
                import mx.utils.ObjectUtil;
    
                private function sum_labelFunc(item:Object, col:DataGridColumn):Number {
                    return Number(item.c1) + Number(item.c2);
                }
    
                private function sum_sortCompareFunc(a:Object, b:Object):int {
                    var sumA:Number = Number(sumCol.itemToLabel(a));
                    var sumB:Number = Number(sumCol.itemToLabel(b));
    
                    return ObjectUtil.numericCompare(sumA, sumB);
                }
            ]]>
        </mx:Script>
    
        <mx:ArrayCollection id="arrColl">
            <mx:source>
                <mx:Array>
                    <mx:Object label="Row 1" c1="1" c2="15" />
                    <mx:Object label="Row 2" c1="5" c2="28" />
                    <mx:Object label="Row 3" c1="5" c2="44" />
                    <mx:Object label="Row 4" c1="9" c2="73" />
                    <mx:Object label="Row 5" c1="3" c2="81" />
                    <mx:Object label="Row 6" c1="1" c2="4" />
                    <mx:Object label="Row 7" c1="6" c2="63" />
                    <mx:Object label="Row 8" c1="5" c2="12" />
                </mx:Array>
            </mx:source>
        </mx:ArrayCollection>
    
        <mx:DataGrid id="dataGrid" dataProvider="{arrColl}">
            <mx:columns>
                <mx:DataGridColumn dataField="label" />
                <mx:DataGridColumn dataField="c1" />
                <mx:DataGridColumn dataField="c2" />
                <mx:DataGridColumn id="sumCol"
                        headerText="sum"
                        labelFunction="sum_labelFunc"
                        sortCompareFunction="sum_sortCompareFunc" />
            </mx:columns>
        </mx:DataGrid>
    
    </mx:Application>
    

    As for the second part of the question, creating a footer that calculates the sum. There are probably a couple ways to do that. Unfortunately this isn’t something I’ve ever tried/investigated, so I can’t be of much help. You could probably loop through the items in the data provider and calculate the sum manually and display it in a Label control beneath the DataGrid. You’d probably want to listen for DataGridColumn resize events and resize/reposition your labels accordingly (so they line up). but that probably isn’t the solution you were looking for.
    Thankfully, Alex Harui has an example of custom DataGrid footers in his blog, so you may be able to view his source code and get the rest of the way there: “Flex 3 DataGrid Footers” and “DataGrid Footers”.

    Peter

  3. Pierre says:

    Hello,

    thank you for your prompt response.

    Best regards.

  4. Pierre says:

    Hello Peter,

    I have two questions in the script below:
    - How round the result in each row of the sum column (2 decimales) , i tried toString but i have an error.
    - Is it possible, and how, to pass the total quantity and the total sum in an other datagrid in order to display the result.

    Thank for your help

    Regards

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="left" verticalAlign="top">
     <mx:Script>
      <![CDATA[
       import mx.controls.Label;
       import mx.controls.dataGridClasses.DataGridColumn;
       import mx.utils.ObjectUtil;
       import mx.events.CollectionEvent;
       import mx.collections.ArrayCollection;
       import mx.controls.Alert;
       import mx.events.DataGridEvent;
    
       private function resizeCols(event:Event=null) : void {
        if(dgS.rowCount > dgS.dataProvider.length)
          dgtot.width = dgS.width;
         else
          dgtot.width = dgS.width-16;
       }
    
       private function resizeCol(event : DataGridEvent) : void {
        DataGridColumn(dgtot.columns[event.columnIndex]).width = DataGridColumn(dgS.columns[event.columnIndex]).width;
       }
    
       private function sum_labelFunc(item:Object, col:DataGridColumn):Number {
        var sum:Number = Number(item.Price) * Number(item.Quantity);
        return sum;
       }
    
       private function sum_sortCompareFunc(a:Object, b:Object):int {
        var sumA:Number = Number(sumCol.itemToLabel(a));
        var sumB:Number = Number(sumCol.itemToLabel(b));
        return ObjectUtil.numericCompare(sumA, sumB);
       }
    
       [Bindable]
       public var dpADG:ArrayCollection = new ArrayCollection([
        {Artist:'Pavement',      Album:'Slanted and Enchanted',  Price:11.99, Quantity:10},
        {Artist:'Pavement',      Album:'Brighten the Corners',   Price:11.99, Quantity:-12},
        {Artist:'Saner',         Album:'A Child Once',           Price:11.99, Quantity:30},
        {Artist:'Saner',         Album:'Helium Wings',           Price:12.99, Quantity:45},
        {Artist:'The Doors',     Album:'The Doors',              Price:10.99, Quantity:60},
        {Artist:'The Doors',     Album:'Morrison Hotel',         Price:12.99, Quantity:45},
        {Artist:'Grateful Dead', Album:'American Beauty',        Price:11.99, Quantity:23},
        {Artist:'Grateful Dead', Album:'In the Dark',            Price:11.99, Quantity:36},
        {Artist:'Grateful Dead', Album:'Shakedown Street',       Price:11.99, Quantity:73},
        {Artist:'The Doors',     Album:'Strange Days',           Price:12.99, Quantity:11},
        {Artist:'The Doors',     Album:'The Best of the Doors',  Price:10.99, Quantity:19},
        {Artist:'The Doors2',    Album:'The Best of the Doors2', Price:10.99, Quantity:21}
       ]);
    
       private var dpADG2:ArrayCollection = new ArrayCollection([
        {Artist:'Pavement',      Album:'Slanted and Enchanted', Price:11.99, Quantity:12},
        {Artist:'Pavement',      Album:'Brighten the Corners',  Price:11.99, Quantity:76},
        {Artist:'Saner',         Album:'A Child Once',          Price:11.99, Quantity:98},
        {Artist:'Saner',         Album:'Helium Wings',          Price:12.99, Quantity:54},
        {Artist:'The Doors',     Album:'The Doors',             Price:10.99, Quantity:79},
        {Artist:'The Doors',     Album:'Morrison Hotel',        Price:12.99, Quantity:28},
        {Artist:'Grateful Dead', Album:'American Beauty',       Price:11.99, Quantity:39},
        {Artist:'Grateful Dead', Album:'In the Dark',           Price:11.99, Quantity:30},
        {Artist:'Grateful Dead', Album:'Shakedown Street',      Price:11.99, Quantity:38}
       ]);
    
       [Bindable]
       private var dpADGTotal:ArrayCollection = new ArrayCollection([
        {Artist:'', Album:'Total', Quantity:'XXX.XX'}
       ]);
    
      ]]>
     </mx:Script>
     <mx:Style>
      .title {
       text-align:center;
       font-weight:bold;
      }
      .body {
       text-align:right;
       padding-right:10;
      }
     </mx:Style>
    
     <mx:NumberFormatter id="numberFormatter"/>
    
     <mx:Button label="{'Switch to Dataprovider '+ (dgS.dataProvider == dpADG ? 'without' : 'with') +'  scroll'}" click="{dgS.dataProvider = (dgS.dataProvider == dpADG ? dpADG2 : dpADG)}"/>
    
     <mx:VBox width="100%" height="100%" verticalGap="0">
      <mx:DataGrid id="dgS"
                   dataProvider="{dpADG}"
                   height="40%" width="40%"
                   resize="{resizeCols()}"
                   columnStretch="{resizeCol(event)}"
                   creationComplete="{dgS.addEventListener(CollectionEvent.COLLECTION_CHANGE, resizeCols, false, 0, true)}"
                   editable="true"
                   textAlign="right">
       <mx:columns>
        <mx:DataGridColumn dataField="Artist"   id="dcArt" textAlign="left"  headerStyleName="title"/>
        <mx:DataGridColumn dataField="Album"               textAlign="left"  headerStyleName="title"/>
        <mx:DataGridColumn dataField="Quantity"            textAlign="right" headerStyleName="title" paddingRight="10"
                           editable="true" itemEditor="comps.MyNumericStepper" editorDataField="value"/>
        <mx:DataGridColumn dataField="Price"               textAlign="right" headerStyleName="title" paddingRight="10"/>
        <mx:DataGridColumn                      id="sumCol" textAlign="right" headerStyleName="title" paddingRight="10"
                           editable="false"
                           headerText="Sum"
                           labelFunction="sum_labelFunc"
                           sortCompareFunction="sum_sortCompareFunc" />
       </mx:columns>
      </mx:DataGrid>
      <mx:DataGrid id="dgtot"
                   width="40%"
                   dataProvider="{dpADGTotal}"
                   showHeaders="false"
                   rowCount="1"
                   height="{dgtot.rowHeight}"
                   creationComplete="{resizeCols()}"
                   fontWeight="bold">
       <mx:columns>
        <mx:DataGridColumn/>
        <mx:DataGridColumn dataField="Album"               textAlign="right" fontStyle="italic" paddingRight="10"/>
        <mx:DataGridColumn dataField="Quantity"            textAlign="right"                    paddingRight="10"/>
        <mx:DataGridColumn dataField="Price"/>
        <mx:DataGridColumn                    id="sumLign" textAlign="right"                 paddingRight="10"
                           labelFunction="sum_labelFunc"/>
       </mx:columns>
      </mx:DataGrid>
     </mx:VBox>
    
    </mx:Application>
    
  5. peterd says:

    Pierre,

    To round to two decimals you can use <Number>.toFixed(2), or you can use a CurrencyFormatter or NumberFormatter.

    As for your other question, this should get you somewhat close, but there are still a few bugs in the code. Most notably:
    (a) Rearranging columns in the top DataGrid control causes the column order in the top and bottom data grid to get out of sync.
    (b) Changing data providers on the top DataGrid doesn’t correctly update the values in the bottom DataGrid. You’ll need to add additional logic/code.

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            horizontalAlign="left"
            verticalAlign="top"
            initialize="init();">
    
     <mx:Script>
      <![CDATA[
       import mx.collections.ArrayCollection;
       import mx.controls.Alert;
       import mx.controls.Label;
       import mx.controls.dataGridClasses.DataGridColumn;
       import mx.events.CollectionEvent;
       import mx.events.DataGridEvent;
       import mx.utils.ObjectUtil;
    
       private function resizeCols(event:Event=null) : void {
        if(dgS.rowCount > dgS.dataProvider.length)
          dgtot.width = dgS.width;
         else
          dgtot.width = dgS.width-16;
       }
    
       private function resizeCol(event : DataGridEvent) : void {
        DataGridColumn(dgtot.columns[event.columnIndex]).width = DataGridColumn(dgS.columns[event.columnIndex]).width;
       }
    
       private function sum_labelFunc(item:Object, col:DataGridColumn):String {
        var sum:Number = Number(item.Price) * Number(item.Quantity);
        return currencyFormatter.format(sum);
       }
    
       private function currency_labelFunc(item:Object, col:DataGridColumn):String {
        return currencyFormatter.format(item[col.dataField]);
       }
    
       private function sum_sortCompareFunc(a:Object, b:Object):int {
        var sumA:Number = Number(sumCol.itemToLabel(a));
        var sumB:Number = Number(sumCol.itemToLabel(b));
        return ObjectUtil.numericCompare(sumA, sumB);
       }
    
       [Bindable]
       public var dpADG:ArrayCollection = new ArrayCollection([
        {Artist:'Pavement',      Album:'Slanted and Enchanted',  Price:11.99, Quantity:10},
        {Artist:'Pavement',      Album:'Brighten the Corners',   Price:11.99, Quantity:-12},
        {Artist:'Saner',         Album:'A Child Once',           Price:11.99, Quantity:30},
        {Artist:'Saner',         Album:'Helium Wings',           Price:12.99, Quantity:45},
        {Artist:'The Doors',     Album:'The Doors',              Price:10.99, Quantity:60},
        {Artist:'The Doors',     Album:'Morrison Hotel',         Price:12.99, Quantity:45},
        {Artist:'Grateful Dead', Album:'American Beauty',        Price:11.99, Quantity:23},
        {Artist:'Grateful Dead', Album:'In the Dark',            Price:11.99, Quantity:36},
        {Artist:'Grateful Dead', Album:'Shakedown Street',       Price:11.99, Quantity:73},
        {Artist:'The Doors',     Album:'Strange Days',           Price:12.99, Quantity:11},
        {Artist:'The Doors',     Album:'The Best of the Doors',  Price:10.99, Quantity:19},
        {Artist:'The Doors2',    Album:'The Best of the Doors2', Price:10.99, Quantity:21}
       ]);
    
       private var dpADG2:ArrayCollection = new ArrayCollection([
        {Artist:'Pavement',      Album:'Slanted and Enchanted', Price:11.99, Quantity:12},
        {Artist:'Pavement',      Album:'Brighten the Corners',  Price:11.99, Quantity:76},
        {Artist:'Saner',         Album:'A Child Once',          Price:11.99, Quantity:98},
        {Artist:'Saner',         Album:'Helium Wings',          Price:12.99, Quantity:54},
        {Artist:'The Doors',     Album:'The Doors',             Price:10.99, Quantity:79},
        {Artist:'The Doors',     Album:'Morrison Hotel',        Price:12.99, Quantity:28},
        {Artist:'Grateful Dead', Album:'American Beauty',       Price:11.99, Quantity:39},
        {Artist:'Grateful Dead', Album:'In the Dark',           Price:11.99, Quantity:30},
        {Artist:'Grateful Dead', Album:'Shakedown Street',      Price:11.99, Quantity:38}
       ]);
    
        private function init():void {
            dpADG.addEventListener(CollectionEvent.COLLECTION_CHANGE, dpADG_collectionChange);
            dpADG.refresh();
        }
    
        private var quantityTotal:Number;
        private var sumTotal:Number;
    
        private function dpADG_collectionChange(evt:CollectionEvent):void {
            quantityTotal = 0;
            sumTotal = 0;
            dpADG.source.forEach(quantitySum);
            var it:Object = dpADGTotal.getItemAt(0);
            it.Quantity = quantityTotal;
            it.Sum = sumTotal;
            dpADGTotal.setItemAt(it, 0);
        }
    
        private function quantitySum(item:*, index:int, array:Array):void {
            quantityTotal += item.Quantity;
            var sum:Number = Number(item.Price) * Number(item.Quantity);
            sumTotal += sum;
        }
    
       [Bindable]
       private var dpADGTotal:ArrayCollection = new ArrayCollection([
        {Artist:'', Album:'Total', Quantity:'', Sum:''}
       ]);
    
      ]]>
     </mx:Script>
     <mx:Style>
      .title {
       text-align: center;
       font-weight: bold;
      }
      .body {
       text-align: right;
       padding-right: 10;
      }
     </mx:Style>
    
     <mx:NumberFormatter id="numberFormatter"/>
     <mx:CurrencyFormatter id="currencyFormatter" precision="2" />
    
     <mx:Button label="{'Switch to Dataprovider '+ (dgS.dataProvider == dpADG ? 'without' : 'with') +'  scroll'}"
             click="dgS.dataProvider = (dgS.dataProvider == dpADG ? dpADG2 : dpADG);"/>
    
     <mx:VBox width="100%" height="100%" verticalGap="0">
      <mx:DataGrid id="dgS"
                   dataProvider="{dpADG}"
                   height="40%" width="100%"
                   resize="resizeCols();"
                   columnStretch="resizeCol(event);"
                   creationComplete="dgS.addEventListener(CollectionEvent.COLLECTION_CHANGE, resizeCols, false, 0, true);"
                   editable="true"
                   textAlign="right">
       <mx:columns>
        <mx:DataGridColumn id="dcArt"
                dataField="Artist"
                textAlign="left"
                headerStyleName="title" />
        <mx:DataGridColumn dataField="Album"
                textAlign="left"
                headerStyleName="title" />
        <mx:DataGridColumn dataField="Quantity"
                textAlign="right"
                headerStyleName="title"
                paddingRight="10"
                editable="true"
                itemEditor="mx.controls.NumericStepper"
                editorDataField="value" />
        <mx:DataGridColumn dataField="Price"
                textAlign="right"
                headerStyleName="title"
                paddingRight="10"
                labelFunction="currency_labelFunc" />
        <mx:DataGridColumn id="sumCol"
                textAlign="right"
                headerStyleName="title"
                paddingRight="10"
                editable="false"
                headerText="Sum"
                labelFunction="sum_labelFunc"
                sortCompareFunction="sum_sortCompareFunc" />
       </mx:columns>
      </mx:DataGrid>
      <mx:DataGrid id="dgtot"
                   width="40%"
                   dataProvider="{dpADGTotal}"
                   showHeaders="false"
                   rowCount="1"
                   height="{dgtot.rowHeight}"
                   creationComplete="{resizeCols()}"
                   fontWeight="bold">
       <mx:columns>
        <mx:DataGridColumn/>
        <mx:DataGridColumn dataField="Album"
                textAlign="right"
                fontStyle="italic"
                paddingRight="10" />
        <mx:DataGridColumn dataField="Quantity"
                textAlign="right"
                paddingRight="10" />
        <mx:DataGridColumn dataField="Price" />
        <mx:DataGridColumn dataField="Sum"
                textAlign="right"
                paddingRight="10"
                labelFunction="currency_labelFunc" />
       </mx:columns>
      </mx:DataGrid>
     </mx:VBox>
    
    </mx:Application>
    

    Peter

  6. PKASH says:

    how can u retrive the arraycollection field name in actionscript. like
    arraycollection(col1:’a',col2:’b');
    in this i want to col1.

    If possible plase let me, how convert the colums as a rows?
    arraycollection(a:’col1′,b:’col2′)

  7. madhu says:

    my requirement is
    mydatagrid contains two columns
    column1 columnn2
    true 12
    false 15
    true 16

    if the value in column1 is true then the backgroundcolor of column2 must be red or else if the value in column1 is false then the backgroundcolor of column 2 must be
    blue

  8. yogesh gaur says:

    Can you please provide an example on how to dynamically color any row of datagrib based on some event on datagrid row ????
    thanks in advance :)

  9. I’m looking at the examples and I suppose I’m not sure how it knows what “haloSilver” is. In my project, I have a DataGrid with five columns, populated by a PHP script that retrieves data from mysql. The first column retrieves an image to display user rank while the next three columns display text. The last column is currently unused. One of the columns currently reads ”

    I want to be able to set the background of the second, third and forth columns to #555555 but as soon as I try, I get script errors.

    http://www.battletech-live.net/error1010.png

  10. Well, I found that my problem is an apparent bug. If showHeaders is false, the debug version of Flash Player 10 will throw an error. A workaround is to keep headers visible, set their height to 1 and set their color to match the background of the columns, or as closely as possible.

  11. Peter deHaan says:

    Charles Shoults,

    Can you please file a bug at http://bugs.adobe.com/flex/ and include a test case which shows the error.

    Thanks,
    Peter

  12. a.samy says:

    Here is another solution for setting but for setting alternating column colors
    http://www.flex4ex.com/?p=9

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree