Guys I've a grid view in flex,
one of the columns is rendered like this:
<mx:DataGridColumn headerText="Cancel" >
<mx:itemRenderer>
<fx:Component>
<mx:Box width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
<mx:Button label="Download" width="100%" >
<mx:click>someFunction();</mx:click>
</mx:Button>
</mx:Box>
</fx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
now I've a problem that the function in button click is not being recognized. It says "call to a possibly undefined function" even though it was defined. What is wrong with this? How do i make a button in a grid call a function in the same mxml file??
thanks
Your itemRenderer is considered its own encapsulated component so it's looking for someFunction() within the itemRenderer itself. To call a function you have defined in the mxml file that contains your DataGrid, try calling the function using outerDocument.someFunction();.
If you would like to define the function at the itemRenderer level, you could do something like this:
<mx:itemRenderer>
<fx:Component>
<mx:VBox>
<fx:Script>
<![CDATA[
public function someFunction():void
{
// Do Something
}
]]>
</fx:Script>
<mx:Button click="someFunction();"/>
</mx:VBox>
</fx:Component>
</mx:itemRenderer>
Related
I'm loading some images from a database using a PHP script through CodeIgniter, but when I try to add an event handler to do some stuff with these images, Flex compiler is showing me an error:
1180: Call to a possibly undefined method cloneCar.
Why I can not add an event handler in this context?
<mx:Accordion>
<mx:Form id="menu5" label="Prueba" width="100%" height="100%" backgroundColor="#707070" icon="{roadIcon}">
<mx:DataGrid x="251" y="95" dataProvider="{traffic_signals.lastResult..signal}"
showHeaders="false"
horizontalGridLines="false"
selectionColor="#707070"
themeColor="#707070"
alternatingItemColors="[#707070, #707070]"
borderColor="#707070"
rollOverColor="#707070">
<mx:columns>
<mx:DataGridColumn dataField="source" >
<mx:itemRenderer >
<mx:Component >
<mx:Image width="94" height="94" mouseDown="cloneCar(event)"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:Form>
</mx:Accordion>
Without mouseDown sentence, everything works fine, but I need to allow drag 'n' drop (and other features) with these images.
Thanks!
EDIT:
cloneCar method defined like this:
private function cloneCar(e:MouseEvent):void
{
// do stuff
}
I solved my own problem. As 'awq' said, ItemRenderer scope is independent of global scope, so I need to declare my event handler function as public and link to it in mouseDown event using outerDocument directive:
public function cloneCar(e:MouseEvent):void
{
// do stuff
}
....
<mx:itemRenderer >
<mx:Component >
<mx:Image width="94" height="94" mouseDown="outerDocument.cloneCar(event)"/>
</mx:Component>
</mx:itemRenderer>
I have a TextArea inside an itemEditor component, the problem is that when typing in the TextArea if the enter key is pressed the itemEditor resets itself rather moving the caret to the next line as expected:
<mx:List width="100%" editable="true" >
<mx:dataProvider>
<mx:ArrayCollection>
<mx:Array>
<mx:Object title="Stairway to Heaven" />
</mx:Array>
</mx:ArrayCollection>
</mx:dataProvider>
<mx:itemRenderer>
<mx:Component>
<mx:Text height="100" text="{data.title}"/>
</mx:Component>
</mx:itemRenderer>
<mx:itemEditor>
<mx:Component>
<mx:TextArea height="100" text="{data.title}"/>
</mx:Component>
</mx:itemEditor>
</mx:List>
</mx:Application>
Could anyone advise how I can get around this strange behaviour and make the enter key behave as expected?
Thanks,
Chris
The trick is to listen for the ITEM_EDIT_END event and prevent the default list behaviour if the reason is NEW_ROW. See example below:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="onComplete();">
<mx:Script><![CDATA[
import mx.events.ListEvent;
import mx.events.ListEventReason;
import mx.controls.TextArea;
private function onComplete():void
{
list.addEventListener(ListEvent.ITEM_EDIT_END, onEndEdit);
}
private function onEndEdit(e:ListEvent):void
{
if (e.reason == ListEventReason.NEW_ROW)
e.preventDefault();
else
list.editedItemRenderer.data.title = TextArea(e.currentTarget.itemEditorInstance).text;
}
]]></mx:Script>
<mx:List width="100%" editable="true" id="list">
<mx:dataProvider>
<mx:Object title="Stairway to Heaven" />
</mx:dataProvider>
<mx:itemRenderer>
<mx:Component>
<mx:Text height="100" text="{data.title}"/>
</mx:Component>
</mx:itemRenderer>
<mx:itemEditor>
<mx:Component>
<mx:TextArea height="100" text="{data.title}"/>
</mx:Component>
</mx:itemEditor>
</mx:List>
</mx:Application>
Looks like the keypress of [enter] is being handled by your lists default function rather than your item renderers. Not sure what the exact code to fix that is, but I would think you would need to extend the list control that would nix the function when the user presses [enter]
Think you can use the "editorUsesEnterKey" of List.as (line 544 Flex3.5)
A flag that indicates whether the item editor uses Enter key.
I have a <mx:Script> on the main file, where I define this:
[Bindable]
private var dpCols:ArrayCollection = new ArrayCollection([
{'prx':'bl', 'nmb':'Blanco', 'ral':'RAL1013', 'hex':'E8E4CD'},
{'prx':'am', 'nmb':'Amarillo', 'ral':'RAL1005', 'hex':'C79E03'},
{'prx':'gr', 'nmb':'Gris Perla', 'ral':'RAL7045', 'hex':'8E939E'}
]);
I can use it as a dataProvider in many places, but not here:
<mx:TileList dataProvider="{dpCols}">
<mx:itemRenderer>
<mx:Component>
<mx:Box backgroundColor="{int('0x' + data.hex)}"
height="64" width="72">
<mx:Label text="{data.ral}" textAlign="center" width="100%"/>
<mx:Label text="{data.nmb}" textAlign="center" width="100%"/>
</mx:Box>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
This TileList is within a <radg:RaDG> (my subclass for AdvancedDataGrid), <radg:columns>, <mx:AdvancedDataGridColumn>, <mx:itemEditor> and <mx:Component>. If I put it outside, it just works. But I need it to put it has the itemEditor.
How should I refer to dpCols then? (or how can I solve this error?)
Thanks!
You need outerDocument, since you're inside the <mx:Component> tag. See the "Using the Component Tag" section in this Adobe docs page or this SO question.
If you're getting particularly tricky with nesting, you may need to use parentDocument instead, but it sounds like outerDocument should work in your case (only one nesting of <mx:Component> tags).
Usage:
<mx:TileList dataProvider="{outerDocument.dpCols}" />
I used play button image within datagrid item renderer, if I click image then move to another state (by using currentState ='play'). So I tried like:
<mx:DataGridColumn textAlign="center" headerText="" dataField="col2">
<mx:itemRenderer>
<mx:Component>
<mx:HBox textAlign="center" paddingLeft="17">
<mx:Image source="#Embed(source='image/play_button.png')" click="currentState='Playsystem'"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
But it shows error like undefined state 'Playsystem'. But Already I have state. What did I wrong? Why error shows like this?
You are getting this error because currentState is not a defined property of Component.
You need to change click="currentState='Playsystem'" to click="this.parent.parent.parent['currentState'] = 'Playsystem'"
as in:
<mx:DataGrid bottom="0" top="37" left="0" dataProvider="{dataAry}" width="340">
<mx:columns>
<mx:DataGridColumn textAlign="center" headerText="" dataField="col2">
<mx:itemRenderer>
<mx:Component>
<mx:HBox textAlign="center" paddingLeft="17">
<mx:Image source="#Embed(source='125x125.gif')" click="this.parent.parent.parent['currentState'] = 'Playsystem'"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
But I wouldn't do that way. It's kinda hacky. What I recommend is actual write a class for the component and have it listen and dispatch the click event to the container. More info
I have 3 checkboxes for calculating amount purpose. I used Datagrid within datgrid used
<mx:DataGrid>
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox id=mycheckbox change="calc()"/>
</mx:Component>
</mx:itemRenderer>
...
public function calc():void
{
statistic.dataProvider = mycheckbox.selectedItem;
}
but it's throws error like Call to possibly undfined method (calc)
You can't give the checkbox an id the way you have done and expect it to behave as a single component.
When you specify the checkbox as an item renderer for a column you are not talking about a single checkbox.
You will be dealing with as many check boxes as there are rows in the datagrid.
The following example shows you how to determine if the checkbox in a particular row is selected or not
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
private var ac:ArrayCollection=new ArrayCollection([
{name: "John", test: true},
{name: "Joe", test: false}]);
private function init() {
dg.dataProvider=ac;
}
public function check():void {
var obj:Object=dg.selectedItem;
Alert.show("Checkbox=" + obj.test);
}
]]>
</mx:Script>
<mx:DataGrid id="dg"
dataProvider="{ac}"
click="check()">
<mx:columns>
<mx:DataGridColumn dataField="name">
</mx:DataGridColumn>
<mx:DataGridColumn>
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox label="Test"
selected="{data.test}"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Sometimes flex seems to have trouble updating the data provider for the datagrid when you have a nested itemrenderer. You can explicitly set the appropriate property of the dataprovider row when the change event occurs on the checkbox as below;
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox label="Test" selected="{data.test}"
change="data.test=selected"/>
</mx:Component>
</mx:itemRenderer>
A checkbox does not have a "selectedItem" function or property...
mycheckbox.selected will return true or false based on whether or not sed checkbox is checked
Not really sure what you're trying to accomplish by setting a dataprovider to true or false, seems to me like you want to use a RadioButtonGroup
use outerDocument.functionname inside itemrenderer, and set the function as public. This is a limitation of Flex, Hierarchy mismanagement.