views:

32

answers:

2

I have a datagrid and it lists several rows as

seqno | NAME  | COMPANY
1     | BOB   | D&T
2     | Jenny | M&Y
3     | Jane  | D&T

It is possible to have buttons as [MOVE UP] and [MOVE DOWN] so that when I select a row in a datagrid and press one of those button that the order changes and the seqno updates accordingly.

Meaning if I select Jane and press the [MOVE UP] button, the new order would be;

seqno | NAME  | COMPANY
1     | BOB   | D&T
2     | Jane  | D&T
3     | Jenny | M&Y

All help is appriciated

+2  A: 

Yes it is possible. But you're going to have to write your own code to change the order of your original dataProvider. Add another column with the buttons; have them fire off events and make sure those events bubble. Listen to the event and then swap the appropriate objects in your dataProvider.

I've implemented this very thing int he Flextras DataSorter, however it is List based not DataGrid based.

http://www.flextras.com/?event=ProductHome&ProductID=7

www.Flextras.com
A: 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">

    <local:ControlDataGrid>
        <local:dataProvider>
            <mx:ArrayCollection>
                <mx:Object a="Anny" b="43"/>
                <mx:Object a="Jenny" b="11"/>
                <mx:Object a="Den" b="9"/>
                <mx:Object a="Marty" b="5"/>
                <mx:Object a="Mary" b="-1"/>
            </mx:ArrayCollection>
        </local:dataProvider>
        <local:columns>
            <mx:DataGridColumn dataField="a"/>
            <mx:DataGridColumn dataField="b"/>
            <mx:DataGridColumn itemRenderer="{new ClassFactory(ControlItemRenderer)}"/>
        </local:columns>
    </local:ControlDataGrid>

</mx:Application>

Source for ControlDataGrid.as:

package
{
import mx.collections.ArrayCollection;
import mx.controls.DataGrid;

public class ControlDataGrid extends DataGrid
{
    public function ControlDataGrid()
    {
        addEventListener(ControlEvent.UP, upHandler);
        addEventListener(ControlEvent.DOWN, downHandler);
    }

    private function moveRow(rowIndex:int, delta:int):void
    {
        var collection:ArrayCollection = ArrayCollection(dataProvider);
        collection.addItemAt(collection.removeItemAt(rowIndex), rowIndex + delta);
    }

    private function upHandler(event:ControlEvent):void
    {
        moveRow(event.rowIndex, -1);
    }

    private function downHandler(event:ControlEvent):void
    {
        moveRow(event.rowIndex, 1);
    }
}
}

Source for ControlItemRenderer.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
    implements="mx.controls.listClasses.IDropInListItemRenderer">

    <mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.controls.DataGrid;
        import mx.controls.listClasses.BaseListData;
        import mx.controls.listClasses.IDropInListItemRenderer;
        import mx.events.CollectionEvent;

        [Bindable]
        private var upEnabled:Boolean = false;

        [Bindable]
        private var downEnabled:Boolean = false;

        private var _listData:BaseListData;

        [Bindable("dataChange")]
        public function get listData():BaseListData
        {
            return _listData;
        }

        public function set listData(value:BaseListData):void
        {
            _listData = value;
            dataProvider = _listData ? ArrayCollection(DataGrid(_listData.owner).dataProvider) : null;
            commitChanges();
        }

        private var _dataProvider:ArrayCollection;

        private function get dataProvider():ArrayCollection
        {
            return _dataProvider;
        }

        private function set dataProvider(value:ArrayCollection):void
        {
            if (_dataProvider == value)
                return;

            if (_dataProvider)
                _dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
                    dataProvider_collectionChangeHandler);

            _dataProvider = value;

            if (_dataProvider)
                _dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,
                    dataProvider_collectionChangeHandler);
        }

        private function commitChanges():void
        {
            if (!_listData || !_dataProvider)
            {
                upEnabled = false;
                downEnabled = false;
                return;
            }

            upEnabled = _listData.rowIndex > 0;
            downEnabled = _listData.rowIndex < _dataProvider.length - 1;
        }

        private function dispatch(type:String):void
        {
            dispatchEvent(new ControlEvent(type, _listData.rowIndex))
        }

        private function dataProvider_collectionChangeHandler(event:CollectionEvent):void
        {
            commitChanges();
        }

    ]]>
    </mx:Script>

    <mx:LinkButton label="Up" visible="{upEnabled}" includeInLayout="{upEnabled}"
        click="dispatch(ControlEvent.UP)" textDecoration="underline"/>

    <mx:LinkButton label="Down" visible="{downEnabled}" includeInLayout="{downEnabled}"
        click="dispatch(ControlEvent.DOWN)" textDecoration="underline"/>

</mx:HBox>

Source for ControlEvent.as:

package
{
import flash.events.Event;

public class ControlEvent extends Event
{

    public static const UP:String = "up";

    public static const DOWN:String = "down";

    public function ControlEvent(type:String, rowIndex:int)
    {
        super(type, true);

        this.rowIndex = rowIndex;
    }

    public var rowIndex:int;
}
}
Maxim Kachurovskiy