Onscreen Keyboard with AIR 9
In one of my last projects I had to develop an air application with an onscreen keyboard that is working with flash as with the internal html browser of air.
I realized pretty quickly that this isn’t that easy as it seams. There are multiple problems especially with the html view:
- how do i get the focus in the html view to add letters.
- how do i get the selection to add chars on the right position.
- how do i know when a user clicks and inputfield/textarea.
- how do i prevent that flash do set the focus on the keyboard when I click on a letter sprite.
After some experiments I discovered the really nice javascript support of the internal browser. So my first problem was already gone, when I found the javascript command:
var webView:HTMLLoader = new HTMLLoader(); //...later, to get the element with the focus call: var element:Object = webView.window.document.activeElement;
I wasn’t really into javascript so I was surprised to discover even more possibilities. Now with the focus I can place an onscreen keyboard made with flash and get the activeElement of the htmlloader and add characters to it. something like this:
var inputField:Object = webView.window.document.activeElement;
if( inputField != null ) {
var select:Number = addScreenBoardText( e.char, inputField, "value", "selectionStart", "selectionEnd" );
inputField.setSelectionRange( select, select );
}
The function where I add the char and return the selection where the cursor should be set:
private function addScreenBoardText( insert:String, object:Object, textAttribute:String, selectionStartAttribute:String, selectionEndAttribute:String ):Number {
var selectionStart:Number = object[ selectionStartAttribute ];
var selectionEnd:Number = object[ selectionEndAttribute ];
var original:String = object[ textAttribute ];
var newText:String = original.substring( 0, selectionStart ) + insert + original.substr( selectionEnd );
object[ textAttribute ] = newText;
return selectionStart + insert.length;
}
Why I make this weird looking function is because I can use it also for the flash TextField just with different parameters. So now we can add letters to a textfield in a html view as a flash TextField. But one big problem is that we loose the focus every time we click on our on screen keyboard. And there is a way to prevent the change of the focus which is very handy in this situation:
// in our main application class we listen to the mouse focus change event.
addEventListener( FocusEvent.MOUSE_FOCUS_CHANGE, onMouseFocus );
// in the listener we check if the relatedObject is a Key,Screenboard ( these are my classes for the Keyboard that get mouseclicks )
// then we prevent the default behaviour of the event. which means no focus change is triggered.
private function onMouseFocus( fe:FocusEvent ):void {
if( fe.relatedObject is Key || fe.relatedObject is ScreenBoard ) fe.preventDefault();
}
We saw earlier that is was possible to write to javascript objects as normal in actionscript. I was even more surprised as its possible to listen to javascript events with actionscript functions. That allows me to listen to javascript focus changes and hide/show the keyboard. This way I can make an overlay keyboard that is only visible when I click in a textfield which I find is a very nice solution. So this is how I listened to the javascript events ( keep in mind that this is all actionscript ):
// register everytime the page has loaded!
private function onPageLoaded( e:Event ):void {
webView.window.addEventListener( "focus", onJavaScriptFocusIn, true );
webView.window.addEventListener( "blur", onJavaScriptFocusOut, true );
}
// if we get a focus in event from js, check if its a inputfield or a textarea. then show the keyboard.
private function onJavaScriptFocusIn( e:Object ):void {
if( e.target.localName == "input" || e.target.localName == "textarea" ) {
dispatchEvent( new JavaScriptEvent( JavaScriptEvent.FOCUS_IN ) );
}
}
// we lost focus - hide keyboard
private function onJavaScriptFocusOut( e:Object ):void {
dispatchEvent( new JavaScriptEvent( JavaScriptEvent.FOCUS_OUT ) );
}
With all this you can build your onscreen keyboard that is working in flash as in html. I made a quick flexbuilder air project that you can download with a keyboard, textfield and htmlloader.