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.
Related
I am having an issue with my ItemRenderer, which I am using for a spark List. My code is the following:
I have this list:
<s:List
id="productSetList"
dataProvider="{ model.productSets }"
change="model.selectSet( productSetList )"
height="100%" width="100%"
borderVisible="false"
itemRenderer="SideBarItemRenderer" top="20" left="15">
</s:List>
and my itemRenderer is:
<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
width="160" height="175" autoDrawBackground="false" buttonMode="true" useHandCursor="true"
click="click(event)" cacheAsBitmap="true"
>
<fx:Script>
<![CDATA[
import com.png.vm.model.vos.ProductSet;
protected function click(event:MouseEvent):void
{
trace('arthur');
}
]]>
</fx:Script>
<s:BitmapImage source="{ProductSet(data).image}" width="160" height="175"/>
</s:ItemRenderer>
The thing is, if I scroll the list, and click on an item, it does not trace 'arthur' ! Why is this so ? I must trace that all the time that someone clicks in the list!
EDIT:
If I remove change="model.selectSet( productSetList )" in the list, it works!! but I cannot remove that, some suggestions ? How can I switch that to another function?
Trace only works when you are debugging/using the debugging version of Flash Player. Make sure you are using that. If you want a pop-up message use Alert.show("message")
For more information about trace() check out:
http://livedocs.adobe.com/flex/3/html/help.html?content=logging_08.html
And Alert.show(): http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001965.html
If you are running debug player. Try originating the click event from an embedded <s:Group> this way whatever you add in here beyond the bitmap will still trigger the click event.
Something like:
<s:Group width="100%" height="100%" click="click(event)" >
<s:BitmapImage source="{ProductSet(data).image}" width="160" height="175"/>
</s:Group>
I've definitely had click events work for me inside of ItemRenderers before
My apologies, I have finally solved it. The problem was that inside the function,model.selectSet, I was calling List.change; I was messing the list up! My function was as follows:
public function selectSet(list:List):void {
list.layout.verticalScrollPosition=100;
// another stuffs
}
So, I just removed the line : list.layout.verticalScrollPosition=100; and now it`s working fine.
Thanks for all the help!
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>
I have a code like the one below
<mx:Button id="TestingID" width="100%" height="20">
<mx:Script>
<![CDATA[
import flexlib.containers.WindowShade;
]]>
</mx:Script-->
</mx:Button>
I am getting the error "id attribute is not allowed on the root tag of a component"
I have to give a Id to the button to refer to it. What should i do.. how do i solve this problem??
Regards
Zeeshan
if you are calling the component from within itself then you use the 'this' keyword.
<mx:Button height="20">
<mx:Script>
<![CDATA[
import flexlib.containers.WindowShade;
this.percentWidth = 100;
]]>
</mx:Script-->
</mx:Button>
And if you want to refer to the custom component from your application then you do this.
<application xmlns:local = "[Directory containing custom component]">
<local:MyCustomButton id="myButtonInstantiation" />
</application>
Make sense?
An MXML file is essentially a class. So if you want to reference the instance of that class from within it then you just use "this".
This can also happen if you are nesting a component inside another
As soon as you use the <fx:Component> tag you are in the root of an mxml-inline-document
<mx:itemEditor>
<fx:Component>
<mx:TextInput id="precioVenta"/>
</fx:Component>
</mx:itemEditor>
All you need to do is move the id attribute into the tag like this
<mx:itemEditor>
<fx:Component id="precioVenta">
<mx:TextInput />
</fx:Component>
</mx:itemEditor>
This applies to any kind of tag or nesting that causes the Flex compiler to create a new context for the inlinde declaration of a component
If you're defining this in a file as a subclass of Button then you can't set the id here. Put the id in the place you use this new component. For example, if this new component will be an AwesomeButton, you could use it like so:
<mycompnamespace:AwesomeButton id="testingId" />
Let see below code -
<s:ComboBox id="myCombo" dataProvider="{al}">
<s:itemRenderer>
<fx:Component>
<s:CheckBox **id="NOWAY**" click="clickHandler(event)"/>
</fx:Component>
</s:itemRenderer>
</s:ComboBox>
id is not allowed in these sort of scenarios, you use of 'this' keyword, because in this context CheckBox is root tag within Component.
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
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.