How to reach elements of an inline component in flex? - apache-flex

I have a problem with inline components. I want to reach an inline component from another one.. From the first component, i want to change "enable" value of the linkbutton named "Add" which is in second component. Altough i gave "id" and "className" to second one, i could reach neither it nor its elements.. is there a way to do this?
*in first component there is a text input in "CodedDescriptionItemEditor" component. I want to validate it and according to validation enable the button that i mentioned above..
These all are in a datagrid by the way. In datagrid, there is always a row that you can enter data and via the "Add" button you can save it. After save it seems as text..
Thank you..
Here is my code:
<mx:columns>
<mx:DataGridColumn headerText="{Problem}" wordWrap="true" textAlign="left" sortable="false">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:ViewStack selectedIndex="{outerDocument.index(data)}" >
<mx:HBox>
<mv:CodedDescriptionItemEditor id="editor" codePM="{outerDocument.problemListPanelPM.getProblemDescPM(data)}"
width="100%" styleName="phrFormItemInput"/>
</mx:HBox>
<mx:HBox>
<mv:CodedDescriptionItemRenderer id="renderer" codedDescPM="{outerDocument.problemListPanelPM.getProblemDescPM(data)}" />
</mx:HBox>
</mx:ViewStack>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="" textAlign="center" editable="false" width="50" resizable="false" sortable="false">
<mx:itemRenderer>
<mx:Component className="buttonColumn">
<mx:ViewStack selectedIndex="{outerDocument.index(data)}" >
<mx:HBox horizontalAlign="center" width="100%">
<mx:LinkButton id="Add" icon="#Embed('img/add.png')"
toolTip="{outerDocument.Add_Problem}"
click="outerDocument.addHandWritten()"
enabled="false" />
</mx:HBox>
<mx:HBox horizontalAlign="center" width="100%">
<mx:LinkButton id="Delete" icon="#Embed('img/delete.png')"
toolTip="{outerDocument.Remove_problem}"
click="outerDocument.removeProblem()"/>
</mx:HBox>
</mx:ViewStack>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>

Inline components in MXML are not instances but classes. So that kind of "reaching" has no sense. To combine this knowledge together to operate them I recommend you the following simple rule (which I follow and haven't problems with understanding class/instances relations):
Do not use inline components in MXML excluding simple cases on a
prototyping stage.
So in your case I recommend you to extract inline components into separate MXML classes and throw all the outerDocument references (you can replace them with events with bubbling). After that I think it will be much easier to understand and improve your design and find appropriate solution.
Another advice is use data-driven way to operate with renderers. This way is about operating data items of data provider but not getting and setting data from outer document directly. Use data binding to bind changed data between different item renderers in different columns.

In this case, you might want to keep a boolean var isAddEnabled in your outerDocument and change your enabled as below:
enabled="{outerDocument.isAddEnabled}"
Change this isAddEnabled based on your validation criteria.
As you don't want it to be applied to all your items, either keep a property in your dataProvider(preferred) OR maintain another collection of same length as your dataProvider (not recommended).

Related

flex datagrid: elemenst do not refresh inside : what do be done?

I have a compoonent inside flex4.5 in 3 columns
When I add some elements, soemtimes these one of these elements just got invisible:
when I resize the browser, it appears again.
There is no rule: it happens randomly and element is always avaible: I tried with referesh, update but this do not help.
ANy idea on why this happens and how to solve that bug ?
<mx:DataGrid id="rowcolordatagrid1" left="10" right="10" top="49" variableRowHeight="true"
bottom="58" borderColor="#CCCCCC" color="#5A5A5A" dataProvider="{questions_dp}" symbolColor="#CCCCCC">
<mx:columns>
<mx:DataGridColumn dataField="data" headerText="{xml.questions}" itemRenderer="QuestionRenderer" sortable="false"/>
<mx:DataGridColumn width="150" headerText="{xml.action}" itemRenderer="ActionRenderer" sortable="false"/>
<mx:DataGridColumn dataField="priority" headerText="{xml.priority}" itemRenderer="PriorityRenderer" width="100" />
</mx:columns>
</mx:DataGrid>
of course I tried questions_dp.refresh();
But when I resize or minimize my browsers, these blank lines appear again !
These lines happens sometimes : I would say 20% of chance some rows are invisible.
reagrds
I think the reason is because your item render.
remove 'QuestionRenderer' and try again.
if it is OK for the first column, then check all your render class:
Did you forgot to call super.method(..) with in every override metod in you render class?

Overlay text on AdvancedDataGrid in Flex 3

I am trying to overlay a label onto an AdvancedDataGrid when there are no results returned from a call for the data.
Here is a mockup of what I am trying to accomplish http://i.stack.imgur.com/6Djga.png
I tried following this previous answer: Drawing an overlay in custom flex component, but this would not work for me because an AdvancedDataGrid is not a Container (and as such does not have a rawChildren property).
I would prefer not to need to mess with the data provider, because this table will be used in many location which will have different columns and labelFields.
Any suggestions welcome.
To give a quick example as to what Flextras mentioned:
<s:Group>
<mx:DataGrid dataProvider="{myDataProvider}">
<mx:columns>
<mx:DataGridColumn dataField="test1" />
<mx:DataGridColumn dataField="test2" />
<mx:DataGridColumn dataField="test3" />
<mx:DataGridColumn dataField="test4" />
</mx:columns>
</mx:DataGrid>
<s:Label text="Overlay text here" visible="{myDataProvider.length == 0}" x="10" y="35" />
</s:Group>
Put the AdvancedDataGrid in a container along with the label overlay. Position the label on top of the DataGrid; and change it's visibility based on the dataProvider's length.

Flex button or any control with two labels

How can I have two labels on a Flex button, one label on top and another on the bottom?
With a Spark architecture button, you should just be able to create a custom button skin.
If you're using the Halo/MX architecture, then you'll have to extend the component. IF you google for multilabel button, a bunch of solutions come up.
You can make custom skin for your button. In that skin's Label, set the maxDisplayedLines attribute to as many lines as you need.
<mx:VBox verticalGap="0" x="60" y="107">
<mx:Canvas cornerRadius="5" backgroundColor="0xff0000" backgroundAlpha=".5" borderStyle="solid">
<mx:Label text="Step 1" fontSize="20" fontStyle="italic" fontWeight="bold" width="171" />
</mx:Canvas>
<mx:Canvas cornerRadius="5" backgroundColor="0xff0000" backgroundAlpha=".5" borderStyle="solid">
<mx:Label text="Initial Request" fontSize="20" fontStyle="italic" fontWeight="bold" width="100%" />
</mx:Canvas>
</mx:VBox>
This is not the correct solution, but you can make a Canvas feel like button if you want. Flexlib has a component where they provide solution for Multiline Label.

PropertyGrid in Adobe Flex?

I'm looking for a PropertyGrid-like control for Adobe Flex, or perhaps the easiest way to create one. The main two things it should do in addition to a normal property grid are displaying categories and having different kind of editor controls to edit the data in one column.
So basically I'm looking for a control to edit key/value pairs, divided into categories, with different kinds of editor controls for different keys/rows.
I found exactly what I want right here: http://www.cnblogs.com/janyou/archive/2009/07/28/1532919.html
Though that page is in Chinese, there is no record of source code or where that component came from, etc. I can also not find any other solutions on the web (although maybe my search terms are incorrect, because I'm not entire sure how to search for it).
i've done it using a datagrid with two columns, and this approach works just fine for me:
<mx:columns>
<mx:DataGridColumn dataField="parameter" width="110" resizable="false">
<mx:itemRenderer>
<mx:Component>
<mx:Label truncateToFit="true" fontWeight="bold" />
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="value">
<mx:itemRenderer>
<mx:Component>
<mx:HBox width="100%" height="100%" horizontalScrollPolicy="off" verticalScrollPolicy="off"
currentState="{(data.parameterType) == 'bool' ? 'checkboxState' : 'baseState'}">
<mx:states>
<mx:State name="baseState">
<mx:AddChild>
<mx:Label truncateToFit="true" text="{data.value}" paddingLeft="2" />
</mx:AddChild>
</mx:State>
<mx:State name="chbState">
<mx:AddChild>
<mx:CheckBox selected="{data.value && parseInt(data.value)}" paddingLeft="5" />
</mx:AddChild>
</mx:State>
</mx:states>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
Surely this is just a List control with your item renderer instantiating the correct control based on whatever the data is... i.e. if the data is an array, show in a combobox, if it's a number show in a stepper, if its text show in TextInput.
This should be very easy to achieve.

Flex: when hiding components in flex

When I set a component to visible=false the component hides, but how do I get it to take no space (get the container it belongs to to resize??)
<mx:HBox width="100%" height="100%">
...
</mx:HBox>
<mx:HBox width="100%" id="boxAddComment" visible="false" >
<mx:TextArea id="txtComment"/>
<mx:Button label="Spara" click="addComment();"/>
</mx:HBox>
When boxAddComment is visible=false I want the first HBox to take 100% height.
use the includeInLayout property. e.g.
<mx:HBox width="100%" height="100%">
...
</mx:HBox>
<mx:HBox width="100%" id="boxAddComment" visible="false" includeInLayout="false" >
<mx:TextArea id="txtComment"/>
<mx:Button label="Spara" click="addComment();"/>
</mx:HBox>
Using includeInLayout ="true" or "false" will toggle the space that it takes in the flow of items being rendered in that section.
Important note: If you don't specify visible="false" when using includeInLayout = "false" then you will usually get something that is undesired which is that your item (boxAddComment) is still visible on the page but stuff below id="boxAddComment" will overlap it visually. So, in general, you probably want "includeInLayout" and "visible" to be in synch.
Ross Henderson's suggestion in binding includeInLayout with boxAddComment.visible works great with Flex 3.0 but I found that it's not working in Flex 3.6 (I saw a posting that it actually stops working since Flex 3.3).
Just fyi.

Resources