Sunday, July 3, 2011

ArrayCollection in Flex: Part 2 - Sorting

Today we will learn how to sort elements in our ArrayCollection using the Sort class.

In this tutorial we will be sorting elements of ArrayCollection. You might already be familiar with the sort() and sortOn() methods that work with Array objects, but these won't work here. To perform sorting in an ArrayCollection, we need to create an object of the Sort class, which we use to set the criteria for our sorting, and then pass this object to the ArrayCollection and refresh its contents.

Our ArrayCollection in this tutorial will have 3 attributes - firstname, lastname and age.

<fx:Declarations>
<mx:ArrayCollection id="myAC">
<fx:Object firstname="John" lastname="Jackson" age="25" />
<fx:Object firstname="Bob" lastname="Thompson" age="30" />
<fx:Object firstname="Andy" lastname="Doyle" age="30" />
</mx:ArrayCollection>
</fx:Declarations>

For the sake of this tutorial, to somehow see the results, we will use a DataGrid object to display the contents of our ArrayCollection. Note that each DataGrid has its own pre-made sorting features, but in this tutorial we are only using the DataGrid to display the contents of the ArrayCollection and then sort them using our own code, so we might as well turn the default sorting feature of the columns in the DataGrid off.

<mx:DataGrid dataProvider="{myAC}" sortableColumns="false" />

We will then add some buttons for sorting the data. Note that the data is not sorted in the DataGrid, it is the elements of ArrayCollection that are sorted, and the results are displayed in DataGrid.

Here is how the final application will look like:


So let's add these 4 buttons:

<s:VGroup>
<mx:DataGrid dataProvider="{myAC}" sortableColumns="false" />
<s:Button label="Sort by first name"/>
<s:Button label="Sort by last name"/>
<s:Button label="Sort by age"/>
<s:Button label="Sort by first name and age"/>
</s:VGroup>

In our script place, we need to import 2 more classes - Sort and SortField, as well as create a new Sort object.

<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.Sort;
import mx.collections.SortField;

private var mySort:Sort = new Sort();
]]>
</fx:Script>

Now I will explain how sorting actually works.

Basically, all we need to sort our ArrayCollection is this piece of code:

private var mySort:Sort = new Sort();
mySort.fields = [new SortField('firstname', true)];
myAC.sort = mySort;
myAC.refresh();

Firstly we need to create a Sort object (which we already did in our main code), then we set its fields value to an Array of SortField objects, then we apply this Sort object as the value of the sort propetry of our ArrayCollection, and then we refresh() our ArrayCollection. Note: we can only refresh an ArrayCollection after we have sort applied to it, remember that.

Now, what is this fields property? What do we need to apply to it? This is basically the criteria that Flex will use to sort your data. Why is it an array though? Because we can set more than one criterias, for example, we can sort by firstname and age at the same time.

A SortField object can have 4 parameters - the first one is name of the property that we will sort by. The second one is a boolean value, which indicates whether the sorting should be case insensitive or not. The third parameter is used to tell whether the sorting should be descending (also a boolean). The fourth parameter is used to tell whether the value of this property is a numeric value or not (as you may already know, numbers are sorted differently from string values).

Now that we know how this works, we can continue working on our application. Let's create a function called doSort() and make it possible to pass a parameter, which is an Array of SortField objects, we will later use this parameter to set it as the field property of the sort object.

<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.Sort;
import mx.collections.SortField;

private var mySort:Sort = new Sort();

private function doSort(fields:Array):void{
mySort.fields = fields;
myAC.sort = mySort;
myAC.refresh();
}
]]>
</fx:Script>

Now we need to update our buttons and make them call this function on click. We pass the SortField array as the parameter.

<s:VGroup>
<mx:DataGrid dataProvider="{myAC}" sortableColumns="false" />
<s:Button label="Sort by first name" click="doSort([new SortField('firstname', true)]);" />
<s:Button label="Sort by last name" click="doSort([new SortField('lastname', true)]);" />
<s:Button label="Sort by age" click="doSort([new SortField('age', true, false, true)]);" />
<s:Button label="Sort by first name and age" click="doSort([new SortField('firstname', true), new SortField('age', true, false, true)]);" />
</s:VGroup>

Full code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
   width="320" height="300">
   
<fx:Declarations>
<mx:ArrayCollection id="myAC">
<fx:Object firstname="John" lastname="Jackson" age="25" />
<fx:Object firstname="Bob" lastname="Thompson" age="30" />
<fx:Object firstname="Andy" lastname="Doyle" age="30" />
</mx:ArrayCollection>
</fx:Declarations>


<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.Sort;
import mx.collections.SortField;

private var mySort:Sort = new Sort();

private function doSort(fields:Array):void{
mySort.fields = fields;
myAC.sort = mySort;
myAC.refresh();
}
]]>
</fx:Script>

<s:VGroup>
<mx:DataGrid dataProvider="{myAC}" sortableColumns="false" />
<s:Button label="Sort by first name" click="doSort([new SortField('firstname', true)]);" />
<s:Button label="Sort by last name" click="doSort([new SortField('lastname', true)]);" />
<s:Button label="Sort by age" click="doSort([new SortField('age', true, false, true)]);" />
<s:Button label="Sort by first name and age" click="doSort([new SortField('firstname', true), new SortField('age', true, false, true)]);" />
</s:VGroup>

</s:Application>

Thanks for reading!

Related:

ArrayCollection in Flex: Part 1 - Declaration
ArrayCollection in Flex: Part 3 - Listening to updates
ArrayCollection in Flex: Part 4 - Filtering the elements
ArrayCollection in Flex: Part 5 - Searching using a Cursor

No comments:

Post a Comment