Displaying the sort arrow in a Flex DataGrid control without having to click a column

by Peter deHaan on February 28, 2008

I’ve seen this question come up a few times recently in various forums/lists and even in my blog comments (see “Changing the default sort arrow skin on a Flex DataGrid control”).

The following example shows how you can display the sort arrow in a DataGrid control in Flex without having the user click on a column header in the DataGrid control.

Full code after the jump.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/02/28/displaying-the-sort-arrow-in-a-flex-datagrid-control-without-having-to-click-a-column/ -->
<mx:Application name="DataGrid_dataProvider_sort_fields_test">
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Script>
        <![CDATA[
            import mx.collections.Sort;
            import mx.collections.SortField;
 
            private function init():void {
                arrColl.sort = new Sort();
                arrColl.sort.fields = [new SortField("idx", false, true)];
                arrColl.refresh();
            }
        ]]>
    </mx:Script>
 
    <mx:ArrayCollection id="arrColl">
        <mx:source>
            <mx:Array>
                <mx:Object idx="1" c1="One.1" c2="One.2" />
                <mx:Object idx="2" c1="Two.1" c2="Two.2" />
                <mx:Object idx="3" c1="Three.1" c2="Three.2" />
                <mx:Object idx="4" c1="Four.1" c2="Four.2" />
                <mx:Object idx="5" c1="Five.1" c2="Five.2" />
                <mx:Object idx="6" c1="Six.1" c2="Six.2" />
                <mx:Object idx="7" c1="Seven.1" c2="Seven.2" />
                <mx:Object idx="8" c1="Eight.1" c2="Eight.2" />
                <mx:Object idx="9" c1="Nine.1" c2="Nine.2" />
                <mx:Object idx="10" c1="Ten.1" c2="Ten.2" />
                <mx:Object idx="11" c1="Eleven.1" c2="Eleven.2" />
                <mx:Object idx="12" c1="Twelve.1" c2="Twelve.2" />
                <mx:Object idx="13" c1="Thirteen.1" c2="Thirteen.2" />
            </mx:Array>
        </mx:source>
    </mx:ArrayCollection>
 
    <mx:DataGrid id="dataGrid"
            dataProvider="{arrColl}"
            creationComplete="init();">
        <mx:columns>
            <mx:DataGridColumn dataField="idx" />
            <mx:DataGridColumn dataField="c1" />
            <mx:DataGridColumn dataField="c2" />
        </mx:columns>
    </mx:DataGrid>
 
</mx:Application>

View source is enabled in the following example.

A big thanks to Rob for the heads up with the solution!

For more information, see http://bugs.adobe.com/jira/browse/SDK-14663.

{ 14 comments… read them below or add one }

bsides August 5, 2009 at 4:39 pm

How do I do the first part but with a XMLList and not an array? Could you please give one example? Pretty please :)

Reply

Peter deHaan August 5, 2009 at 11:05 pm

@bsides,

How about this?

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/02/28/displaying-the-sort-arrow-in-a-flex-datagrid-control-without-having-to-click-a-column/ -->
<mx:Application name="DataGrid_dataProvider_sort_fields_test"
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Script>
        <![CDATA[
            import mx.collections.Sort;
            import mx.collections.SortField;
 
            private function init():void {
                xmlListColl.sort = new Sort();
                xmlListColl.sort.fields = [new SortField("@idx", false, true, true)];
                xmlListColl.refresh();
            }
        ]]>
    </mx:Script>
 
    <mx:XMLListCollection id="xmlListColl">
        <mx:source>
            <mx:XMLList>
                <node idx="1" c1="One.1" c2="One.2" />
                <node idx="2" c1="Two.1" c2="Two.2" />
                <node idx="3" c1="Three.1" c2="Three.2" />
                <node idx="4" c1="Four.1" c2="Four.2" />
                <node idx="5" c1="Five.1" c2="Five.2" />
                <node idx="6" c1="Six.1" c2="Six.2" />
                <node idx="7" c1="Seven.1" c2="Seven.2" />
                <node idx="8" c1="Eight.1" c2="Eight.2" />
                <node idx="9" c1="Nine.1" c2="Nine.2" />
                <node idx="10" c1="Ten.1" c2="Ten.2" />
                <node idx="11" c1="Eleven.1" c2="Eleven.2" />
                <node idx="12" c1="Twelve.1" c2="Twelve.2" />
                <node idx="13" c1="Thirteen.1" c2="Thirteen.2" />
            </mx:XMLList>
        </mx:source>
    </mx:XMLListCollection>
 
    <mx:DataGrid id="dataGrid"
            dataProvider="{xmlListColl}"
            creationComplete="init();">
        <mx:columns>
            <mx:DataGridColumn dataField="@idx" />
            <mx:DataGridColumn dataField="@c1" />
            <mx:DataGridColumn dataField="@c2" />
        </mx:columns>
    </mx:DataGrid>
 
</mx:Application>

Peter

Reply

Alexandre Croiseaux August 18, 2009 at 6:13 am

If you just want to display arrows without sorting the model, you can extend the datagrid class and add these 2 methods :

public function set sortIndex(index:uint):void { mx_internal::sortIndex = index; } // Column index
public function set sortDirection(direction:String):void { mx_internal::sortDirection = direction; } //ASC or DESC

you don’t need to refresh the dataprovider…

Hope that helps
Alex

Reply

peter December 2, 2009 at 4:23 am

@Alexandre Croiseaux

thanks!

i needed to invalidateDisplayList() on the grid afterwards tough

Reply

Colin February 26, 2010 at 5:45 am

I have an interesting challenge with regard to sort arrows. I would like to not show them in order to preserve available label real estate. I have attempting this by setting sortArrowSkin to various things but with no luck. Might you be able to offer me any advise?

Reply

Peter deHaan February 26, 2010 at 8:04 am

@Colin,

You should be able to set the sortArrowSkin to null, although it would appear that it makes the column unsortable (that may be a bug):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 
    <mx:DataGrid sortArrowSkin="{null}">
        <mx:columns>
            <mx:DataGridColumn dataField="c1" />
            <mx:DataGridColumn dataField="c2" />
            <mx:DataGridColumn dataField="c3" />
        </mx:columns>
        <mx:dataProvider>
            <mx:ArrayCollection>
                <mx:Object c1="row1, col1" c2="row1, col2" c3="row1, col3" />
                <mx:Object c1="row2, col1" c2="row2, col2" c3="row2, col3" />
                <mx:Object c1="row3, col1" c2="row3, col2" c3="row3, col3" />
                <mx:Object c1="row4, col1" c2="row4, col2" c3="row4, col3" />
                <mx:Object c1="row5, col1" c2="row5, col2" c3="row5, col3" />
                <mx:Object c1="row6, col1" c2="row6, col2" c3="row6, col3" />
                <mx:Object c1="row7, col1" c2="row7, col2" c3="row7, col3" />
                <mx:Object c1="row8, col1" c2="row8, col2" c3="row8, col3" />
                <mx:Object c1="row9, col1" c2="row9, col2" c3="row9, col3" />
            </mx:ArrayCollection>
        </mx:dataProvider>
    </mx:DataGrid>
 
</mx:Application>

Peter

Reply

Peter deHaan February 26, 2010 at 8:06 am

Or you could set the sortArrowSkin style via an external .CSS file or <Style> block, as seen in the following example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 
    <mx:Style>
        DataGrid {
            sortArrowSkin: ClassReference(null);
        }
    </mx:Style>
 
    <mx:DataGrid>
        <mx:columns>
            <mx:DataGridColumn dataField="c1" />
            <mx:DataGridColumn dataField="c2" />
            <mx:DataGridColumn dataField="c3" />
        </mx:columns>
        <mx:dataProvider>
            <mx:ArrayCollection>
                <mx:Object c1="row1, col1" c2="row1, col2" c3="row1, col3" />
                <mx:Object c1="row2, col1" c2="row2, col2" c3="row2, col3" />
                <mx:Object c1="row3, col1" c2="row3, col2" c3="row3, col3" />
                <mx:Object c1="row4, col1" c2="row4, col2" c3="row4, col3" />
                <mx:Object c1="row5, col1" c2="row5, col2" c3="row5, col3" />
                <mx:Object c1="row6, col1" c2="row6, col2" c3="row6, col3" />
                <mx:Object c1="row7, col1" c2="row7, col2" c3="row7, col3" />
                <mx:Object c1="row8, col1" c2="row8, col2" c3="row8, col3" />
                <mx:Object c1="row9, col1" c2="row9, col2" c3="row9, col3" />
            </mx:ArrayCollection>
        </mx:dataProvider>
    </mx:DataGrid>
 
</mx:Application>

Peter

Peter deHaan February 26, 2010 at 8:14 am

And the workaround for the null sort arrow skin not performing a sort is to set the sortArrowSkin style to something like ProgrammaticSkin instead:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 
    <!-- <mx:Style>
        DataGrid {
            sortArrowSkin: ClassReference("mx.skins.ProgrammaticSkin");
        }
    </mx:Style> -->
 
    <mx:DataGrid sortArrowSkin="mx.skins.ProgrammaticSkin">
        <mx:columns>
            <mx:DataGridColumn dataField="c1" />
            <mx:DataGridColumn dataField="c2" />
            <mx:DataGridColumn dataField="c3" />
        </mx:columns>
        <mx:dataProvider>
            <mx:ArrayCollection>
                <mx:Object c1="row1, col1" c2="row1, col2" c3="row1, col3" />
                <mx:Object c1="row2, col1" c2="row2, col2" c3="row2, col3" />
                <mx:Object c1="row3, col1" c2="row3, col2" c3="row3, col3" />
                <mx:Object c1="row4, col1" c2="row4, col2" c3="row4, col3" />
                <mx:Object c1="row5, col1" c2="row5, col2" c3="row5, col3" />
                <mx:Object c1="row6, col1" c2="row6, col2" c3="row6, col3" />
                <mx:Object c1="row7, col1" c2="row7, col2" c3="row7, col3" />
                <mx:Object c1="row8, col1" c2="row8, col2" c3="row8, col3" />
                <mx:Object c1="row9, col1" c2="row9, col2" c3="row9, col3" />
            </mx:ArrayCollection>
        </mx:dataProvider>
    </mx:DataGrid>
 
</mx:Application>

I’ll file a bug at http://bugs.adobe.com/flex/ later today and document the workaround and then post the bug number here for anybody interested.

Peter

Peter deHaan February 26, 2010 at 11:09 am

Bug filed; http://bugs.adobe.com/jira/browse/SDK-25679

When I tested in Flex 3.5, I got a runtime error. I don’t remember seeing that at home, so I’ll double check my home config later.

Peter

Colin February 26, 2010 at 9:01 am

This solution works perfectly. Thanks again and thank you for this blog; a fantastic resource.

Reply

Anonymous February 28, 2010 at 9:23 pm

Hi,

Another way to prevent the sort arrow from appearing is to override placeSortArrow to do nothing:

override protected function placeSortArrow():void{}

- Rob

Reply

Peter deHaan February 28, 2010 at 10:11 pm

@Rob,

Good tip, thanks!

Peter

Reply

Flexicious March 3, 2010 at 6:06 pm

We actually have a grid that solves the issue of placing the intial sort arrow as required by the original poster. This is available at http://www.flexicious.com. We also have a solution for the advanced datagrid, where you can programatically add multiple sorts and it will draw the arrows appropriately.

Reply

Geert July 15, 2010 at 6:15 am

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: