Latest entries » ActionScript 3.0 » Filling a ComboBox with XML data and showing the filtered result in a DataGrid (using AS3)

Filling a ComboBox with XML data and showing the filtered result in a DataGrid (using AS3)

End result:

This movie requires Flash Player 8 and JavaScript enabled.

[Update: November 9th, 2009 - I decided to define authorXMLList and bookXMLList as public var in loadingXML.as and reference them in our main class (myXML.authorXMLList, myXML.bookXMLList).]

First, we create our XML file, showing authors and books in a nested format » authors.xml:

<?xml version="1.0" encoding="UTF-8"?>
<authors>
	<author name="Kafka">
		<book title="The Metamorphosis" pages="94" />
		<book title="The Trial" pages="304" />
	</author>
	<author name="Murakami">
		<book title="Norwegian Wood" pages="298" />
		<book title="Dance Dance Dance" pages="416" />
	</author>
	<author name="Dickens">
		<book title="Great Expectations" pages="544" />
		<book title="Oliver Twist" pages="608" />
		<book title="A Christmas Carol" pages="62" />
		<book title="Hard Times" pages="448" />
	</author>
</authors>

Then we create our main document class » Main.as:

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import fl.data.DataProvider;
	import fl.controls.ComboBox;
	import fl.controls.DataGrid;
	import fl.controls.dataGridClasses.DataGridColumn;

	public class Main extends Sprite 
	{
		public static var xmlURL:String = "authors.xml";
		public static var xmlData:XML;
		
		private static var myComboBoxFirstItem:String = "Show all";
		private static var dgColumn1Text:String = "Books";
		private static var dgColumn2Text:String = "Pages";
		private static var myComboBox:ComboBox;
		private static var myDataGrid:DataGrid;
		private static var myXML:loadingXML;
		private static var dp:DataProvider;

		public function Main() 
		{
			myXML = new loadingXML();
			myXML.addEventListener("XMLLoadedAndParsedEvent", XMLLoadedHandler);
		}

		private function XMLLoadedHandler(event:Event):void 
		{
			createComboBox();
			createDataGrid();
		}

		private function createComboBox():void 
		{
			myComboBox = new ComboBox();
			myComboBox.addEventListener(Event.CHANGE, changeHandler);
			myComboBox.labelFunction = nameLabelFunction;
			myComboBox.width = 130;
			myComboBox.move(20, 10);
			fillComboBox();
			addChild(myComboBox);
			function nameLabelFunction(item:Object):String 
			{
				return item.name;
			}
		}
		
		private function fillComboBox():void {
			dp = new DataProvider();
			dp.addItem( { name:myComboBoxFirstItem } );
			for each (var prop:XML in myXML.authorXMLList) 
			{
				var authorData:XML = prop;
				dp.addItem(
					{
						name:authorData.@name
					}
				);
			}
			myComboBox.dataProvider = dp;
		}

		private function changeHandler(event:Event):void 
		{
			if (myComboBox.selectedIndex == 0) 
			{
				//show all books
				fillDataGrid();
			} 
			else 
			{
				//show books of selected author
				filterDataGrid();
			}
		}

		private function createDataGrid():void 
		{
			myDataGrid = new DataGrid();
			myDataGrid.columns = [ "title",	"pages"	];
			myDataGrid.getColumnAt(0).headerText = dgColumn1Text;
			myDataGrid.getColumnAt(1).headerText = dgColumn2Text;
			myDataGrid.getColumnAt(1).width = 50;
			myDataGrid.width = 210;
			myDataGrid.move(160, 10);
			fillDataGrid();
			addChild(myDataGrid);
		}
		
		private function fillDataGrid():void 
		{
			dp = new DataProvider();
			for each (var prop:XML in myXML.bookXMLList) 
			{
				var bookData:XML = prop;
				dp.addItem(
					{
						title:bookData.@title,
						pages:bookData.@pages
					}
				);
			}
			myDataGrid.dataProvider = dp;
			myDataGrid.rowCount = dp.length;
		}
		
		private function filterDataGrid():void 
		{
			myDataGrid.removeAll();
			var selectedAuthor = myComboBox.selectedItem.name;
			var booksCount = 0;
			for each (var author:XML in myXML.authorXMLList) 
			{
				if (author.@name == selectedAuthor) 
				{
					for each (var book:XML in author.*) 
					{
						var bookData:XML = book;
						myDataGrid.addItem(
							{
								title:bookData.@title,
								pages:bookData.@pages
							}
						);
						booksCount++;
					}
				}
			}
			myDataGrid.rowCount = booksCount;
		}
	}
}

To load and handle the XML data we create a new ActionScript file » loadingXML.as:

package
{
	import flash.events.Event;
    import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	public class loadingXML extends EventDispatcher
	{		
		public var authorXMLList:XMLList;
		public var bookXMLList:XMLList;
		private static var loadURL:URLLoader;
		private static var myXML:XML;
		
		public function loadingXML():void 
		{
			loadURL = new URLLoader();
			loadURL.addEventListener(Event.COMPLETE, dataCompleteHandler);
			loadURL.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			loadURL.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			loadURL.load(new URLRequest(Main.xmlURL));
		}

		private function dataCompleteHandler(event:Event):void
		{
			myXML = new XML(event.target.data);
			authorXMLList = new XMLList(myXML.author);
			bookXMLList = new XMLList(myXML.author.book);
			this.dispatchEvent(new Event("XMLLoadedAndParsedEvent"));
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			trace(event.text);
		}
		
		private function progressHandler(event:ProgressEvent):void
		{
			var percent:Number = (event.bytesLoaded / event.bytesTotal) * 100;
			trace("Loading..." + percent.toString(10) + "%");
		}
	}
}	

Now we create a new Flash file (ActionScript 3.0):

newflashfile

assign the document class:

mainclass

open the component window (Strg+F7) and import one ComboBox and one DataGrid, delete them from the stage. Our library should look like this:

library

save all documents in the same folder, export the swf and we’re done.

Post to Twitter Post to Facebook Post to Delicious Post to StumbleUpon

Leave a Comment