Exception on trying to change the state in Flex 3 - actionscript-3

I am trying to change the stage state to different state on click of a button. The problem is some times am getting exception as The supplied DisplayObject must be child of the caller.
Here is what am trying to do to change the state
this.currentState = 'fullScreen';
here this is a canvas.
Here is the MXML for the State fullscreen
<mx:State name="fullScreen">
<mx:RemoveChild target="{lstExpert}"/>
<mx:RemoveChild target="{screenToggle}"/>
<mx:AddChild relativeTo="{outContainer}" position="firstChild">
<mx:HBox id="topHeaderBox" horizontalAlign="left" verticalAlign="middle" width="98.5%" height="60"/>
</mx:AddChild>
<mx:AddChild relativeTo="{topHeaderBox}" position="firstChild" >
<mx:Label id="lblCourseName" width="100%" text="Name" color="#ffffff" fontFamily="Arial" fontSize="14" fontWeight="bold" height="20" />
</mx:AddChild>
<mx:AddChild target="{screenToggle}" relativeTo="{lblCourseName}" position="after" />
<mx:AddChild relativeTo="message" position="before">
<mx:Spacer id="Bar" height="5" width="2" />
</mx:AddChild>
</state>
What would be the mistake here?

You might want to bind the relativeTo property value of the last AddChild object. Meaning, to write it like this:
<mx:AddChild relativeTo="{message}" position="before">
Assuming you have an element with that id.
Hope this helps.

Related

as3 tilelist with custom itemrender add to selectedIndices

I create a TileList with custom renderer.
<s:BorderContainer
id="bcImage"
width="120"
height="99%"
borderVisible="true"
borderStyle="solid"
borderColor="#B3B3B3"
borderWeight="1"
cornerRadius="2"
backgroundAlpha=".8"
backgroundColor="#F8F8FF"
dropShadowVisible="true"
>
<mx:Canvas id="cvsImage" width="100%" click="cvsImage_clickHandler(event)">
<s:HGroup width="100%" paddingBottom="0" paddingTop="5" >
<s:CheckBox id="cbImgSelect"/>
<s:Label x="23" y="3" width="82" fontSize="11" fontWeight="normal" text="{data.imDate}"
textAlign="right" color="#000000"/>
</s:HGroup>
<mx:Image id="iconCanvas" x="10" y="20" width="99" height="99" horizontalAlign="center"
maintainAspectRatio="true" scaleContent="true"
verticalAlign="middle" mouseDown="iconCanvas_mouseDownHandler(event)"
>
</mx:Image>
</mx:Canvas>
<s:BorderContainer width="100%" y="124" height="25" bottom="1" left="3" right="3"
backgroundColor="#FFFFFF" id="bcTitre" borderAlpha="0" >
<s:VGroup width="100%" y="124" height="25" bottom="0" left="0" right="0"
paddingBottom="0" paddingTop="0" gap="0" click="iconCanvasLabel_mouseUp(event)">
<s:Label text="{data.imType}" height="50%" fontSize="10" paddingBottom="1" id="lType"
fontWeight="normal" width="99%" textAlign="center" toolTip="{data.imType}"/>
<s:Label text="{data.imStade}" fontSize="10" textAlign="center" paddingTop="1"
fontWeight="normal" width="99%" id="lStade" toolTip="{data.imStade}"/>
</s:VGroup>
</s:BorderContainer>
</s:BorderContainer>
My TileList has allowMultipleSelection enable.
I'd to check CheckBox when item is selected by click or by selection (continus or not) and if CheckBox.selected=true I'd like to show color selection around selected item.
Could you help me to do that ?
Best regards
It seems that you're trying to resolve the issue from opposite side, which is wrong
I suppose yo can consider following way:
set mouseEnabled to false for checkBox so that all the list item triggers click
alter default selection behaviour by intercepting changing event and doing something like
protected function lst_changingHandler(evt:IndexChangeEvent):void {
evt.preventDefault();
var ids:Vector.<int> = (evt.currentTarget as List).selectedIndices;
(evt.currentTarget as List).selectedIndices = ids.concat(new <int>[evt.newIndex]);
bind checkBox selected state to the renderer selected one

Flex 4.x accordion items child unknown in actionscript

I have an Accordion component in Flex that has two children,
at the load of my page, I want to give the textvalue of a textfield in the first children to a textfield in the second children by using actionscript, but its faild
nb : when I click the secode children and I return to pass the textvalue from the first children, the action succeed!
<mx:HBox width="100%" height="310" horizontalAlign="center">
<mx:Accordion id="accordion1" width="100%" height="310" historyManagementEnabled="true">
<!-- child 1--><mx:VBox id="theme_resultat" width="95%" height="95%"
label="Résultat" horizontalAlign="center"
verticalAlign="middle">
<s:HGroup left="0" right="0" bottom="0" width="98%"
horizontalAlign="right">
<s:TextInput id="doc"/>
<mx:Button id="btnAdd" label="Add"
click="add_text(event)"
icon="#Embed('assets/images/add.png')"
paddingLeft="3" paddingRight="3"/>
</s:HGroup>
</mx:VBox>
<!-- child 2--><mx:VBox id="theme_detail" width="95%" height="95%" label="Détail"
verticalAlign="middle">
<mx:VBox width="100%" height="150" horizontalAlign="center">
<s:HGroup>
<mx:FormItem label="Titre:" paddingLeft="5">
<mx:TextInput id="doc_titre"/>
</mx:FormItem>
</s:HGroup>
</mx:VBox>
</mx:VBox>
</mx:Accordion>
</mx:HBox>
protected function add_text(event:MouseEvent):void
{
accordion1.selectedIndex=1;
doc_titre.text = doc.text;
}
}
when I click add I move to the second child, but the (mx:TextInput id="doc_titre") dont have the value of (s:TextInput id="doc"/)
for the second time I return to the child 1 and I click add, then I move to the second child and I find the value of (s:TextInput id="doc") in (mx:TextInput id="doc_titre")
What happens exactly? I think your problem may be caused by the fact that the components on the second children are not created until that view is opened, There are many solution for this, you could write some code in the creation complete oof the second view that will load the correct value, you can use databinding to bind the text inputs to the same string or you can try setting creationPolicy to all.
My answer is based on my above assumption so if I am wrong please give more details.
Check this http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cb8.html#WS2db454920e96a9e51e63e3d11c0bf69084-7ae5 and try setting the creationPolicy to all then let us know if the problem is solved
Use createDefferedContent() instead:
for (var i:int = 0; i < accordion.numChildren; i++)
{
(accordion.getElementAt(i) as NavigatorContent).createDeferredContent();
}
This method creates the children and their components in the background. Don't use creationPolicy as I did since this causes memory-related issues.

Obtaining a HGroup subcomponent that it is in view of a Scroller container Adobe Flex 4.5

I have setup a Scroller container around an HGroup of labels. The Scroller is setup to only display a single label at a time. What I am trying to do is determine which label is in view of the Scroller when a button is clicked. I have scoured the reference material on Scrollers and HGroups, but cannot formulate a programmatic strategy to determine what element of the group is in view.
Scroller Code for reference:
<local:Scroller id="imageViewer" includeIn="startState" left="411" right="411" top="241"
bottom="356" depth="2">
<s:HGroup id="imageGroup" gap="0" width="100%" height="100%">
<s:Label id="vin1337" width="201" height="104" color="white" fontSize="30"
text="Vehicle ID:1337" textAlign="center" verticalAlign="middle"/>
<s:Label id="vin2567" width="199" height="104" color="white" fontSize="30"
text="Vehicle ID:2567" textAlign="center" verticalAlign="middle"/>
<s:Label id="vin9456" width="199" height="104" color="white" fontSize="30"
text="Vehicle ID:9456" textAlign="center" verticalAlign="middle"/>
</s:HGroup>
</local:Scroller>
Eventually these Labels will be images, but using labels for proof of concept currently.
Any help would be greatly appreciated, and thank you for reading.
EDIT:
So after implementing an approach with lastIndexInView, I keep getting "TypeError: Error #1009: Cannot access a property or method of a null object reference." on the line "vehicleID.text = Label(lObj).text;". Below is the code involved:
Function:
protected function idSelect_clickHandler(event:MouseEvent):void
{
var hLay:HorizontalLayout = imageGroup.layout as HorizontalLayout;
var lIndex:int = hLay.lastIndexInView;
var lObj:Object = imageGroup.getElementAt(lIndex);
vehicleID.text = Label(lObj).text;
currentState="selectedState";
}
Components:
<local:SnapScroller id="imageViewer" includeIn="startState" left="411" right="411" top="241"
bottom="356" depth="2">
<s:HGroup id="imageGroup" gap="0" width="100%" height="100%">
<s:Label id="vin1337" width="201" height="104" color="white" fontSize="30"
text="Vehicle ID:1337" textAlign="center" verticalAlign="middle"/>
<s:Label id="vin2567" width="199" height="104" color="white" fontSize="30"
text="Vehicle ID:2567" textAlign="center" verticalAlign="middle"/>
<s:Label id="vin9456" width="199" height="104" color="white" fontSize="30"
text="Vehicle ID:9456" textAlign="center" verticalAlign="middle"/>
</s:HGroup>
</local:SnapScroller>
<s:Button id="idSelect" includeIn="startState" x="367" y="608" width="290" height="67"
label="Select" click="idSelect_clickHandler(event)" color="#00008F" fontSize="24"/>
<s:Label id="vehicleID" includeIn="selectedState" x="425" y="453" color="#00008F" fontSize="24"
text="Vehicle ID: ____"/>
I think this should answer your question http://blog.flexexamples.com/2009/10/31/determining-how-much-of-an-item-is-visible-in-a-scrolling-vgroup-container-in-flex-4/
basically the layout has firstIndexInView and lastIndexInView property which will tell you which items are visible.
The second issue I was running into was due to the fact I was trying to access the vehicleID component before it had actually been initialized. In other words, I was trying to change an element that wasn't included in the current state, but in fact, was a member of the next state.
Solved it by changing the state first, then assigning the label.

Manage hboxs in Vbox flex

I have VBox that contains two Hbox. The first hbox is not included in the layout while second is. After a event occurs, first hbox is visible & included in the layout. But the problem is the second hbox does not move down & first & second are overlapping. I tried using the co ordinates x,y, move it does not work. Here is the code below.
<mx:VBox id="quesBx" >
<mx:HBox id="errBx" width="698" height="50" borderColor="#ff0000" borderStyle="solid" visible="false"
paddingTop="12" paddingLeft="15"
verticalScrollPolicy="off">
<mx:Image source="{CommonImages.EXCLAMATION_ICON}" width="20"/>
<mx:Text color="#ff0000" fontSize="14" paddingLeft="-100" paddingTop="-18" >
<mx:htmlText>
<![CDATA[
<
]]>
</mx:htmlText>
</mx:Text>
</mx:HBox>
<mx:Spacer height="5"/>
<mx:HBox id ="btnBx" textAlign="center" paddingRight="20" bottom="0" verticalAlign="bottom" horizontalAlign="right">
<mx:Spacer width="435"/>
<mx:Button id="btn_Cancel" label="Cancel" width="120"/>
<mx:Button id="btn_Submit" label="Submit" click="submit(event)" width="120"/>
</mx:HBox>
after the calling submit
this.quesBx.height += 50;
btnBx.y += 50;
Why are both of them overlapping & how can i get second box after first one.
Make sure you're setting includeInLayout=true when you set visible=true on the first HBox.

How to access other panels in Flex 3 ViewStack?

I have a ViewStack with 2 panels:
<mx:ViewStack id="viewstack1" height="243">
<mx:Panel id="gridPanel">
<mx:DataGrid id="grid" right="10" left="10" top="10" bottom="10" width="300" height="150" itemClick="showDetails(event)">
<mx:columns>
<mx:DataGridColumn headerText="ID" dataField="Id"/>
<mx:DataGridColumn headerText="Summary" dataField="Summary"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
<mx:Panel id="detailsPanel">
<mx:HBox width="100%" height="100%">
<mx:VBox height="100%" width="228" id="detailsVbox">
<mx:Label text="Label" id="itemTitle"/>
<mx:Text text="Text" id="itemSummary"/>
<mx:DataGrid height="97">
<mx:columns>
<mx:DataGridColumn headerText="Property" dataField="col1"/>
<mx:DataGridColumn headerText="Value" dataField="col2"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
<mx:Image source="images/BackButton.png" width="50" height="50" click="viewstack1.selectedChild = gridPanel"/>
</mx:HBox>
</mx:Panel>
</mx:ViewStack>
I want to have the user click a grid item in the first panel and then load the data in a panel in the second panel. I can grab the value of the index for the clicked item in the itemClicked handler, but how do I access the detailsPanel to set the values based on the row info from the Grid?
I'm not sure if this is what you want, but you can do something like this:
private function showDetails(event:ListEvent):void {
itemTitle.text = event.itemRenderer.data.Id;
itemSummary.text = event.itemRenderer.data.Summary;
//assuming that the datagrid ID from the details panel is: detailsDatagrid
detailsDatagrid.dataProvider = event.itemRenderer.data.Properties;
viewstack1.selectedChild = detailsPanel;
}
In order for this to work you will also have to add a creation policy to the viewstack.
<mx:ViewStack id="viewstack1" height="243" creationPolicy="all">
This way all panels are going to be created when the viewstack is created (by default they are created only when they are needed). This ensures that you will have a reference the detailsPanel, itemTitle, itemSummary, etc... before the panel is visible.
As for me the best way is to use data binding. Just introduce additional field
[Bindable]
private var detailsDataProvider:ArrayCollection;
And fill it with details in showDetails method. If details data need to be obtained asynchronously (from server, for example) you can reset current details value until data received:
detailsDataProvider = null;
And then populate it with server data.
The final changes are in details data grid:
<mx:DataGrid height="97" dataProvider="{detailsDataProvider}">
Hope it helps.
Here this code will explain 'stackview' simple example. Using this can call panel as same.