How do I set the dataProvider for an <s:List> component to be an XML file? - actionscript-3

I've got the latest Beta of Adobe Flash Builder 4.
I want to use a <s:List> component, and specify the dataProvider as being an XML file.
However, after loads of research (including looking at doc links off labs.adobe.com), I still can't figure out how to do it.
The XML file will look something like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<imageList>
<image location="path/to/file1.jpg" />
<image location="path/to/file2.jpg" />
<image location="path/to/file3.jpg" />
</imageList>

if you want to display images in a list, you should load the xml with a URLLoader , store it in a bindable variable and assign that as data provider to your list. the list should use a mx:itemrenderer where you can customize your view as you wish.
Actual code goes someting like this
<fx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.collections.IList;
import mx.controls.Image;
private var loader : URLLoader = new URLLoader();
[Bindable]
private var xml : XMLList;
private function init() : void
{
this.loader.addEventListener(Event.COMPLETE, onComplete);
this.loader.load(new URLRequest("data.xml"));
}
private function onComplete(evt : Event) :void
{
this.loader.removeEventListener(Event.COMPLETE, onComplete);
this.xml = new XML(this.loader.data).image;
}
]]>
</fx:Script>
<mx:List id="list" width="200" height="500" dataProvider="{xml}">
<mx:itemRenderer>
<fx:Component>
<mx:Image width="200" height="200" source="{data.#location}" />
</fx:Component>
</mx:itemRenderer>
</mx:List>

If you want to load the XML file over the network you can do:
<?xml version="1.0" encoding="utf-8"?>
<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/halo">
<fx:Declarations>
<mx:HTTPService id="srv" url="http://ws.jamesward.com/images.xml"/>
</fx:Declarations>
<s:applicationComplete>
srv.send();
</s:applicationComplete>
<s:List dataProvider="{srv.lastResult.images.image}" width="100%" height="100%">
<s:itemRenderer>
<fx:Component>
<mx:Image source="{data.source}"/>
</fx:Component>
</s:itemRenderer>
</s:List>
</s:Application>

You need to use the XMLListCollection class.
<s:List dataProvider="{new XMLListCollection(data.image)}" labelField="#location"/>

My original aim was to have an XML file external to the SWF that my client could maintain themselves, and thus they would have control over the images displayed.
The first answer I posted was not quite the solution I was after: using fx:XML means that the contents of the XML file is actually compiled into the SWF, and hence is not alterable after compilation.
So I've implemented James' solution.
The XML file looks like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<images>
<image source="path/to/image1.jpg" />
<image source="path/to/image2.jpg" />
<image source="path/to/image3.jpg" />
<image source="path/to/image4.jpg" />
</images>
MXML:
<?xml version="1.0" encoding="utf-8"?>
<s:Group
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function lstImages_creationCompleteHandler(event : FlexEvent) : void
{
dpHttpService.send();
}
]]>
</fx:Script>
<fx:Declarations>
<mx:HTTPService
id="dpHttpService"
url="images.xml"
/>
</fx:Declarations>
<s:List
id="lstImages"
dataProvider="{dpHttpService.lastResult.images.image}"
width="100%"
itemRenderer="path.to.render.ImageRenderer"
skinClass="path.to.skins.ListSkin"
>
<s:layout>
<s:HorizontalLayout gap="2" />
</s:layout>
</s:List>
</s:Group>
And in the image renderer, I refer to the data like this:
<mx:Image
id="imgRendered"
source="{data.source}"
/>
The really useful thing about this solution is that I can also put full http:// references to images that exist on another site if I want to (remembering crossdomain.xml, of course).
In fact, the images.xml file can exist on another server.

Well, I found one solution.
The MXML will look like this:
<fx:Declarations>
<fx:XML
id="dpXml"
source="path/to/images.xml"
/>
<mx:XMLListCollection
id="dpXmlListCollection"
source="{dpXml.image}"
/>
</fx:Declarations>
<s:List
id="lstImages"
dataProvider="{dpXmlListCollection}"
itemRenderer="path.to.render.ImageRenderer"
skinClass="path.to.skins.ListSkin"
>
<s:layout>
<s:HorizontalLayout gap="2" />
</s:layout>
</s:List>
And images.xml like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<images>
<image>
<location>path/to/image1.jpg</location>
</image>
<image>
<location>path/to/image2.jpg</location>
</image>
<image>
<location>path/to/image3.jpg</location>
</image>
</images>
Many thanks for all your responses!
Matt

Related

Adobe AIR, External swf file when loaded from swf does not render properly

I was trying to create an Adobe AIR application that loads an external swf file. However when the swf file is loaded from it does not render properly.
My Main.mxml file:
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%" height="100%" paddingLeft="0" paddingBottom="0" paddingRight="0" paddingTop="0"
creationComplete="Created()">
<fx:Script><![CDATA[
private var moduleLoader:Loader;
private function Created():void {
moduleLoader = new Loader();
var urlre: URLRequest = new URLRequest("Shell1.swf"); //http://localhost:8080/aps/
moduleLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
moduleLoader.load(urlre);
}
private function loaded(event:Event):void {
uic.addChild(moduleLoader);
}
]]></fx:Script>
<mx:UIComponent id="uic" width="100%" height="100%" ></mx:UIComponent>
</mx:Application>
My Shell1.mxml file:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%" height="100%" creationComplete="Created(event)"
backgroundColor="0xf5deb3">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
private function Created(event:Event):void {
}
]]>
</fx:Script>
<fx:Declarations>
<mx:RemoteObject id="RO" destination="AdministrationHandler"
fault="Alert.show(event.fault.faultString), 'Error'">
</mx:RemoteObject>
</fx:Declarations>
<s:Group id="Group" width="100%" height="100%">
<s:Label id="Introduction"
text="This is a demo application to show that the flex based application works. Click on the button below get generate a random number"
styleName="FilterLabel"/>
<s:VGroup id="VertGroup" paddingLeft="10" paddingRight="10" paddingTop="10" width="100%" height="100%">
<s:Label backgroundColor="green" width="1000" id="firstNumberLabel" text="Enter First Number"
styleName="FilterLabel"/>
<s:TextInput id="firstNumber" width="20%"/>
</s:VGroup>
</s:Group>
</s:Application>
When Shell1.swf is loaded directly in adobe air (by mentioning it application-descriptor.xml), it looks like:
But when I load it by using Main.mxml it looks like this:
So why is that the Components are not properly rendered when Shell1.swf is loaded from Main.swf ?

Why does this non-descriptive error happen when I try to build this mxml file?

I get the following error when trying to build a simple MXML file:
Build halted with errors (fcsh).
Here is the MXML:
<?xml version="1.0" encoding="utf-8"?>
<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">
<s:Label id="titleLabel" x="50" y="50" fontFamily="Arial" fontWeight="bold" text="My first Flex 4 application"/>
<fx:Script>
<![CDATA[
public function example() {
speakTextInput.text = "This is an example of horrible code!";
}
]]>
</fx:Script>
<s:HGroup x="50" y="70" width="80%">
<s:Button id="speakButton" label="Say Something!" />
<s:TextInput id="speakTextInput" width="100%" text="" />
</s:HGroup>
</s:Application>
Maybe your compiler doesn't like functions without type declaration for return value. Try change to:
public function example():void

How to access the swfcontrols from one mxml to other mxml

Hai i have SwfControl in page1.mxml,i need to hide and show that control...In page1 i hide that control and page 2 i need to show that control how to do?
Note page1.mxml is main page
page1.mxml
<?xml version="1.0" encoding="utf-8"?>
<local:WindowsControl xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:local="*"
height="100%" width="100%"
backgroundColor="#FFFFFF"
backgroundAlpha="0">
<mx:HBox x="11" y="167" horizontalGap="0">
</mx:HBox>
<mx:SWFLoader id="loader" source="loading.swf" visible="false"/>
</local:WindowsControl>
i need to hide the SWFloader in page1.mxml and show the SWFloader in page2.mxml
page2
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" creationComplete="init()" width="164" height="150" cornerRadius="3">
<mx:Script>
<![CDATA[
import flash.media.Microphone;
import flash.media.Video;
public function init():void
{
loader.visible=true;
}
]]>
</mx:Script>
<mx:VBox height="100%" width="100%" horizontalAlign="center" backgroundColor="#000000" >
<VideoContainer id="vids" opaqueBackground="true" width="160" height="120" />
</mx:VBox>
</mx:Canvas>
The right way to do this is by dispatching events to parent container of page1 and page2.
The parent container will relay the message/action to the target page. Your event will contain info of what is supposed to happen.

Editable column's value not getting 'persisted' in AdvancedDataGrid

I have an AdvancedDataGrid (whose dataProvider is a variable being bound from my main mxml file, not sure if this is relevant to my problem ). I'm setting one of the AdvancedDataGridColumn's editable property as true, and when I click on the cell in the UI, it is infact editable. But when I press enter/move to a different cell, the old value returns and the newly entered value is lost. Would anyone have any ideas why that's happening? Do I have to manually change the variable provided in the dataProvider?...I would think that would happen automatically right? I'd appreciate any help!
Thanks.
This traces out correct when I edit a field and press enter then click on the button to see trace output:
<?xml version="1.0" encoding="utf-8"?>
<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" minWidth="955" minHeight="600" applicationComplete="init()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.HierarchicalData;
[Bindable]
private var companyHierarchy:HierarchicalData;
private var companyData:XML = <data>
<company name="Employees">
<department name="Unit 1">
<employee name="Dave" func="C# Developer"/>
<employee name="Bob" func="AS3 Developer"/>
<employee name="Clair" func="AS3 Architect"/>
</department>
<department name="Unit 2">
<employee name="John" func="ORACLE Developer"/>
<employee name="Sandra" func="HTML Developer"/>
</department>
</company>
</data>;
private function init():void
{
companyHierarchy = new HierarchicalData(companyData.company);
}
private function checkSetData():void
{
trace(companyData);
}
]]>
</fx:Script>
<mx:AdvancedDataGrid id="test" width="500" height="500" dataProvider="{companyHierarchy}"
displayItemsExpanded="true" editable="true" enabled="true">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="#name"
headerText="Companies"/>
<mx:AdvancedDataGridColumn dataField="#func"
headerText="Function"/>
</mx:columns>
</mx:AdvancedDataGrid>
<s:Button x="205" y="508" label="Button" click="checkSetData()"/>
</s:Application>

pass data from popup to parent

I have a parent w/ a popup child. When parent loads, I have to call a function within the popup without showing the popup (thus, I load "pupLove" but don't include it in layout)....I then pass this data to the parent. When the user manually clicks another button to open the popup, the same function is called & data passed to the parent. However, I am not able to pass dg.length to the parent. I believe the root problem is that I am loading "pupLove" & thus the parents are getting confused.....I'm guessing if I get rid of "pupLove" I can pass the data correctly but will need to call the child's function at creationComplete of the parent....how do I do that?
Here's my parent:
<?xml version="1.0" encoding="utf-8"?>
<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"
backgroundColor="green" width="50%" height="100%"
xmlns:local="*"
>
<fx:Script>
<![CDATA[
import pup;
import mx.managers.PopUpManager;
public function showPup(evt:MouseEvent):void {
var ttlWndw:pup = PopUpManager.createPopUp(this, pup, true) as pup;
PopUpManager.centerPopUp(ttlWndw);
}
]]>
</fx:Script>
<mx:VBox>
<local:pup id="pupLove" visible="false" includeInLayout="false" />
<s:Button click="showPup(event);" label="launch Pup" />
<mx:Text id="Ptest" color="black" text="from Parent:{pupLove.dg.length}" />
</mx:VBox>
</s:Application>
And a popup child called 'pup.mxml':
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
<![CDATA[
public function init():void{
// send php call
}
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private function removePup(evt:Event):void {
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="dg">
</s:ArrayCollection>
</fx:Declarations>
<s:TitleWindow width="100%" height="100%" close="removePup(event)">
<mx:VBox>
<mx:Text id="test" color="red" text="from Child:{dg.length}" />
<s:Button label="add Items" click="dg.addItem({id:'cat'})" />
</mx:VBox>
</s:TitleWindow>
</s:Group>
UPDATE: I guess my question can be more easily stated as: "is there a way to call a child's function from the parent without actually loading the child?"
Well, if in your child's function, you don't need to access any of its UI component, then you could instanciate the child in the parent view and call the method.
When you need to display the popup afterwhile, use the PopupManager addPopup method with this existing instance instead of using createPopup