AboutFlex.net

flex,air,flash …

Archive for July 30th, 2008

This example shows you how to create a component that extends the TileList and gives you the possibility to sort the element;

This movie requires Flash Player 9

The Application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	creationComplete="{init()}"
	layout="absolute" xmlns:creativesource="it.creativesource.*">
	<mx:Script>
		<![CDATA[
			import it.creativesource.SortObject;
			import it.creativesource.DisplayItem;
			import mx.collections.ArrayCollection;

			[Bindable]
			private var dp:ArrayCollection=new ArrayCollection();

			[Bindable]
			private var fields:ArrayCollection=new ArrayCollection();

			private function init():void{

				var field1:SortObject=new SortObject("field1");
				var field2:SortObject=new SortObject("field2");
				var field3:SortObject=new SortObject("field3");

				field1.label="Sort by field1";
				field2.label="Sort by field2";
				field3.label="Sort by field3";				

				field1.isNumeric=true;
				field2.isNumeric=true;
				field3.isNumeric=true;				

				fields.addItem(field1);
				fields.addItem(field2);
				fields.addItem(field3);

				for(var i:int=0;i<10;i++){
					var obj:Object={};
					obj['field1']=i;
					obj['field2']=Math.round(Math.random()*100);
					obj['field3']=Math.round(Math.random()*100);

					dp.addItem(obj);

				}

			}

		]]>
	</mx:Script>
	<creativesource:SortableTileList 

		itemRenderer="it.creativesource.DisplayItem"
		dataProvider="{dp}"
		x="10" y="10"
		width="400" height="480"
		sortableFields="{fields}"
	 />
	<mx:Button x="418" y="10" label="Button"/>
	<mx:Button x="418" y="468" label="Button"/>

</mx:Application>

The SortableTileList.as:

package it.creativesource
{
	import flash.events.MouseEvent;

	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.collections.Sort;
	import mx.collections.SortField;
	import mx.controls.TileList;
	import mx.events.CollectionEvent;

	public class SortableTileList extends TileList
	{
		[Bindable]
		private var _header:ArrayCollection=new ArrayCollection();
		[Bindable]
		private var _fields:ICollectionView=new ArrayCollection();
		private var _currentSort:Sort=new Sort();

		public function SortableTileList(){
			super();
			_fields.enableAutoUpdate();

		}

		override protected function createChildren():void{
			super.createChildren();
			this.y+=22;
			this.height-=22;
		}

		public function set sortableFields(fields:ArrayCollection):void{

			_header=new ArrayCollection();
			_fields=fields
			if(!_fields.hasEventListener(CollectionEvent.COLLECTION_CHANGE))
				_fields.addEventListener(CollectionEvent.COLLECTION_CHANGE,createBtn);

		}

		private function createBtn(e:CollectionEvent=null):void{
			for(var i:int=0;i<_header.length;i++){
				try{
					removeChild(_header.getItemAt(i) as SortBtn);
				}catch(e:*){}

			}

			_header=new ArrayCollection()

			for(i=0;i<_fields.length;i++){
				if(!(_fields[i] is SortObject)){

					throw new Error("Fields must be SortObject");

				}

				var b:SortBtn=new SortBtn();
				b.label=_fields[i].label;
				b.field=_fields[i].field;
				b.styleName="SortBtn";
				b.isNumeric=_fields[i].isNumeric;
				addChild(b);
				_header.addItem(b)
			}

		}

		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{ 

			super.updateDisplayList(unscaledWidth,unscaledHeight);

			for(var i:int=0;i<_header.length;i++){

				var b:Object=_header.getItemAt(i);
				b.x=this.width/_header.length*i
				b.y=-22;
				b.width=this.width/_header.length;
				b.height=22;
				b.buttonMode=true;
				b.addEventListener(MouseEvent.CLICK,handleDownSortBtn)

			}

		}

		private function handleDownSortBtn(e:MouseEvent=null):void{
			try{
				if(_currentSort.fields[0].name==e.target.field){
					var desc:Boolean=!_currentSort.fields[0].descending

				}
			}catch(e:*){
				desc=false;
			}

			_currentSort = new Sort();
     		_currentSort.fields = [new SortField(e.target.field,true,desc,e.target.isNumeric)];
     		sortIt(_currentSort)

     	  	for(var i:int=0;i<_header.length;i++){
     			var b:Object=_header.getItemAt(i);
     			if(b!=e.target){
     				b.restoreDefault();
     			}
     		}

		}

		public function set sortStyleName(value:Object):void{
			for(var i:int=0;i<_header.length;i++){
     			var b:Object=_header.getItemAt(i);
     			b.styleName=value;
     		}

		}

		private function sortIt(sort:Sort):void{

			dataProvider.sort = sort;

     		dataProvider.refresh();

		}

	}
}

The SortObject.as:

package it.creativesource
{

	public class SortObject
	{
		public function SortObject(field:String){
			this.field=field
		}
		public var label:String="";
		public var field:String="";
		public var isNumeric:Boolean=false;
	}
}

The SortBtn.as:

package it.creativesource
{
	import flash.events.MouseEvent;

	import mx.controls.Button;
	import mx.controls.Image;

	public class SortBtn extends Button
	{
		public function SortBtn()
		{
			super();
			arrow.source=arrowImage;

		}
		[Embed(source="assets/arrow.swf" , symbol="arrow" )]

        [Bindable]
        public var arrowImage:Class;
		private var arrow:Image=new Image();
		private var _isDown:Boolean=false;

		override protected function createChildren():void{

			super.createChildren();
			addChild(arrow);
			arrow.alpha=.5;
			arrow.visible=false;

		}

		override protected function mouseDownHandler(event:MouseEvent):void{
			super.mouseDownHandler(event);
			_isDown=true

		}
		public function restoreDefault():void{

			arrow.rotation=0
			arrow.visible=false
		}

		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth,unscaledHeight)
			if(_isDown){
				arrow.visible=true;
				swapChildren(arrow,this.getChildAt(this.numChildren-2));
				arrow.alpha=.2
				_isDown=false;
				arrow.rotation+=180

			}else{
				swapChildren(arrow,this.getChildAt(this.numChildren-3));
				arrow.alpha=.5
			}
			arrow.width=10;
			arrow.height=7;
			arrow.x=this.width-13;
			arrow.y=10;
		}
		public var field:String="";
		public var isNumeric:Boolean=false;
	}
}

The DisplayItem.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"  borderStyle="solid" height="124" width="99">

	<mx:Label x="10" y="11" text="Field1"/>
	<mx:Text x="55" y="11" text="{data.field1}" width="35" height="18"/>

	<mx:Label x="10" y="37" text="Field2"/>
	<mx:Text x="56" y="37" text="{data.field2}" width="35" height="18"/>

	<mx:Label x="10" y="63" text="Field3"/>
	<mx:Text x="56" y="63" text="{data.field3}" width="35" height="18"/>

</mx:Canvas>