How to validate the radio button group? in flex - apache-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>

Related

Caret on textInput never goes away

I have a login form with various textInputs and a submit button. If you submit proper login credentials the system unloads the login view and loads the app view. Pretty standard.
Unfortunately I've noticed this weird bug where if you hover over one of the textInput boxes with the mouse, then fill the form using only the keyboard (and leave the mouse parked on top of the textInput), and then tab to the submit button and press the space bar, i.e. login via keyboard, the mouse cursor will remain a caret in the new view, no matter what you do (move, click), until you find another textInput to undo the cursor state.
I've tried to do all sorts of stuff via CursorManager but nothing seems to do the trick. I've tried dispatching events ROLL_OUT or MOUSE_OUT events to the textInput but that doesn't do the trick either.
I've tried to reproduce this in a small example and have not been able to, which I realize makes helping me that much harder. Would still love to hear if anyone has dealt with something similar or hear of any pointers that may sound connected.
thank you!
f
I had the exactly the same problem. Here is my login screen view:
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
.textInput
{
showErrorTip : true;
showErrorSkin : true;
}
</fx:Style>
<fx:Declarations>
<mx:StringValidator id="usernameValidator" source="{username}" property="text"
trigger="{signinButton}" triggerEvent="click" required="true" />
<mx:StringValidator id="passwordValidator" source="{password}" property="text"
trigger="{signinButton}" triggerEvent="click" required="true"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import info.thwm.appx.model.vo.LoginVO;
import info.thwm.appx.view.events.ViewEvent;
import mx.validators.Validator;
public static const NAME:String = "LoginView";
[Bindable] public var loginVO:LoginVO = new LoginVO();
private function init():void{
focusManager.setFocus( username );
sendEvent( ViewEvent.VIEW_CREATED, NAME );
}
private function sendEvent( type:String, data:Object=null ):void{
dispatchEvent( new ViewEvent( type, data ) );
}
private function loginUser(event:MouseEvent = null):void{
var validators:Array = [usernameValidator, passwordValidator];
var errors:Array;
errors = Validator.validateAll(validators);
if (errors.length == 0){
sendEvent( ViewEvent.BTN_LOGIN_CLICK, loginVO );
}
}
]]>
</fx:Script>
<s:Panel width="320" height="230" title="Sign In">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:Form id="form1" styleName="formStyle" defaultButton="{signinButton}"> <s:layout>
<s:FormLayout paddingLeft="25" gap="-5"/>
</s:layout>
<s:FormItem label="Username" required="true" skinClass="info.thwm.appx.view.skins.FormItemSkin">
<s:TextInput id="username" text="#{loginVO.username}" styleName="textInput"/>
</s:FormItem>
<s:FormItem label="Password" required="true" skinClass="info.thwm.appx.view.skins.FormItemSkin">
<s:TextInput displayAsPassword="true" id="password" text="#{loginVO.password}" styleName="textInput"/>
</s:FormItem>
<s:FormItem>
<s:CheckBox label="Remember" id="remember" selected="#{loginVO.remember}"/>
</s:FormItem>
<s:FormItem>
<s:Button label="Sign In" id="signinButton" click="loginUser(event)"/>
</s:FormItem>
</s:Form>
<s:controlBarContent>
<s:HGroup width="100%" verticalAlign="middle">
<s:Button label="Register" id="registerButton" click="sendEvent( ViewEvent.BTN_REGISTER_CLICK );" />
<s:Label buttonMode="true" color="#57595A" text="Forgot your username or password?" click="sendEvent( ViewEvent.BTN_PSW_REMINDER_CLICK );"/>
</s:HGroup>
</s:controlBarContent>
</s:Panel>
Nothing special about that, but if i select username field with mouse and then only use keyboard for the rest, as soon as i get to next view mouse cursor becomes input caret. The only way around it was add this line "Mouse.cursor = MouseCursor.ARROW" in next view's onCreationComplete event function.
Try explicitly setting the focus to another object? See UIComponent.setFocus()
After stripping my app down to almost the bare bones I noticed that the text property of my textInputs was bound to a field of another variable. I'm not sure why this would create the issue described above but taking that binding out solved the problem. I wish I could do more research in the matter, but sadly this has already taken way too much time.

Flex3: Component Declarations are Not Allowed Here error

I'm getting the "Component declarations are not allowed here error" where I've got my RadioButtonGroup. Below is the custom component.
Why can't I put a RadioButtonGroup in it?
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.RadioButton;
import mx.controls.RadioButtonGroup;
public function removeMe(event:MouseEvent):void {
this.removeChild(event.currentTarget as DisplayObject);
}
]]>
</mx:Script>
<mx:Panel width="500" height="400" title="hello" click="removeMe(event)">
<mx:Text text="My Text" />
<mx:RadioButtonGroup>
<mx:RadioButton label="A"/>
<mx:RadioButton label="B"/>
<mx:RadioButton label="C"/>
</mx:RadioButtonGroup>
</mx:Panel>
</mx:Canvas>
Any advice on how to solve this problem. I'm using Flex 3, SDK 3.2.
Thank you.
-Laxmidi
A RadioButtonGroup is not a container and therefore cannot have Children in the manner you're setting it up. Add a RadioButton to a group using the groupName property on the RadioButton instance. Like this:
<mx:RadioButtonGroup id="rbg" />
<mx:RadioButton label="A" groupName="rbg"/>
<mx:RadioButton label="B" groupName="rbg"/>
<mx:RadioButton label="C" groupName="rbg"/>

Flex - Play resize effect on parent before adding child to it

I have a panel with a button in it. Clicking on the button will direct the panel to state "State2" adding another two buttons into the panel. During the state change, I want the panel to resize first and then show the newly added two buttons, so I applied transitions onto the state change.
My question is:
If I put the two buttons within a HBox directly under the addChild tag, it works fine. However, if I create a new component with the same code (HBox with two buttons in it) and then add the new component to the panel (Comp in the code commented), it won't show the resize effect.
Could someone tell me how to fix this? Thanks in advance.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*">
<mx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
currentState="State2";
}
]]>
</mx:Script>
<mx:transitions>
<mx:Transition>
<mx:Sequence targets="{[comp,panel1]}">
<mx:Resize target="{panel1}" />
<mx:AddChildAction />
</mx:Sequence>
</mx:Transition>
</mx:transitions>
<mx:states>
<mx:State name="State2">
<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:HBox id="comp">
<mx:Button label="B" />
<mx:Button label="C" />
</mx:HBox>
<!--<local:Comp id="comp" />-->
</mx:AddChild>
</mx:State>
</mx:states>
<mx:Panel layout="horizontal" borderThickness="1" borderStyle="solid" id="panel1" title="AB">
<mx:Button label="A" click="button1_clickHandler(event)"/>
</mx:Panel>
</mx:Application>
I guess <mx:AddChild> tag can handle only one component at a time.
You will get your sweet resize effect if you separate your custom component to another <mx:AddChild> tag, similar to the code below:
<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:HBox id="comp">
<mx:Button label="B" />
<mx:Button label="C" />
<!-- Don't put your custom component here. -->
</mx:HBox>
</mx:AddChild>
<!-- Use separated AddChild. Still add to same relativeTo object -->
<mx:AddChild relativeTo="{panel1}" position="lastChild">
<local:Comp id="comp2" />
</mx:AddChild>
I hope you got what you want.

How do I set a focus property on a TextInput that is built using AddChild?

I have the following MXML:
<mx:State name="myState">
<mx:AddChild relativeTo="{myhbox}" position="after">
<mx:Box verticalAlign="middle" horizontalAlign="center" width="100%" height="100%">
<mx:Form id="myForm" width="479" verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:FormItem label="My Label:" fontWeight="bold" id="myLabel" direction="vertical">
<mx:TextInput id="myTextInput" width="282" />
<mx:HBox>
<mx:Button label="Go" click="go();" id="goButton" />
</mx:HBox>
</mx:FormItem>
</mx:Form>
</mx:Box>
</mx:AddChild>
</mx:State>
How do I set focus on the TextInput field using <mx:SetProperty/>? I've tried the following, but it only results in the field being highlighted -- the cursor does not appear in the TextInput:
<mx:SetProperty target="{stage}" name="focus" value="{myTextInput}"/>
Long story short, I want the cursor to appear in the field.
UPDATE: I figured it out. See comments for solution.
I try to avoid using the AddChild state tag. It's usually better to put all that in a component, and use SetProperty to set visible and includeInLayout when you want it to display.
You can always override visible in your custom component to set the focus to the field. Or create a custom setter than does the same thing
public function set show(value:Boolean):void
{
visible = true;
includeInLayout = true;
if (value)
myFunctionThatSetsTheFocus();
}
Add a "creationComplete" to the TextInput and had it call a method that setFocus on the TextInput

Is it safe to use a component reference in mxml

Consider the following radio button example.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
private function getRb1():RadioButton {
trace(rb1 == null);
return rb1;
}
]]>
</mx:Script>
<mx:VBox>
<mx:RadioButtonGroup **id="rbg" selection="{getRb1()}**"/>
<mx:RadioButton id="rb1" label="Radio Button 1" />
<mx:RadioButton id="rb2" label="Radio Button 2" />
<mx:RadioButton id="rb3" label="Radio Button 3" />
</mx:VBox>
</mx:Application>
The problem is that I can not refer to rb1 while defining RadioButtonGroup, rb1 is null at that time, but i can use the selectedValue to set the initial selction.
I was just wondering is this some special case or its not safe to refer to components in mxml in general.
Thanks,
I'm not quite sure what you're asking, but hopefully this'll answer your question -- from the Flex docs:
RadioButtonGroup.selectionContains a reference to the currently
selected RadioButton control in the
group. You can access the property in
ActionScript only; it is not settable
in MXML. Setting this property to null
deselects the currently selected
RadioButton control.
In general, though, making component references in MXML is totally fine; that's how effects are often handled, among many other things. For example:
<mx:Glow id="g" />
<mx:Label showEffect="{g}" />
However in your case, assuming you're having trouble setting the selected item, it might be because you haven't specified the group attribute on the radio buttons; omitting that detaches the group component from the individual buttons. Once you add that, you can bind the group's selection property using a Bindable variable containing a reference to a component, like so:
<mx:Script>
<![CDATA[
[Bindable]
private var selectedRadioButton:RadioButton;
private function this_creationComplete(event:Event):void
{
selectedRadioButton = rb1;
}
private function btn_click(event:Event):void
{
selectedRadioButton = rb2;
}
]]>
</mx:Script>
<mx:VBox>
<mx:RadioButtonGroup id="rbg" selection="{selectedRadioButton}" />
<mx:RadioButton id="rb1" group="{rbg}" label="Radio Button 1" />
<mx:RadioButton id="rb2" group="{rbg}" label="Radio Button 2" />
<mx:RadioButton id="rb3" group="{rbg}" label="Radio Button 3" />
<mx:Button label="Choose a Different Button" click="btn_click(event)" />
</mx:VBox>
Does this make sense? Hopefully it's not completely off the mark; post back and let me know and I'll try to help out as best I can.
Generally: just because a control was declared in MXML does not mean it is available at runtime (it might be deleted from AS, not created yet, not added to stage, therefore some properties are not available yet). This indicates it is not safe to access components at runtime and depend on values.

Resources