<mx:HTTPService id="myService" url="configure.php" method="POST">
<mx:request xmlns="">
<mode>
{modeLabel.text}
</mode>
</mx:request>
</mx:HTTPService>
<mx:Button label="Start" id="startButton" click="{myService.send()}" width="88" height="38" x="52" y="36"/>
The above code works fine i.e. the service gets started and the configure.php does it's work but instead of using click="{myService.send()}", if I use a function call (as done in following code) the service does not get started or configure.php does not perform it's work.
<mx:Script>
<![CDATA[
private function start():void
{
startButton.enabled = false;
myService.send();
}
]]>
</mx:Script>
<mx:Button label="Start" id="startButton" click="start()" width="88" height="38" x="52" y="36"/>
Any idea why the service not executing when invoked from a function?
Thanks
That should be working but you can try to remove the <mx:request> block and instead do this:
myService.send({mode: modeLabel.text});
Related
I am having an issue with my ItemRenderer, which I am using for a spark List. My code is the following:
I have this list:
<s:List
id="productSetList"
dataProvider="{ model.productSets }"
change="model.selectSet( productSetList )"
height="100%" width="100%"
borderVisible="false"
itemRenderer="SideBarItemRenderer" top="20" left="15">
</s:List>
and my itemRenderer is:
<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
width="160" height="175" autoDrawBackground="false" buttonMode="true" useHandCursor="true"
click="click(event)" cacheAsBitmap="true"
>
<fx:Script>
<![CDATA[
import com.png.vm.model.vos.ProductSet;
protected function click(event:MouseEvent):void
{
trace('arthur');
}
]]>
</fx:Script>
<s:BitmapImage source="{ProductSet(data).image}" width="160" height="175"/>
</s:ItemRenderer>
The thing is, if I scroll the list, and click on an item, it does not trace 'arthur' ! Why is this so ? I must trace that all the time that someone clicks in the list!
EDIT:
If I remove change="model.selectSet( productSetList )" in the list, it works!! but I cannot remove that, some suggestions ? How can I switch that to another function?
Trace only works when you are debugging/using the debugging version of Flash Player. Make sure you are using that. If you want a pop-up message use Alert.show("message")
For more information about trace() check out:
http://livedocs.adobe.com/flex/3/html/help.html?content=logging_08.html
And Alert.show(): http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001965.html
If you are running debug player. Try originating the click event from an embedded <s:Group> this way whatever you add in here beyond the bitmap will still trigger the click event.
Something like:
<s:Group width="100%" height="100%" click="click(event)" >
<s:BitmapImage source="{ProductSet(data).image}" width="160" height="175"/>
</s:Group>
I've definitely had click events work for me inside of ItemRenderers before
My apologies, I have finally solved it. The problem was that inside the function,model.selectSet, I was calling List.change; I was messing the list up! My function was as follows:
public function selectSet(list:List):void {
list.layout.verticalScrollPosition=100;
// another stuffs
}
So, I just removed the line : list.layout.verticalScrollPosition=100; and now it`s working fine.
Thanks for all the help!
I wonder is anyone can look at this code and tell me why calling the removeSelectedChild works when called from the same document, but returns the following error when called from the child document/component.
"ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller."
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Accordion id="myAccordion"
width="100%" height="100%"
selectedIndex="0">
<mx:Script>
<![CDATA[
public function removeSelectedChild():void {
trace("before");
try {
myAccordion.selectedChild.parent.removeChild(myAccordion.selectedChild)
} catch(err:ReferenceError) {
trace("catch")
}
trace("after");
}
]]>
</mx:Script>
<mx:headerRenderer>
<mx:Component>
<mx:Button click="{ parentDocument.removeSelectedChild() }" />
</mx:Component>
</mx:headerRenderer>
<mx:HBox>
<mx:Button click="{ removeSelectedChild() }" />
</mx:HBox>
</mx:Accordion>
</mx:Application>
Clicking on the button in the child produces the expected result, whilst clicking on the header removes the child as expected but also throws an error despite the fact they both call exactly the same method.
Sorry that the example is a little contrived, this problem arose in a quite complicated view, which was using all kinds of custom components. This was the only way I could display it in a way that will be quick for you to compile and easy to focus on the real issue without background noise.
I'm pulling my hair out on this one and would really appreciate it if anyone could help.
UPDATE: I have now discovered that the exception is fired after the method has finished executing. See the trace statements above. "after" is traced before the exception is thrown.
Cheers,
Chris
As you noted, the error is not being thrown by your function. The default action when clicking on the header of an accordion is to expand or contract that element. Since you're removing the element, when Flex tries to expand or contract it, you get an error.
You can fix it by stopping the event from doing its default action:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Accordion id="myAccordion"
width="100%" height="100%"
selectedIndex="0">
<mx:Script>
<![CDATA[
public function removeSelectedChild(event:MouseEvent):void {
myAccordion.removeChild(myAccordion.selectedChild);
event.stopImmediatePropagation();
}
]]>
</mx:Script>
<mx:headerRenderer>
<mx:Component>
<mx:Button click="{ parentDocument.removeSelectedChild(event) }" />
</mx:Component>
</mx:headerRenderer>
<mx:HBox>
<mx:Button click="{ removeSelectedChild(event) }" />
</mx:HBox>
</mx:Accordion>
</mx:Application>
Not a solution, but perhaps a workaround: could you try rewriting the method like this:
myAccordion.selectedChild.parent.removeChild(myAccordion.selectedChild)
if that doesn't work there must be a bug somewhere in Flex.
Use "outerDocument" instead of "parentDocument". defines a new mini-scope.
I'm new to Flex and am using TileList bound to an ArrayCollection. The array collection is empty at load time, and then updates with the results from am HTTPService call. The problem is that the item renderers aren't being rendered as expected, I'm guessing because there was no data when they were first rendered at load time. Here's simplified example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myList1:ArrayCollection = new ArrayCollection();
[Bindable]
public var myList2:ArrayCollection = new ArrayCollection([{item:"foo"}, {item:"bar"}]);
public function updateMyList():void
{
myList1.source = [{item:"foo"}, {item:"bar"}];
}
]]>
</mx:Script>
<mx:Button id="myButton" label="Update My List"
click="updateMyList();"/>
<mx:TileList dataProvider="{myList1}"
direction="vertical"
width="800" >
<mx:itemRenderer>
<mx:Component >
<mx:Canvas backgroundColor="yellow" >
<mx:Label text="{data.item}" width="800" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
<!-- This one renders as expected -->
<mx:TileList dataProvider="{myList2}"
direction="vertical"
width="800" >
<mx:itemRenderer>
<mx:Component >
<mx:Canvas backgroundColor="yellow" >
<mx:Label text="{data.item}" width="800" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
</mx:Application>
You will notice that the second TileList whose bindings has data at load time renders as expected (800px wide), bit the first TileList is rendered is not the correct width and has scrollbars around it.
Could anyone explain why this is happening or even provide some work arounds to avoid this?
Regards,
Chris
It's likely that this section is causing the problems:
public function updateMyList():void
{
myList1.source = [{item:"foo"}, {item:"bar"}];
}
From here:
source of data in the ArrayCollection.
The ArrayCollection object does not
represent any changes that you make
directly to the source array. Always
use the ICollectionView or IList
methods to modify the collection.
This property can be used as the
source for data binding. When this
property is modified, it dispatches
the listChanged event.
So I'd probably change the line to:
myList1= new ArrayCollection([{item:"foo"}, {item:"bar"}]);
http://livedocs.adobe.com/flex/3/langref/mx/controls/TileList.html
Check the API.
Set the columnWidth and rowHeight properties like this,
<mx:TileList dataProvider="{myList1}"
direction="vertical"
width="800" columnWidth="800" rowHeight="25">
There is probably a more "proper" way to do it, but that should get you started.
i have a data grid in my application and am pulling data from a MYSQL DB using php.
is there a way to store all that data into an array and pass it to a function or is it possible to just store the data directly into an array instead of pulling it from the datagrid
here is the code
<mx:DataGrid id="dgUserRequest" x="150" y="10" dataProvider=" {userRequest.lastResult.users.user}" editable="false">
<mx:columns>
<mx:DataGridColumn headerText="UserID" dataField="userid"/>
<mx:DataGridColumn headerText="Ip Address" dataField="ip"/>
<mx:DataGridColumn headerText="latitude" dataField="lat"/>
<mx:DataGridColumn headerText="longitude" dataField="lng"/>
</mx:columns>
</mx:DataGrid>
<mx:HTTPService id="userRequest" url="http://localhost/post.php" useProxy="false" method="POST">
<mx:request xmlns="">
</mx:request>
</mx:HTTPService>
Add a listener to the "result" event of you HTTPService and have the code in the listener function fill a locally stored array.
something like this should help
[Bindable]
public var dp:ArrayCollection;
protected function samplePhp_resultHandler(event:ResultEvent):void
{
dp = event.result as ArrayCollection;
}
<mx:HTTPService id="userRequest" url="http://localhost/post.php" useProxy="false"
method="POST" result="samplePhp_resultHandler">
<mx:request xmlns="">
Is there any reason why there isn't an addAll() function available when using ArrayCollections in Actionscript? I've been using for loops to individually add them one at a time using addItem(). Is this common or is there a more convenient way?
I can add some historical nuance to this. Apparently, Adobe heard the Flex community and has responded. An addAll(addList:IList) method has been added to the ListCollectionView type in the Flex 3.4 SDK.
But just in case there are others who may still be looking for a one-liner equivalent that works across the board, here is my one-very-long-line go at it:
var arrColl1 = new ArrayCollection(['x','y','z']);
var arrColl2 = new ArrayCollection(['a', 'b', 'c']);
// Using Flex SDK version 3.4:
arrColl1.addAll( arrColl2 );
// Using any Flex SDK:
arrColl2.source.forEach(function(item:*, i:int, arr:Array):void { arrColl1.addItem(item); }, this);
This is essentially what the Flex implementation does, and should handle binding concerns correctly, although it is not necessarily the prettiest thing to look at.
There's no reason that it isn't there, it's just not there. If you changed your code to use a plain Array instead of an ArrayCollection, you can use the Array.concat method. Otherwise, the only option is addItem in a loop.
By way of example, try dropping this into a container. Essentially, it seems that if you have to have a one liner, creating a new ArrayCollection with the source of the original plus the new data will work, at least in the case below. Attempts to manipulate the source directly don't seem terribly useful, at least for data binding purposes (and if no data binding or events are involved, its probably better to use an array anyway).
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] public var collection:ArrayCollection = new ArrayCollection([
2,6,4,6,7,8,9
]);
public function addToCollection():void {
collection.addItem(Number(collectionValue.text));
}
public function newCollectionWithAddition():void {
collection = new ArrayCollection(collection.source.concat(Number(collectionValue2.text)));
}
public function addToCollectionSource():void {
collection.source.push(Number(sourceValue));
}
public function addToCollectionSourceWithRefresh():void {
collection.source.push(Number(sourceValue2));
collection.refresh();
}
]]>
</mx:Script>
<mx:HBox width="100%">
<mx:PieChart width="300" height="300">
<mx:series>
<mx:PieSeries dataProvider="{ collection }" />
</mx:series>
</mx:PieChart>
<mx:PieChart width="300" height="300">
<mx:series>
<mx:PieSeries dataProvider="{ collection.source }" />
</mx:series>
</mx:PieChart>
</mx:HBox>
<mx:HBox>
<mx:TextInput id="collectionValue" />
<mx:Button label="Add To ArrayCollection"
click="addToCollection()"
/>
</mx:HBox>
<mx:HBox>
<mx:TextInput id="collectionValue2" />
<mx:Button label="Create New ArrayCollection with new value"
click="newCollectionWithAddition()"
/>
</mx:HBox>
<mx:HBox>
<mx:TextInput id="sourceValue" />
<mx:Button label="Add To ArrayCollection Source"
click="addToCollectionSource()"
/>
</mx:HBox>
<mx:HBox>
<mx:TextInput id="sourceValue2" />
<mx:Button label="Add To ArrayCollection Source with refresh"
click="addToCollectionSourceWithRefresh()"
/>
</mx:HBox>
After some more investigation, it turns out that an ArrayCollection is just a wrapper for an Array and that you have access to the array via arrcoll1.source. This allows you to call concat. I was able to remove my for loop and use this instead.
var arrColl1 = new ArrayCollection(['x','y','z']);
var arrColl2 = new ArrayCollection(['a', 'b', 'c']);
arrColl1.source = arColl1.source.concat(arrColl2.source);
If you are concatenating an array, for example selectedItems in a list, you can do this:
arrColl1.source = arrColl1.source.concat(seletedItems);