How to warn user of CAPS LOCK enabled in Flex/AIR? - apache-flex

Similar to the XP login screen, in Flex 3, how can I display a warning to the user in a textbox that the CAPS LOCK key is enabled?

flash.ui.Keyboard.capsLock is not bindable so that code won't really work.
I would invoke a function in the "keyDown" event for the TextInput and then check flash.ui.Keyboard.capsLock in that function. You can then set visible/includeInLayout on that Text, pop up an Alert, etc...

try this
private function addHandler():void{
//Called from app's creation complete event.
//Listener to handle any keyboard KEY_DOWN event:
this.addEventListener(KeyboardEvent.KEY_DOWN,handleKeyDown);
}
private function handleKeyDown(event:KeyboardEvent):void{
if (Keyboard.capsLock){
lblCaps.visible =true;
} else {
lblCaps.visible =false;
}
}
call addHandler on creation complete

In actionScript:
if(flash.ui.Keyboard.capsLock){
// caps lock is on...
}
or MXML:
<mx:Box width="100%" id="capsbox"
visible="{flash.ui.Keyboard.capsLock}"
includeInLayout="{capsbox.visible}">
<mx:Text text="Caps Lock is on." color="red" />
</mx:Box>

Related

How to ignore Ctrl-C events in flex that do not change a textbox contents?

Currently, it seems that every time Ctrl-C is pressed within a textbox to copy its content, the textbox receives an Event.CHANGE, and thus our application decides that a change was made in the text box and enables the "apply changes" button, although no changes were made, and all the user wanted was to copy the textbox contents.
The textbox component we're using is spark.components.TextInput
On view initialization I register:
_view.hostNameTextBox.addEventListener(
Event.CHANGE, onConnectionDat‌aChanged, false, 0, true
);
And the event listener function is:
private function onConnectionDataChanged(e:Event):void {
_view.applyButton.enabled = true;
}
Any ideas ?
Thanks !
Here's a slight variation of #Sunil D.'s answer: use the operation property of the event to determine whether the current operation was a copy operation or another one:
private function inputChangeHandler(event:TextOperationEvent):void {
var operation:IOperation = event.operation;
if (operation is CopyOperation) trace("Ctrl+C was pressed");
if (operation is InsertTextOperation) trace("New text was inserted");
if (operation is DeleteTextOperation) trace("Some text was deleted");
}
This approach will also fix your issue with multiple TextInputs: only one event handler required instead of many.
The Spark TextInput dispatches a TextOperationEvent.CHANGE event on every keystroke that you make.
However, unlike the KeyboardEvent that Flextras is referring to, this event does not tell you which keys were pressed. Instead the event has an operation property which is a FlowOperation that describes the change.
But don't bother with that. Since the change event will get dispatched on every keystroke, compare the value of the TextInput with the the value from the previous change event.
private var lastTextInputValue:String = "";
private function inputChangeHandler(event:Event):void
{
if (textInput.text == lastTextInputValue)
{
}
else
{
}
lastTextInputValue = textInput.text;
}
You can try something like this:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import spark.events.TextOperationEvent;
protected function inPutText_changeHandler(event:TextOperationEvent):void
{
// TODO Auto-generated method stub
if(ctrlCPressed)
{
clickBtn.enabled = false;
ctrlCPressed = false;
}
else
{
clickBtn.enabled = true;
}
}
private var ctrlCPressed:Boolean = false;
protected function inPutText_keyDownHandler(event:KeyboardEvent):void
{
// TODO Auto-generated method stub
if(event.ctrlKey == true && event.keyCode == Keyboard.C)
ctrlCPressed = true;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:TextInput id="inPutText" change="inPutText_changeHandler(event)" text="Mahesh Parate"
keyDown="inPutText_keyDownHandler(event)"/>
<s:Button id="clickBtn" label="Click" enabled="false"/>
</s:Application>
The TextInput component contains two listeners, one for the TextInput.CHANGE event and one for the KeyboardEvent.KEY_DOWN. The keyDown listener will detect whether CTRL+C and set a flag. When the CHANGE event is handled, that listener will check whether the flag for CTRL+C is true or not and take the appropriate actions. If CTRL+C was pressed, the code will enable the button. If not, the button will be disabled and the flag reset to false.

Dismiss SoftKeyboard in Flex Mobile

The Flex InteractiveObject has has a requestSoftKeyboard() method that pops up the Soft Keyboard.
How can I do the opposite and send it back?
Thank you.
With Flex 4.6, you can dismiss by setting
stage.focus = null;
Please read more here:
open soft keyboard in a mobile Flex application
For example, say your InteractiveObject is a TextInput, then you can keep it from popping up with the following:
private function onActivating(event:SoftKeyboardEvent):void
{
event.preventDefault();
}
<s:TextInput softKeyboardActivating="onActivating(event)" />
Or you can use
<s:TextInput needsSoftKeyboard = "False"/>
EDIT:
You can send it back with the following:
Listen for the event when you want it to close (like hitting the "enter" key) and then use the setFocus property to change the focus to another component:
private function CloseKeyboard():void
{
hidesoftkeyboard.setFocus();
}`
<s:TextInput id="txtinput"/>
<s:Button id="hidesoftkeyboard" click=CloseKeyboard();>
UPDATE
Following the 4.6 update to Flex - there are new softkeyboard techniques chronicled here.

Alert is triggered multiple times

The following code works in the following way:
When I enter incorrect values in the txtother.textbox and focuses out, an alert will be displayed as "Please enter a valid Format Mask." .
After pressing the "ok" button in the Alertbox the txtOther.focusout even is triggered again.
i.e. immediately after pressing the OK of alert, the same ALERT is displayed again.
I have added the code for ur reference:
//in mxml File:
<mx:Canvas label="General" >
<mx:VBox>
<mx:Canvas id="cvsGeneral">
<mx:TextInput id="txtOther" focusOut="txtOther_Validate();"/>
</mx:Canvas>
</mx:VBox>
</mx:Canvas>
<mx:Canvas width="100%" height="5%" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:HBox width="80%" height="100%" horizontalAlign="left">
<mx:Button width="64" label="Save" id="btnSave" click="btnSave_Click();" focusIn="txtOther_Validate();"/>
</mx:HBox>
</mx:Canvas>
//Validating action script is as follows:
public function txtOther_Validate():void{
var formatMask: String = null;
if(txtOther.editable && txtOther.enabled){
if(txtOther.text != ""){
formatMask = txtOther.text;
if(conditions to validate){
//some expression
}
if(formatMask.length < 12){
Alert.show("Please enter format mask with minimum 12 digits.");
txtOther.setFocus();
return;
} VariableEditControl.getInstance().validateFormatMask(txtOther.text,validateFormatMask_Result,validateFormatMask_Fault, validateFormatMask_Error);
}
}
}
public function validateFormatMask_Result(event:PLEvent): void {
var result:String = event.getData().toString(); // here lets assume that the result variable is stored as "FAILURE"
if(result == "FAILURE"){
Alert.show("Please enter a valid Format Mask.");
txtOther.setFocus(); //
}
}
I don't want to the alert to come again and again ..
I need it in such a way that when the ok button of alert is pressed. The txtother.text should be in focus, and the alert should not come again and again as before.
it's because you have the focusIn="txtOther_Validate();" on the ok button a second time. just remove the focusIn handler and you should be fine.
I may be in error but I think the alert box won't wait till you close it. So you trigger your validate and immediately set the focus back to the input. Now you click the alert box's ok button which will make the input lose the focus triggering the validation which will raise the alert which will... and so on.
EDIT:
stage.focus = txtOther;
This will works in as3... I don't know about flex.

"FlexGlobals.topLevelApplication.addEventListener" can't catch keyboard input on PopUp

Suppose I have an application and a global event listener in it. Should the key events, who are fired in the PopUp, be caught by that listener? Or maybe popups are not placed in that hierarchy?
Here's simplified test-code for you to understand what I'm talking about:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
<mx:Script><![CDATA[
private function init():void {
FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDownHandler);
}
private function myKeyDownHandler(event:KeyboardEvent):void {
Alert.show("It works!");
}
private function makeNewPopup():void {
var win:PopupWindow = new PopupWindow(this, new TestingForm(), true, "Popup", false);
win.showPopup();
}
]]></mx:Script>
<mx:VBox>
<mx:TextInput/>
<mx:Button label="MakePopup" click="makeNewPopup()"/>
</mx:VBox>
</mx:Canvas>
Ok, what we have .. after running the application, put the input focus into the TextInput and press any letter. The Alert will be fired. Now, press the MakePopup and do the same in it TextInput .. no any feedback from it.
Any thoughts about that?
The parent of all popups is SystemManager. So, use FlexGlobals.topLevelApplication.systemManageror stage.

What's the best way to cause a Flex 3 button to respond to the enter key?

In Flex 3, buttons call their click handler when they are clicked on by the mouse, or when they have the focus and the user depresses the space bar.
Is there a straightforward way to cause Flex 3 buttons with focus to call their click handler when the user presses the enter key?
Sure, you could do something like this:
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function btn_click(event:MouseEvent):void
{
Alert.show("Clicked!");
}
private function btn_keyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.ENTER)
btn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
]]>
</mx:Script>
<mx:Button id="btn" label="Click Me" click="btn_click(event)" keyDown="btn_keyDown(event)" />
... although I'm not a huge fan of dispatching events on objects outside of those objects. A cleaner approach might be to subclass Button, add the listeners and handlers inside your subclass, and then dispatch the click event from within that class. But this should help illustrate the point. Good luck!
For something like a login form, you need to actually use an mx:form - here's the code snippet that illustrates it:
<mx:Form defaultButton="{loadButton}">
<mx:TextInput id="feedURL" />
<mx:Button id="loadButton" label="Load" click="someHandler(event)" />
</mx:Form>
Enter the url and hit enter, bam, expected behavior.
Googled from here.
If you are submitting a form like a Login dialog or the like, the "enter" property on the TextField is a great solution:
<mx:TextInput displayAsPassword="true" id="wPassword" enter="handleLoginSubmit()"/>
Even better
private function setValidationFocus(formObject:Object):void
{
formObject.setFocus();
formObject.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT)); // sneaky sneaky
formObject.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OVER));
}
You can also add the KEY_DOWN listener in Christian's answer to the button itself. Just make sure you call stopImmediatePropagation. In this example I let any key cause the button action. And I am using the same handler so I allow any "Event" type. You could use different "cancelClick" handlers.
protected function cancelClick(e:Event = null):void{
this.dispatchEvent(new Event(Event.CANCEL)); // do component action
e.stopImmediatePropagation();
}
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName,instance);
switch(instance){
case cancel:
cancel.addEventListener(MouseEvent.CLICK,cancelClick);
cancel.addEventListener(KeyboardEvent.KEY_DOWN,cancelClick);
}
}
Try the "buttonDown" event; it may be dispatched in either case. Otherwise you are probably looking at using "keyDown" and checking the key that was pressed.
I've been lookind at the same problem but the answer from Christian Nunciato seem's to me to be the best.
One more thing to add to his solution, I think that the bubbling, flag in btn.dispatchEvent(new MouseEvent(MouseEvent.CLICK)), should be set to false (btn.dispatchEvent(new MouseEvent(MouseEvent.CLICK, false))) because
the event should be isolated on the button.

Resources