TextArea text is not getting set when in another state - apache-flex

The TextArea.text value is not getting set or staying set. This happens when I have a transition and that uses a Rotate3D and there are two transitions. With one transition it works. With two transitions (the return transition) it doesn't. So in the case below I have a transition from "note" to "list". If I add a transition from "list" to "note" then the behavior occurs. BUT if I put the textArea (note) in both states then it works correctly (ie incluedIn="note,list" works)!
<s:Group id="noteGroup" includeIn="note">
<s:TextArea id="normalTextArea" />
</s:Group>
<s:transitions>
<s:Transition fromState="note" toState="list"
autoReverse="false">
<s:Sequence target="{this}"
duration="{duration}" >
<s:Rotate3D angleYFrom="0" angleYTo="90"
autoCenterTransform="true"
applyChangesPostLayout="true"
/>
<s:SetAction target="{noteGroup}" property="visible" />
<s:RemoveAction target="{noteGroup}" />
<s:AddAction target="{listGroup}"/>
<s:Rotate3D angleYFrom="-90" angleYTo="0"
autoCenterTransform="true"
applyChangesPostLayout="true"/>
</s:Sequence>
</s:Transition>
<s:Transition fromState="list" toState="note"
autoReverse="false"
>
<s:Sequence target="{this}" duration="{duration}" >
<s:Rotate3D angleYFrom="0" angleYTo="-90"
effectStart="trace('rotateStart')"
duration="250"
autoCenterTransform="true"
applyChangesPostLayout="true" />
<s:AddAction target="{noteGroup}"
effectStart="trace('add notes action')"/>
<s:SetAction target="{noteGroup}" property="visible" />
<s:RemoveAction target="{listGroup}"
effectStart="trace('remove lists action')"/>
<s:Rotate3D angleYFrom="90" angleYTo="0"
effectStart="trace('rotateStart 2')"
duration="250"
autoCenterTransform="true"
applyChangesPostLayout="true" />
</s:Sequence>
</s:Transition>
</s:transitions>
~~ UPDATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A work around I mentioned is to include the textarea in both states and then set the visible to false in the state that it was not originally included in:
<s:Group id="noteGroup"
includeIn="note,list"
visible.list="false">
<s:TextArea id="normalTextArea" />
</s:Group>
~~ UPDATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Setting the value later (after the transition) works (thanks Flextras) but the text is not visible until I place the cursor in the textarea.
List change handler code:
protected function list1_changeHandler(event:IndexChangeEvent):void {
content = (list.selectedItem as Note).content;
currentState = "note";
setTimeout(setText,1000);
}
private function setText():void {
normalTextArea.text = content; // works but only on clicking into the textarea
}
THIS DOES NOT WORK:
protected function list1_changeHandler(event:IndexChangeEvent):void {
content = (list.selectedItem as Note).content;
normalTextArea.text = content;
trace('1 text ='+normalTextArea.text); // contains content
currentState = "note";
normalTextArea.text = content;
trace('2 text ='+normalTextArea.text); // contains content
setTimeout(setText,1000);
}
// scenario 1
private function setText():void {
normalTextArea.text = content; // clicking into textarea it is empty
}
// scenario 2
private function setText():void {
normalTextArea.text = ""; // this does work but
normalTextArea.text = content; // you have to click into textarea
}

Related

flex effect on visible event

I would like to create a component that apply a resize effect when the it is visible:
I did this:
<s:Panel id="loginPanel" title="Connect" creationCompleteEffect="customResize"
showEffect="customResize" hideEffect="fadeOut"
width="400" height="300" includeIn="login">
with:
<fx:Declarations>
<!-- Effects declaration -->
<s:Fade id="fadeIn" alphaFrom="0.0" alphaTo="1.0" duration="500"/>
<s:Fade id="fadeOut" alphaFrom="1.0" alphaTo="0.0" duration="500"/>
<s:Animate id="customResize" duration="1000">
<s:SimpleMotionPath property="percentWidth" valueFrom="0" valueTo="100"/>
<s:SimpleMotionPath property="percentHeight" valueFrom="0" valueTo="100"/>
</s:Animate>
</fx:Declarations>
The problem is that when the component is displayed for the first time, the effect is correctly played but when the state change for example from "login" to "working" then back to "login", the effect isn't played anymore.
I thought that a visibility event would have been dispatched and the showEffect applied but it seems that the state changes don't work like I was expecting.
How can I apply the effect each time the component is visible?
are you sure the states are toggling the visible property?
Try to force Visible property to change:
<s:Fade id="fadeIn" alphaFrom="0.0" alphaTo="1.0" duration="500" effectStart="loginPanel.visible = true"/>
<s:Fade id="fadeOut" alphaFrom="1.0" alphaTo="0.0" duration="500" effectEnd="loginPanel.visible = false"/>

Flex 4 state transition Move effect in a VGroup

I am trying to create a nice state transition where I have 2 containers (in the example below I have used panels).
When the state changes, I want to fade away the upper panel, then move the lower panel to the top of the screen, and below that I want to fade in a new 'lower' panel.
In the code below, the fades are working fine, but the panel doesn't move to the top of the box, it just goes to it's new position without a transition.
Also the 'reverse' transition doesn't happen at all. I tried to set autoReverse to true, and I also tried to build an opposite transition, both no result, there was no transition.
When I replace the VGroup (in which it all happens) for VBox, I get a slightly better result, the transition works in one way. The reverse transition still doesn't work at all.
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
private function switchMode():void
{
if (currentState == "up")
currentState = "down";
else
currentState = "up";
}
]]>
</fx:Script>
<s:states>
<s:State name="up" />
<s:State name="down" />
</s:states>
<s:transitions>
<s:Transition fromState="up" toState="down">
<s:Sequence>
<s:Fade target="{upperGrid}" />
<s:RemoveAction target="{upperGrid}" />
<s:Move target="{panel1}" />
<s:AddAction target="{lowerGrid}" />
<s:Fade target="{lowerGrid}" />
</s:Sequence>
</s:Transition>
<s:Transition fromState="down" toState="up">
<s:Sequence>
<s:Fade target="{lowerGrid}" />
<s:RemoveAction target="{lowerGrid}" />
<s:Move target="{panel1}" />
<s:AddAction target="{upperGrid}" />
<s:Fade target="{upperGrid}" />
</s:Sequence>
</s:Transition>
</s:transitions>
<s:VGroup width="100%" height="100%" top="10" left="10" right="10" bottom="10">
<s:Panel id="upperGrid" width="100%" height="100%" includeIn="up" title="upper panel" />
<s:Panel id="panel1" width="100%" title="Panel">
<s:Button label="Switch mode" click="switchMode()" />
</s:Panel>
<s:Panel id="lowerGrid" width="100%" height="100%" includeIn="down" title="lower panel" />
</s:VGroup>
When I get rid of the VGroup or VBox, and use absolute positions, the transitions work fine:
<s:Panel id="upperGrid" left="10" right="10" top="10" bottom="{panel1.height + 20}" includeIn="up" title="upper panel" />
<s:Panel id="panel1" left="10" right="10" top.up="{upperGrid.height + 20}" top.down="10" title="Panel">
<s:Button label="Switch mode" click="switchMode()" />
</s:Panel>
<s:Panel id="lowerGrid" left="10" right="10" top="{panel1.height + 20}" bottom="10" includeIn="down" title="lower panel" />
Should you always use absolute positioning if you want these kind of moving transitions or is it possible to use these transitions in a VGroup or VBox combined with includeIn and excludeFrom properties? And if so, how could I correct that in the example above?
The problem is that you're using a container that is meant to 'layout' it's children. You could try to create your own layout that could know when it's children are currently in an effect and not touch them until they're done, or use an absolutely positioned layout container (like Group) instead.

Flex animation question

I am trying to do a simple animation. I want to fade in and resize a List inside creationcomplete. My problem is that I can alway see the element flash in before the element animation begin. On the other word, the user will see the element appear for 1 second->then fade in and resize animation. I was hoping anyone here could help me about it. thanks...
my code.
AS:
protected function compList_creationCompleteHandler(event:FlexEvent):void
{
compinfoResult.token = getCompList.compinfo();
compinfoResult.addEventListener(ResultEvent.RESULT, completeLoading);
function completeLoading(event:ResultEvent):void{
fadeList.play(); //the animation will fire when the List get the result from the server...
scaleList.play();
}
}
mxml
<s:Scale id="scaleList" scaleXFrom="0" scaleXTo="1" scaleYFrom="0"
scaleYTo="1" duration="500" target="{compList}" />
<s:Fade id="fadeList" alphaFrom="0" alphaTo="1" target="{compList}" />
<s:List id="compList"
width="280"
height="560"
x="0"
y="0"
alpha="0"
creationComplete="compList_creationCompleteHandler(event)"
itemRenderer="itemRenderer.compListItemRenderer"
change="compList_changeHandler(event)"/>
First off, I would combine these into a single transition, either in parallel or in sequence at your preference:
<s:Sequence id="effectSequence">
<s:Scale id="scaleList" scaleXFrom="0" scaleXTo="1" scaleYFrom="0"
scaleYTo="1" duration="500" target="{compList}" />
<s:Fade id="fadeList" alphaFrom="0" alphaTo="1" target="{compList}" />
</s:Sequence>
Then, I would not try to trigger this manually with an event. Use an effect instead, in this case I'd recommend the creationCompleteEffect.
<s:List id="compList"
width="280"
height="560"
x="0"
y="0"
alpha="0"
creationComplete="compList_creationCompleteHandler(event)"
itemRenderer="itemRenderer.compListItemRenderer"
change="compList_changeHandler(event)"
creationCompleteEffect="{effectSequence}"`/>

How to validate the radio button group? in flex

How to validate the radio button is selected or not in flex 3?
if my question is wrong, please suggest me any thing regarding the validation of radio group.
Simply use a StringValidator:
<mx:StringValidator id="myRadioButtonGroupValidator"
source="{myRadioButtonGroup}"
property="selectedValue"
required="true"/>
For Spark groups and RadioButtons things work slightly different. See the example below.
Note: For a HGroup as the example shows: The warning-sight will appear for errors but there will be no red-colored border be visible. If you set a RadioButton itself as listener you might get an ugly result and if you set a FormItem as target you will see nothing happen.
<fx:Declarations>
<s:RadioButtonGroup id="myGroup" />
<mx:StringValidator id="vLevel"
required="true"
source="{myGroup}"
property="selectedValue"
minLength="1"
maxLength="80"
listener="{grpLevel}"
/>
</fx:Declarations>
<s:FormItem label="Level">
<s:HGroup id="grpLevel">
<s:RadioButton group="{myGroup}" label="A"/>
<s:RadioButton group="{myGroup}" label="B"/>
<s:RadioButton group="{myGroup}" label="C"/>
</s:HGroup>
</s:FormItem>
This is the way I solved the problem. If anything is wrong please leave a the comment.
<mx:NumberValidator id="radiogroupValidator" source="{radiogroup}" property="selectedValue" allowNegative="false" />
radio group source in mxml file
<mx:RadioButtonGroup id="radiogroup" itemClick="radiochangefunction(event)" selectedValue="-1" />
<mx:RadioButton id="radiobtn1" groupName="radiogroup" label="Send Password to existing EmailId" value="0"/>
<mx:RadioButton id="radiobtn2" groupName="radiogroup" label="Enter new EmailId" value="1"/>
The itemClick function
public function radiochangefunction(event):void
{
radiogroup.selectedValue=event.currentEvent.selectedValue.toString();
}
and finally in validation function
var isValidradiobutton:Boolean = (Validator.validateAll([radiogroupValidator]).length==0);
Listen to the itemClick event of the RadioButtonGroup. Within the handler, use selection or selectedValue property to know which RadioButton was clicked.
selection - returns a reference to the selected RadioButton instance
selectedValue - returns the value property of the selected RadioButton, if it is set. Otherwise, returns its label text.
Both of these properties return null if no RadioButton is selected.
A running example from livedocs
<?xml version="1.0"?>
<!-- Simple example to demonstrate RadioButtonGroup control. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ItemClickEvent;
// Event handler function to display the selected button
// in an Alert control.
private function handleCard(event:ItemClickEvent):void {
if (event.currentTarget.selectedValue == "AmEx") {
Alert.show("You selected American Express")
}
else {
if (event.currentTarget.selectedValue == "MC") {
Alert.show("You selected MasterCard")
}
else {
Alert.show("You selected Visa")
}
}
}
]]>
</mx:Script>
<mx:Panel title="RadioButtonGroup Control Example" height="75%" width="75%"
paddingTop="10" paddingLeft="10">
<mx:Label width="100%" color="blue"
text="Select a type of credit card."/>
<mx:RadioButtonGroup id="cardtype" itemClick="handleCard(event);"/>
<mx:RadioButton groupName="cardtype" id="americanExpress" value="AmEx"
label="American Express" width="150" />
<mx:RadioButton groupName="cardtype" id="masterCard" value="MC"
label="MasterCard" width="150" />
<mx:RadioButton groupName="cardtype" id="visa" value="Visa"
label="Visa" width="150" />
</mx:Panel>
</mx:Application>

How can I remove items from a Collection with filter function, and then add new items that don't meet the filter criteria?

I have a Collection, and I want to remove all items that have a certain property set to true. I use a filterFunction to accomplish this. My question is, how can I add new items to the Collection that have that property set to true? The filterFunction is still applied, and the item is not added....
Do I have to iterate through the entire collection and remove items one at a time? I thought that that is exactly what refresh() does.
Thanks.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
private function hideSpecialItems():void
{
items.filterFunction =
function (item:Object):Boolean
{
return item.isSpecial;
}
items.refresh();
trace(items.length.toString()); // 2
}
private function addSpecialItem():void
{
items.addItem({name: "new Special Item", isSpecial: true});
trace(items.length.toString()); // Item is added - returns 3
}
private function addNormalItem():void
{
items.addItem({name: "new Item", isSpecial: false});
trace(items.length.toString()); // Item not added - returns 2
}
</mx:Script>
<mx:ApplicationControlBar>
<mx:Button label="Hide Items That Aren't Special" click="hideSpecialItems();" />
<mx:Button label="Add a Normal Item" click="addNormalItem();" />
<mx:Button label="Add a Special Item" click="addSpecialItem();" />
</mx:ApplicationControlBar>
<mx:ArrayCollection id="items">
<mx:Array>
<mx:Object name="item 1" isSpecial="{false}" />
<mx:Object name="item 2" isSpecial="{false}" />
<mx:Object name="item 3" isSpecial="{false}" />
<mx:Object name="item 4" isSpecial="{true}" />
<mx:Object name="item 5" isSpecial="{true}" />
<mx:Object name="item 6" isSpecial="{false}" />
</mx:Array>
</mx:ArrayCollection>
<mx:DataGrid dataProvider="{items}" />
</mx:Application>
filterFunction doesn't actually remove the items from the ArrayCollection. It just hides them from the view. You can still see all the items in ArrayCollection.source property.
If you add new items while filterFunction is still applied, they too are subject to filtering.
To permanently remove items from a list, convert it to an Array and use Array#filter.
var newCollection:ArrayCollection =
new ArrayCollection(oldCollection.toArray().filter(myFilterFunction))

Resources