Menu

Spark Sort and SortField

SourceForge Editorial Staff

Functional and Design Specification


Glossary


Locale data All the data that is required by a framework/application/API in order to be able to honor various cultural conventions in a specific language and region. The data consist of month and day names, date patterns, decimal and thousand separators for number formatting, rules for language specific sorting, info on the measurement system used, and so on. The exact type of data each system chooses to store differs between systems.

Locale In the context of this document, locale refers to the language, script, and region for which an operating system has a collection of locale data as described above. The identification of a locale can be further tailored using variants and keywords. See Locale ID below.

Locale Identifier A string that identifies a locale. In the context of this specification, locale identifiers use the syntax defined in Unicode Technical Standard #35, Unicode Locale Data Markup Language (LDML). In this syntax a locale identifier consists of several sub-tags, that specify the language, script, region, variants, and key value pairs. E.g. the locale identifier for Germany using the German language and sorting by the phonebook sort order is: de-DE@collation=phonebook. Note that not all sub-tags are required; in this case the script is inferred from the language.

flash.globalization A new package added to Flash player version 10.1 to access locale-specific functionality provided by the operating system on which the Flash Player is running.

Summary and Background


This Spark Sort & SortField creation is a part of integration of the flash.globalization package with the Flex SDK. (The entire integration process includes the addition of new classes and updates in some existing classes. Such examples are: Spark NumberFormatter, CurrencyFormatter, DateTimeFormatter, MatchingCollator, SortingCollator, StringTools, NumberValidator and CurrencyValidator.)
The existing MX Sort and SortField classes use a compare function for strings that is based on the Unicode code values and does not take into account ordering rules that are language specific. Thus for most languages, the current behavior is incorrect. This specification proposes the creation of new Sort and SortField classes in the Spark namespace that use the language specific string comparison method from the flash.globalization.Collator class by default. In the flash.globalization.Collator class, the language to be used for string comparison is specified by a LocaleID. The new Spark Sort and SortField classes will follow the precedent set by the spark.formatters and spark.globalization classes use the locale style to specify the LocaleID.
A primary use of these new classes is for comparison in the columns of DataGrid components and classes that implement the mx.collections.ICollectionView. To allow interchangeability between the MX Sort and SortField classes, interfaces will be defined and then both the MX and Spark Sort and SortField classes will implement these interfaces.
The new Spark DataGrid component, will use these new Spark Sort and SortField classes by default.

Usage Scenarios


  • Danny is a freelance Flex developer building Rich Internet financial applications for browsers and Android phones. He is currently building an application for a well-known global bank. One of the application features allows a client to list past transactions. Danny uses the Spark DataGrid in Flex SDK to show the data. The list items can be sorted in alphabetical in locale-specific manner or numerical order.
  • Gouri is a web designer primarily conversant with HTML, MXML and Flex. She is not comfortable coding ActionScript but is OK with MXML syntax. She is developing an auto parts sales application frontend that needs to cater to English, French and Chinese communities per customer demand. The users input the model name of their vehicle and the program is supposed to list potential models in alphabetical order.

Detailed Description

Requirements


  1. Do not change the behavior of the existing MX Sort and SortField classes in an incompatible manner.
  2. Create new Spark Sort & SortField classes that perform locale-aware comparison for strings by default.
  3. Make MX Sort & SortField and Spark counterparts interchangeable and have similar API signatures as much as possible.
  4. The new Spark Sort & SortField should derive the locale in the same way as the Spark Formatter and Validator classes.

API Description


The new Spark Sort & SortField will have almost same API signatures with the existing MX counterparts. The notable points are:

  1. New Sort & SortField interfaces will be created to make the MX and Spark Sort and SortField classes interchangeable. (mx.collections.ISort, mx.collections.ISortField, spark.globalization.Sort and spark.globalization.SortField)
  2. Some mx_internal functions in the existing MX SortField class will be made public in order to make the MX and Spark versions interchangeable. Proper ASDoc descriptions will be added for those functions if they currently don't exist.
  3. The new Spark Sort & SortField classes will derive from AdvancedStyleClient class to provide style inheritance for the locale style.

Following is the proposed Sort & SortField interfaces. They are simply extracted from the existing MX Sort & SortField classes and the behavior will be the same with the current MX versions. However, SortField.caseInsensitive is not included in the interface. For the Spark SortField class, this attribute is controlled by a property of the Spark Collator. The existing MX SortField class will continue to have a caseInsensitive property.

package mx.collections
{
// Proposed ISortField interface.
// The existing MX and the new Spark SortField classes implement this interface.
// The MX version has all of those functions already.
public interface ISort
{
    //--------------------------------------------------------------------------
    //  Properties
    //--------------------------------------------------------------------------

    function get compareFunction():Function;
    function set compareFunction(value:Function):void;

    function get fields():Array;
    function set fields(value:Array):void;

    function get unique():Boolean;
    function set unique(value:Boolean):void;

    //--------------------------------------------------------------------------
    //  Functions
    //--------------------------------------------------------------------------

    function findItem( items:Array, values:Object, mode:String, returnInsertionIndex:Boolean = false, compareFunction:Function = null):int;

    function propertyAffectsSort(property:String):Boolean;

    function reverse():void;

    function sort(items:Array):void;
}

// Proposed ISortField interface.
// The existing MX and the new Spark SortField will implement this interface.
// The MX version has all of those functions already plus caseInsensitive:Boolean property.
public interface ISortField
{
    //--------------------------------------------------------------------------
    //  Properties
    //--------------------------------------------------------------------------

    function get compareFunction():Function;
    function set compareFunction(c:Function):void;

    function get descending():Boolean;
    function set descending(value:Boolean):void;

    function get name():String;
    function set name(n:String):void;

    function get numeric():Object;
    function set numeric(value:Object):void;

    //--------------------------------------------------------------------------
    //  Functions
    //--------------------------------------------------------------------------

    function reverse():void;

    //--------------------------------------------------------------------------
    //  Properties and functions that were used to be mx_internal and now public
    //--------------------------------------------------------------------------

    function get usingCustomCompareFunction():Boolean;

    function internalCompare(a:Object, b:Object):int;

    function getArraySortOnOptions():int;

    function initCompare(obj:Object):void;
}

}

Update on Nov. 29, 2010
The functions that were used to be mx_internals now have been assigned new names or removed for better clarity as public functions.

Old name
New name

function get usingCustomCompareFunction():Boolean;
(no change)

function internalCompare(a:Object, b:Object):int;
(removed, substituted with other calls.)

function getArraySortOnOptions():int;
function get arraySortOnOptions():int;

function initCompare(obj:Object):void;
function initializeDefaultCompareFunction(obj:Object):void;

Update on Dec. 3, 2010

The new Spark Sort & SortField will have exactly the same API signature with the existing MX counterparts minus SortField.caseInsensitive:Boolean property.

B Features


Examples and Usage


<?xml version="1.0" encoding="utf-8"?>
<!-- Simple example to demonstrate the Halo DataGrid control. -->
<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">
    <fx:Declarations>
        <fx:XMLList id="employees">
            <employee>
                <name>Joanne Wall</name>
                <phone>555-219-2012</phone>
                <email>jwall@fictitious.com</email>
                <active>true</active>
            </employee>

            <employee>
                <name>fr cote</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>

            <employee>
                <name>Maurice Smith</name>
                <phone>555-219-2012</phone>
                <email>maurice@fictitious.com</email>
                <active>false</active>
            </employee>

            <employee>
                <name>fr côte</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>

            <employee>
                <name>fr coté</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>

            <employee>
                <name>fr côté</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>

            <employee>
                <name>Christina Coenraets</name>
                <phone>555-219-2270</phone>
                <email>ccoenraets@fictitious.com</email>
                <active>true</active>
            </employee>

            <employee>
                <name>Mary Jones</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>
        </fx:XMLList>
        <s:XMLListCollection id="employees2" source="{employees}"/>
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import mx.collections.ISort;
            import mx.collections.ISortField;
            import mx.collections.Sort;
            import mx.collections.SortField;
            import spark.globalization.Sort;
            import spark.globalization.SortField;
            import spark.globalization.SortingCollator;

            <a href="Bindable%28%26quot%3Bchange%26quot%3B%29">Bindable("change")</a>
            private static var useSparkSort:Boolean = true;

            <a href="Bindable%28%26quot%3Bchange%26quot%3B%29">Bindable("change")</a>
            private var collator:SortingCollator = new SortingCollator();

            private function sortCompareFunction(a:String, b:String):int
            {
                return collator.compare(a, b);
            }

            private function sortChange(locale:String):void
            {
                const sort:ISort = useSparkSort
                    ? new spark.globalization.Sort()
                    : new mx.collections.Sort();

                if (useSparkSort)
                    addStyleClient(sort as spark.globalization.Sort);

                sort.fields = new Array();
                var sf:mx.collections.ISortField;

                sf = useSparkSort
                    ? new spark.globalization.SortField()
                    : new mx.collections.SortField();

                if (useSparkSort)
                    addStyleClient(sf as spark.globalization.SortField);

                sf.name = "name";
                sf.compareFunction = sortCompareFunction;
                sort.fields.push(sf);

                employees2.sort = sort;
                dg.dataProvider = employees2;
                if (locale)
                {
                    collator.setStyle("locale", locale);
                    (dg.columns<a href="0">0</a> as DataGridColumn).sortCompareFunction = sortCompareFunction;
                }
                else
                {
                    (dg.columns<a href="0">0</a> as DataGridColumn).sortCompareFunction = null;
                }
            }
        ]]>
    </fx:Script>
    <mx:Form>
        <mx:FormItem label="Locale">
            <s:RadioButton label="Use Spark Sort/SortFiled classes"
                click="useSparkSort=true" selected="{useSparkSort}"/>
            <s:RadioButton label="Use MX Sort/SortFiled classes"
                click="useSparkSort=false" selected="{useSparkSort}"/>
        </mx:FormItem>
        <mx:FormItem label="Locale">
            <s:Button label="Sort: No Collator" click="sortChange(null)"/>
            <s:Button label="Sort: Collator with 'en' locale" click="sortChange('en')"/>
            <s:Button label="Sort: Collator with 'fr' locale" click="sortChange('fr')"/>
        </mx:FormItem>
        <mx:FormItem label="DataGrid">
            <mx:Text text="Select a row in the DataGrid control."/>
            <mx:DataGrid id="dg" width="100%" height="100%" rowCount="10" dataProvider="{employees2}">
                <mx:columns>
                    <mx:DataGridColumn dataField="name" headerText="Name"/>
                    <mx:DataGridColumn dataField="phone" headerText="Phone"/>
                    <mx:DataGridColumn dataField="email" headerText="Email"/>
                </mx:columns>
            </mx:DataGrid>
        </mx:FormItem>
        <mx:FormItem label="Selected Item">
            <mx:Form>
                <mx:FormItem label="Name">
                    <mx:Label text="{dg.selectedItem.name}"/>
                </mx:FormItem>
                <mx:FormItem label="Email">
                    <mx:Label text="{dg.selectedItem.email}"/>
                </mx:FormItem>
                <mx:FormItem label="Phone">
                    <mx:Label text="{dg.selectedItem.phone}"/>
                </mx:FormItem>
            </mx:Form>
        </mx:FormItem>
    </mx:Form>
</s:Application>

Additional Implementation Details


Prototype Work


A prototype was made based on the current specification.

Compiler Work


None.

Web Tier Compiler Impact


None.

Flex Feature Dependencies


Dependent on several of the support classes that were created when implementing the spark validator classes. The dependent classes are:

  • spark.globalization.SortingCollator
  • spark.globalization.LastOperationStatus

Backwards Compatibility


Syntax changes

None.

Behavior

None.

Warnings/Deprecation

None.
However, the new Spark SortField will not have caseInsensitive:Boolean property compare to the existing MX counterpart. Also the new Spark Sort & SortField classes will extend AdvancedStyleClient class as opposed to EventDispatcher class, which the existing MX versions extend.

Accessibility


None.

Performance


None.

Globalization


None.

Localization


Compiler Features

None.

Framework Features

None. Some existing error messages in Flex SDK are used.

Cross-Platform Considerations


The flash.globalization classes provide different results depending on the platform. Therefore this feature will require testing on different platforms, to ensure that these platform differences are handled properly. If there is a platform that does not support the flash.globalization classes, then testing should also include that platform. The testing should also include setting locales that are not supported on the specific device. This will ensure that the fallback behavior is working correctly.

Issues and Recommendations


None.


Related

Wiki: Flex 4.5

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.