• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 860
  • Last Modified:

Struggling filtering an XMLList from another XMLList (Actionscript 3.0)

Hi,

I'm trying to build something of a document library at work.  There will probably be two main filters (insurance class and type of document) which I'd like users to be able to select to filter the list of documents.

I've been trying to have two list boxes at the top interact using XMLLists and DataProviders.  Something very similar in fact to the Adobe Video Workshop - the way they have the two selections above the list of videos.  

I've enclosed the code below of where I'm upto.  I can get it to display both lists (XML at the bottom), but I'd like to be able to say click on Property and have the second list reflect only document types applicable to Property.

On my stage i have the businessDP and typeDP lists.  

Hope this makes sense, if I need to post anymore I will!

Thanks,
John  
import fl.data.DataProvider;
 
var selectedBusiness:Object = new Object();
var selectedType:Object = new Object();
var businesses:XMLList = new XMLList();
var types:XMLList = new XMLList();
 
var businessDP:DataProvider = new DataProvider();
business.dataProvider = businessDP;
business.addEventListener(Event.CHANGE, changeBusiness);
 
var typeDP:DataProvider = new DataProvider();
type.dataProvider = typeDP;
type.addEventListener(Event.CHANGE, changeType);
 
function changeBusiness(event:Object):void {
	selectedBusiness = business.selectedItem;
} 	
 
function changeType(event:Object):void {
	selectedType = type.selectedItem;
} 	
 
// load the XML file
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("assets/SampleDocLibrary.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, myXMLLoadedHandler);
 
function myXMLLoadedHandler(eventObj:Event):void {
	var businessXML = new XML(eventObj.currentTarget.data);
	businesses = businessXML.children()[0].children();	
	
	var typesXML = new XML(eventObj.currentTarget.data);
	types = typesXML.children()[1].children();	
	
	setBusinesses();
	setTypes();
	//typeText.text = typesXML.children().children()[6];
}
 
function setBusinesses():void {
	var i:int = 0;
	for each(var prop:XML in businesses) {
		var businessData:XML = prop;
		businessDP.addItem( { label:businessData.@label, data:businessData.@data } );
		i++;
	}	
	selectedBusiness = business.dataProvider.getItemAt(0);
}
 
function setTypes():void {
	var i:int = 0;
	for each(var prop:XML in types) {
		var typeData:XML = prop;
		typeDP.addItem( { label:typeData.@name, data:typeData.@code } );
		i++;
	}	
	selectedType = type.dataProvider.getItemAt(0);
}
 
 
<!---------------------------------------- XML ---------------------------------------->
 
<dataset>
	<businesses>
		<business label="Property" data="prop"/>
		<business label="Liability" data="liab"/>
		<business label="Household" data="hous"/>
		<business label="Motor" data="moto"/>
		<business label="ProFin" data="prof"/>
		<business label="Marine" data="mari"/>
	</businesses>
	<types>
		<type name="British Standard" code="bs" lob="prop"/>
		<type name="Guide" code="gd" lob="liab"/>
	</types>
</dataset>

Open in new window

0
RSA_KM_TEAM
Asked:
RSA_KM_TEAM
  • 2
  • 2
1 Solution
 
OlaMuldalCommented:
You can filter directly from your XML data with E4X, and apply it to the DataProvider for the buisnessList.

Examples

I wrote some code loosely based on your sample. Create a new ActionScript 3 document and drag the List component into the library, then paste this code in the first frame.

import fl.data.DataProvider;
import fl.controls.List;
 
 
/**
 *	Data
 */
 
var data:XML =
<dataset>
	<businesses>
		<business label="Property" data="prop"/>
		<business label="Liability" data="liab"/>
		<business label="Household" data="hous"/>
		<business label="Motor" data="moto"/>
		<business label="ProFin" data="prof"/>
		<business label="Marine" data="mari"/>
	</businesses>
	<types>
		<type name="British Standard" code="bs" lob="prop"/>
		<type name="Guide" code="gd" lob="liab"/>
	</types>
</dataset>;
 
 
/**
 *	Setup List controls
 */
 
var typeList:List = createList();
var buisnessList:List = createList();
 
typeList.x = 10;
buisnessList.x = 220;
typeList.y = buisnessList.y = 10;
 
function createList():List {
	var list:List = new List();
	list.width = 200;
	list.height = 300;
	addChild(list);
	return list;
}
 
typeList.labelField = "name";
buisnessList.labelField = "label";
 
typeList.addEventListener(MouseEvent.CLICK, filterBuisness);
 
 
/**
 *	Integrate data providers
 */
 
typeList.dataProvider = new DataProvider(data.types[0]);
 
function filterBuisness(event:MouseEvent = null):void {
	
	
	if (typeList.selectedIndex == -1) {
		
		// If no type is selected, view all businesses
		buisnessList.dataProvider = new DataProvider(data.businesses[0]);
		
	} else {
		
		// Else, filter by the lob attribute in types
		var filteredXMLList:XMLList = data.businesses[0].business.(@data == typeList.selectedItem.lob);
		
		// Make an XML object for the dataprovider
		var filteredXML:XML = XML(<data/>).setChildren(filteredXMLList);
		
		// Set the new data
		buisnessList.dataProvider = new DataProvider(filteredXML);
		
	}
}
 
// Run filter on initialization
filterBuisness();

Open in new window

0
 
RSA_KM_TEAMAuthor Commented:
Hey OlaMudal,

Thanks so much, that's really helpful.

I'm trying to keep the xml file external, it's going to be really large when finished I think, so I'm trying to take the above and apply it to an external file, but not succeeding!

I'm very new to actionscript/flash and especially with using XML within it, so apologies if there is something very basic I'm doing incorrectly!  Can you help further?

Thanks,
John
0
 
OlaMuldalCommented:
You just have to remember to set the dataprovider in filter initialization after the XML is loaded.
import fl.data.DataProvider;
import fl.controls.List;
 
 
/**
 *	Data
 */
 
var data:XML;
 
var dataLoader:URLLoader = new URLLoader();
dataLoader.addEventListener(Event.COMPLETE, onDataLoaded);
dataLoader.load(new URLRequest("data.xml"));
 
function onDataLoaded(event:Event):void {
	data = XML(dataLoader.data);
	initialize();
}
 
 
/**
 *	Setup List controls
 */
 
var typeList:List = createList();
var businessList:List = createList();
 
typeList.x = 10;
businessList.x = 220;
typeList.y = businessList.y = 10;
 
function createList():List {
	var list:List = new List();
	list.width = 200;
	list.height = 300;
	addChild(list);
	return list;
}
 
typeList.labelField = "name";
businessList.labelField = "label";
 
typeList.addEventListener(MouseEvent.CLICK, filterBusiness);
 
 
/**
 *	Integrate data providers
 */
 
function initialize():void {
	typeList.dataProvider = new DataProvider(data.types[0]);
	// Run filter on initialization
	filterBusiness();
}
 
function filterBusiness(event:MouseEvent = null):void {
	
	
	if (typeList.selectedIndex == -1) {
		
		// If no type is selected, view all businesses
		businessList.dataProvider = new DataProvider(data.businesses[0]);
		
	} else {
		
		// Else, filter by the lob attribute in types
		var filteredXMLList:XMLList = data.businesses[0].business.(@data == typeList.selectedItem.lob);
		
		// Make an XML object for the dataprovider
		var filteredXML:XML = XML(<data/>).setChildren(filteredXMLList);
		
		// Set the new data
		businessList.dataProvider = new DataProvider(filteredXML);
		
	}
}

Open in new window

0
 
RSA_KM_TEAMAuthor Commented:
That's absolutely solved my issues.

Thank you Ola.
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now