3 Replies Latest reply on Dec 8, 2009 9:09 PM by PhilipKeiter

    Sorting DataGrid by multiple columns but sorting arrow not appearing... need help!

    aq2sllik Level 1
      I'm trying to be able to sort the datagrid by multiple columns... I'm using this code:
      http://livedocs.adobe.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDo cs_Parts&file=00000598.html

      The sorting is working fine, but the little sorting arrow in the column header is not showing... any ideas on how I can get it to show?

      I've tried creating a custom headerRenderer but it got a little complicated... is there a way to do it without a custom headerRenderer? Any help is appriciated, thanks!
        • 1. Re: Sorting DataGrid by multiple columns but sorting arrow not appearing... need help!
          ThinkingProspects
          The code does not show the little arrow icon as there is call to event.preventDefault.
          If you want to avoid custom renderer, you can have custom sort. There is Sort class. which can be assigned to the dataprovider. but before that see if this helps. I have the header release function and set sortableColumns property to True.

          <?xml version="1.0"?>
          <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml"
          initialize="initDP();" width="550" height="400">

          <mx:Script>
          <![CDATA[
          import mx.events.DataGridEvent;
          import mx.collections.*;

          // Declare storage variables and initialize the simple variables.
          // The data provider collection.
          private var myDPColl:ArrayCollection;
          // The Sort object used to sort the collection.
          private var sortA:Sort;
          // The sort fields used to determine the sort.
          private var sortByInStock:SortField;
          private var sortByArtist:SortField;
          private var sortByAlbum:SortField;
          private var sortByPrice:SortField;
          // The data source that populates the collection.
          private var myDP:Array = [
          {Artist:'Pavement', Album:'Slanted and Enchanted',
          Price:11.99, InStock: true},
          {Artist:'Pavement', Album:'Crooked Rain, Crooked Rain',
          Price:10.99, InStock: false},
          {Artist:'Pavement', Album:'Wowee Zowee',
          Price:12.99, InStock: true},
          {Artist:'Asphalt', Album:'Brighten the Corners',
          Price:11.99, InStock: false},
          {Artist:'Asphalt', Album:'Terror Twilight',
          Price:11.99, InStock: true},
          {Artist:'Asphalt', Album:'Buildings Meet the Sky',
          Price:14.99, InStock: true},
          {Artist:'Other', Album:'Other', Price:5.99, InStock: true}
          ];

          //Initialize the DataGrid control with sorted data.
          private function initDP():void {
          //Create an ArrayCollection backed by the myDP array of data.
          myDPColl = new ArrayCollection(myDP);
          //Create a Sort object to sort the ArrrayCollection.
          sortA = new Sort();
          //Initialize SortField objects for all valid sort fields:
          // A true second parameter specifies a case-insensitive sort.
          // A true third parameter specifies descending sort order.
          // A true fourth parameter specifies a numeric sort.
          sortByInStock = new SortField("InStock", true, true);
          sortByArtist = new SortField("Artist", true);
          sortByAlbum = new SortField("Album", true);
          sortByPrice = new SortField("Price", true, false, true);
          // Sort the grid using the InStock, Artist, and Album fields.
          sortA.fields=[sortByInStock, sortByArtist, sortByAlbum];
          myDPColl.sort=sortA;
          // Refresh the collection view to show the sort.
          myDPColl.refresh();
          // Set the ArrayCollection as the DataGrid data provider.
          myGrid.dataProvider=myDPColl;
          // Set the DataGrid row count to the array length,
          // plus one for the header.
          myGrid.rowCount=myDPColl.length +1;
          }

          // Re-sort the DataGrid control when the user clicks a header.
          private function headRelEvt(event:DataGridEvent):void {
          // The new third priority was the old second priority.
          sortA.fields[2] = sortA.fields[1];
          // The new second priority was the old first priority.
          sortA.fields[1] = sortA.fields[0];
          // The clicked column determines the new first priority.
          if (event.columnIndex==0) {
          sortA.fields[0] = sortByArtist;
          } else if (event.columnIndex==1) {
          sortA.fields[0] = sortByAlbum;
          } else if (event.columnIndex==2) {
          sortA.fields[0] = sortByPrice;
          } else {
          sortA.fields[0] = sortByInStock;}
          // Apply the updated sort fields and re-sort.
          myDPColl.sort=sortA;
          // Refresh the collection to show the sort in the grid.
          myDPColl.refresh();
          // Prevent the DataGrid from doing a default column sort.
          event.preventDefault();
          }
          ]]>
          </mx:Script>

          <!-- The Data Grid control.
          By default the grid and its columns can be sorted by clicking.
          The headerRelease event handler overrides the default sort
          behavior. -->
          <mx:DataGrid id="myGrid" width="100%" sortableColumns="true">
          <mx:columns>
          <mx:DataGridColumn minWidth="120" dataField="Artist" />
          <mx:DataGridColumn minWidth="200" dataField="Album" />
          <mx:DataGridColumn width="75" dataField="Price" />
          <mx:DataGridColumn width="75" dataField="InStock"
          headerText="In Stock"/>
          </mx:columns>
          </mx:DataGrid>
          </mx:Application>

          • 2. Re: Sorting DataGrid by multiple columns but sorting arrow not appearing... need help!
            aq2sllik Level 1
            ThinkingProspects, in the example you've provided the headRelEvt method is never called because you don't add an event listener to headerRelease event so thats why the arrows work.

            There is already a Sort class assigned to the dataprovider:

            //Create a Sort object to sort the ArrrayCollection.
            sortA = new Sort();
            //Initialize SortField objects for all valid sort fields:
            // A true second parameter specifies a case-insensitive sort.
            // A true third parameter specifies descending sort order.
            // A true fourth parameter specifies a numeric sort.
            sortByInStock = new SortField("InStock", true, true);
            sortByArtist = new SortField("Artist", true);
            sortByAlbum = new SortField("Album", true);
            sortByPrice = new SortField("Price", true, false, true);
            // Sort the grid using the InStock, Artist, and Album fields.
            sortA.fields=[sortByInStock, sortByArtist, sortByAlbum];
            myDPColl.sort=sortA;

            Can anyone think of a solution to this?
            • 3. Re: Sorting DataGrid by multiple columns but sorting arrow not appearing... need help!
              PhilipKeiter Level 2

              Hello aq2sllik,

               

              The DataGrid class was coded to only show sort arrows if only one column was sorted on. If you ctrl click the DataGrid tag to see its code, you will notice that in its private method updateSortIndexAndDirection(), there is this if statement: if (fields.length != 1), and within the if statement body it clears the sortColumn indicators and returns.

               

              The reason the Flex Framework developers did this, was because it is unclear what the behavior should be when there is more than one sort field. Do you just put the arrow on the first field or on every field? If on every field do you color code them to show the sort order? There is no one-solution-fits-all solution.

               

              Since this is controlled in private methods, in order to extend the behavior, you'll have to make a copy of the DataGrid control in your project, with the same package structure (mx.controls.DataGrid) and edit the code there. The compiler will prefer your project's version of the DataGrid code over the framework swc's version.

               

              Or, if it is an option for you, it would a better idea to use the AdvancedDataGrid, which went with a one-solution-fits-all advanced sorting using header arrows with numbers next to them showing the priority.

               

              Thanks,

              Philip

               

              Message was edited by: Philip Keiter