AS3: How to access data in XMLListCollection using ActionScript3? - actionscript-3

I'm using an XMLListCollection for a spark ComboBox, inspired by this link
http://blog.shortfusion.com/index.cfm/2009/4/15/FlexAS3-Custom-ComboBox-for-Countries-with-XML
The XMLListCollection is defined here:
public class ComboBox_Country extends ComboBox {
private var Country:XML=new XML(
<countries>
<country code="US" iso="840" label="United States" />
<country code="CA" iso="124" label="Canada" />
<country code="GB" iso="826" label="United Kingdom" />
....
<country code="ZM" iso="894" label="Zambia" />
<country code="ZW" iso="716" label="Zimbabwe" />
</countries>);
public function ComboBox_Country() {
dataProvider = new XMLListCollection(Country.children());
labelField = '#label';
}
and called in mxml as:
<mycomp:ComboBox_Country id="countryComboBox" width="100%"/>
When the user makes a selection, I can get the index from: countryComboBox.selectedIndex. But, I need the string for the country, and I'm not sure how to extract that from an XMLListCollection. When I look in the debugger I see:
Let's say the user selected index 2 (e.g. United Kingdom). What would I need to type into the debugger to return United Kingdom? I've tried things like:
countryComboBox.Country.getItemAt(2)
countryComboBox.Country.getItemAt(2).label
countryComboBox.Country[2]
countryComboBox.Country.label.getItemAt(2)
etc...
to no avail.

ComboBox have a property selectedItem which you probably should use. In this case selectedItem would be XML object. Read how you can get data from XML objects here.
In your case you can get label using
countryComboBox.selectedItem.#label

I'm not entirely sure you populating the combo box correctly, normally you'd use a data provider (see http://help.adobe.com/en_US/flex/using/WS70f0d54f063b9b081aac8d1d1247252e4a0-8000.html)
Assuming that is displaying the data correctly for you, then you're pretty close
// Should give you the country object selected
var obj:Object = countryComboBox.selectedItem;
// You should also be able to use .code or .iso
return obj.label;
If obj.label doesn't work, you could try obj['label'];

Related

accessing current rowData of dataprovider in flex view

I have a view
<view:SampleDataGridView
rowCount="{Math.min(MAX_ROW_COUNT, hostComponent.dataList.length)}"
dataprovider="{hostComponent.dataList}"
buttonMode="true"
click="clickRow(event)"
/>
I want to get which row was clicked. I tried using currentTarget and target from event object however it wasn't of much use.
Is there a way I can pass some parameter in clickEvent function like clickEvent(rowData) or clickEvent(currentRowIndex)?
Is there any property when we use dataProvider to show currentIndex?
Data Grid
<mx:DataGrid id="employeeDataGrid" doubleClickEnabled="true" itemDoubleClick="selectEmployee(event);" dataProvider={employeeList} >
Handler
protected function selectEmployee(event:ListEvent):void
{
var selectedEmployee:Employee = event.currentTarget.selectedItem as Employee;
}

Getting name of selected item in Tree UIComponent FLEX 4.6

This is my second day using FLEX and AS 3.0 so I am very new at this. I am trying to obtain the value of the selected item in a tree component, in this case it is just a name. Below is the tree I have created. The tree contents have been populated programmatically with an array called "cat". The tree gets populated just fine but I can't figure out how to get the name of the currently selected item.
<mx:Tree id="category_tree" x="10" y="80" width="160" height="169" showRoot="true" dataProvider="{cat}" labelField="name">
I have used the selectedItem.toString() function but this only seems to return the type of object and not the value. Currently it returns "object Object"
In my script I have...
category_tree.selectedItem.toString();
Any help on this would be greatly appreciated. Thank you in advance for your time.
You can add a change event to the tree and have use a callback similar to:
private function changeEvt(event:Event):void {
var lableData:*;
var label:String;
if (event.currentTarget.selectedItem.#data) {
labelData = event.currentTarget.selectedItem.#data;
}
label = event.currentTarget.selectedItem.#label;
}
}
or access the value directly
category_tree.selectedItem.#label;

how to link to url in service from itemclick handler mx:list

so this one has stupped me cant find a good explanation anywhere, so i have a php service which provides an array of objects in binary back to my flash application. the service is fed into an mx:list, the sevice has 4 fields countrycode, citycode, city, and url. what i need to do is to call the url for each object and feed it to this itemClickHandler this is what i have tried plus the other two others on RIAstar's answer what am i doing wrong here?,
protected function citylist_itemClickHandler(event:ListEvent):void
{
var data:City = citylist.selectedItem as City;
navigateToURL(new URLRequest(data.url));
}
this is the mx:list with getCitysResult as the objects
<mx:List includeIn="data" x="28" y="10" width="312" height="255" id="citylist" dataProvider="{getCitysResult.lastResult}" labelField="city" itemClick="citylist_itemClickHandler(event)">
</mx:List>
what i need to do is get each row of this list to have a url link for the Mouse click
The ListEvent has a property rowIndex which carries the index of the row that was just clicked. You can use this index to retrieve the correct element from the dataProvider.
var city:City = cityList.dataProvider.getItemAt(event.rowIndex) as City;
navigateToURL(new URLRequest(city.url));
or directly on the service result object (which is the same, since it's bound):
var city:City = getCitysResult.lastResult.getItemAt(event.rowIndex) as City;
(unless that lastResult object is an Array: then it would be getCitysResult.lastResult[event.rowIndex])
or (the shortest way) use the List's selectedItem property:
var city:City = cityList.selectItem as City;

Flex 4.6 Mobile - ItemRenderers and application data

A question about ItemRenderers: let's say I have an ArrayCollection that is my application data sitting inside a global object. I them populate a sparks list with this data, setting the ArrayCollection as the dataProvider.
So each ItemRenderer gets a copy of an item sitting in the array. You can override the "set data" method to set the data something more domain-specific. The problem is that the data is a copy of the original item.
Now let's say we want to add some data to the item while inside the ItemRender. For example, it could call a method on the item telling it to load some details about itself, or maybe we allow the user to modify something on the item.
Obviously, we can't do any of this if we are operating on a copy because it will be thrown away as soon as the ItemRenderer is destroyed and the original object doesn't know anything about what happened.
So what's the best practice? Should I just use the itemIndex of the renderer to pull out the original item from my global array like this:
{globalArrayCollection}.getItemAt(this.itemIndex)
But it seems kind of clunky to me. Is there a best practice for dealing with this?
Not sure I'm following but it sounds like you're looking for a way to get at your item renderer to set/change a value.
You could go about accessing a method on the renderer directly.
In your renderer:
public function setSomeValue(aValue:String):void{
someString = aValue;
}
You would also set the data on your ArrayCollection as well.
To access this method you would use this:
var dataGroup:DataGroup = list.dataGroup;
var itemRenderer:YourItemRenderer = dataGroup.getElementAt(list.selectedIndex) as YourItemRenderer;
itemRenderer.setSomeValue("string");
Hmm, why do you think that original ArrayCollection won't change if you change values in itemRenderer? For me this works and initial ArrayCollection changes.
[Bindable]
protected var model:Model;
override public function set data(value:Object):void
{
super.data = value;
this.model = value as Model;
}
protected function changeValue():void
{
model.value = "newValue";
}
Or am I misunderstood something?

Creating Dynamically Flex Custom ItemRender (Constructor)

am creating some Advanced Datagrid with actionscript.
I have created an actionscript class where I extend the VBox object:
package core
{
import mx.containers.VBox;
import mx.controls.TextInput;
public class customItemRender extends VBox
{
public function customItemRender(_TextInput:TextInput, _TextInput2:TextInput)
{
//TODO: implement function
super.addChild(_TextInput);
super.addChild(_TextInput2);
}
}
}
The problem comes up when I declare de itemrender property on the data grid:
AdvancedDataGridColumn.itemRenderer = new ClassFactory(customItemRender(_TextInput1,_TextInput2));
The compiler wont let me instanciate my customItemRender.
Does any one know if there is an alternative solution to solve the problem?
Thanks in advance for you helps,
Regards Javier
private var _ItemRendere:ClassFactory;
private function get MyItemRendere():ClassFactory
{
if (_ItemRendere == null)
{
_ItemRendere = new ClassFactory();
_ItemRendere.generator = customItemRender;
_ItemRendere.properties = {
_TextInput1:MY_TextInput1_OBJECT,
_TextInput2:MY_TextInput2_OBJECT
};
}
return _ItemRendere;
}
then you can use
AdvancedDataGridColumn.itemRenderer = MyItemRendere;
I've only tried to do this using MXML. In that case, i usually have to wrap the IListItemRenderer instance in mx:Component tags. I'm not exactly sure what is going on programmatically when I do this, but it works. The reason is that the itemRender is actually looking for an instance of IFactory rather than an instance so I suppose to do this strictly using AS you would need to create your own IFactory implementation.
e.g.
<mx:List>
<mx:itemRenderer>
<mx:Component>
<mx:Text />
</mx:Component>
</mx:itemRenderer>
</mx:List>
ClassFactory's constructor has a Class as a parameter, not an instance. You need to call:
new ClassFactory(customItemRender);
and not:
new ClassFactory(new customItemRender(_TextInput1,_TextInput2));
or:
new ClassFactory(customItemRender(_TextInput1,_TextInput2));
Now, since the constructor will not be called with reference to TextInput1 and TextInput2, you'll need to instantiate your own TextInputs in the custom renderer itself. (But this is a good thing, if you continue to call new customItemRender(_TextInput1, _TextInput2), then the two TextInputs will only be added to the LAST instance of customItemRender, and all of the others will not have these two objects ).