Thursday, August 24, 2017

Something in the cordova / angular / ionic stack steals my focus

Leave a Comment

In order to provide Accessibility i need to to focus elements when entering screens in my Cordova app. With some tricks i managed to set the focus on an element, but the element looses the focus in an instant (verified by listening for the "blur" event) and the loss happens before Apples VoiceOver, Androids Talkback kicks in or the User can take any actions.

I already tried wrapping the setting of the focus inside the $timeout to force it to happen after everything is rendered but that did not help at all. It occurs to me that something in Cordova, angular 1 or ionic does some nasty focus magic on its own interfering with m code.

Has anybody experienced something smiliar and found a workaround for that?

1 Answers

Answers 1

I used following directive for Cordova-Ionic:

app.directive('focusableInput', function($timeout,$log) {     return {         restrict: 'A',         require: 'ngModel',         scope: {             focusState: "=",             onGo: "&"         },         link: function(scope, element, attr, ngModel) {              var moveCursorToEnd = function(el) {                 if (typeof el.selectionStart == "number") {                     el.selectionStart = el.selectionEnd = el.value.length;                 } else if (typeof el.createTextRange != "undefined") {                     el.focus(); //                    var range = el.createTextRange(); //                    range.collapse(false); //                    range.select();                 }             }              scope.$watch("focusState", function(state) {                 $log.debug("focusableInput - focus state change: " + state,element);                 if (state) {                     //cordova.plugins.Keyboard.show();                     $log.debug("focusableInput - do focus!!!",element);                     $timeout(function() {                         element[0].focus();                         moveCursorToEnd(element[0]);                     }, 300);                      //element[0].focus();                 } else {                     element[0].blur();                 }             });              element.on("keydown", function(event) {                 console.log("pressed: " + event.which, event);                 //$log.debug(attr);                  if (event.which == 13) {                     $timeout(function() {                         scope.onGo();                     });                 }             });                scope.$watch(                     function() {                         return ngModel.$modelValue;                     },                     function(newValue) {                         $log.debug("focus input model changed: ", newValue);                          if (newValue) {                             var endChar = newValue[newValue.length - 1];                             $log.debug("endChar",endChar);                              if (endChar == " " || endChar == ",") {                                 $timeout(function() {                                     scope.addItem();                                 });                             }                         }                     }             );         }     }; }); 

And usage:

<input type="email" placeholder="Email"                 class="login-custom-input"                focusable-input                 focus-state="textAreaFocusState"                ng-model="meeterAccount.email"                ng-focus="onSignUpLoginEmailFocus()"                ng-blur="onSignUpLoginEmailFocusLost()"                > 

focusable-input directive uses focus-state attribute


Hope it will help you.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment