Tag onscreen

Onscreen Keyboard with AIR 4

Nov14

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.

Developed by Dariusz Siedlecki and brought to you by FreebiesDock.com