Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input loose focus instantly on Android after focused with javascript

I'm working on an Ionic App with AngularJS.

I got few inputs (signin/signup stuff) and when Enter key is pressed -go button on android and equivalent on iOS- which is KeyCode 13, it focuses on the next input with help a custom directive.

It works perfectly well on web browser, but on the phone, it focuses the next input, then the focus is lost instantly and the keyboard hide itself, forcing user to click again on the input.

Here is the HTML:

<ion-view title="First Screen" hide-nav-bar="true" id="firstScreen" class=" ">
<ion-content padding="false" style="background: url(img/XAYpMMdUTvWFVAnrEhUi_restaurant.jpg) no-repeat center;background-size:cover;" class=" manual-remove-top-padding" scroll="false">
    <div class="">
        <img src="img/awdYDbeeSlSHCToXN5Lw_logo.png" width="auto" height="30%" style="display: block; margin-left: auto; margin-right: auto;">
    </div>
        <label class="item item-input " id="emailInput" name="email">
            <input class="invisible-input" type="email" placeholder="Email" ng-model="user.email" focus-me="currentInput == 0" ng-keyup="inputKeyEvent($event, 0)">
     </label>
    <label class="item item-input " id="passwordInput" name="password">
        <input class="invisible-input" type="password" placeholder="Mot de passe"  focus-me="currentInput == 1" ng-model="user.password" ng-keyup="inputKeyEvent($event, 1)">
    </label>
    <label  ng-show="isSignUp" class="item item-input " ng-class="{'animated fadeInLeft': isSignUp, 'animated fadeOutLeft' : !isSignUp && changed }" id="confirmPasswordInput" name="password">
        <input class="invisible-input" type="password" placeholder="Confirmation du mot de passe"  focus-me="currentInput == 2" ng-model="user.confirmation" ng-keyup="inputKeyEvent($event, 2)">
    </label>
    <div>
        {{response}}
    </div>
    <div class="actionButtonContainer">
        <button ng-click="signin()" id="loginButton" class=" button button-balanced  button-full">Se oonnecter</button>
        <button ng-click="signup()" id="signupButton" class=" button button-energized  button-full" ng-disabled="disableSignUp()">S'inscrire</button>
    </div>
</ion-content>

Here is the directive :

directive('focusMe', function() {
return {
    link: function (scope, element, attrs) {
        scope.$watch(attrs.focusMe, function (value) {
            if (value === true) {
                element[0].focus();
            }
        });
    }
};

And here is the controller methods that is involved :

$scope.inputKeyEvent = function(event, inputId)
{
    $scope.response = event.keyCode;
    if (event.keyCode == 13)
    {
        $scope.currentInput = inputId + 1;
        if ($scope.currentInput == 2 && !$scope.isSignUp)
            $scope.signin();
        else if ($scope.currentInput == 3 && $scope.isSignUp)
            $scope.signup();
    }
}

Thanks for your help !

EDIT

The problem was my genymotion emulator, it does work perfectly on real phone (at least mine.)

like image 662
Sorikairo Avatar asked Oct 18 '22 09:10

Sorikairo


1 Answers

I think you should call blur() method before on the unfocused element. I have done it in ionic and cordova and it works perfectly.

Also, wrap the focus() on next element in a timeout ($timeout for angular version or setTimeout for vanillajs) so the focus will be executed in another scope and after the blur has completed.

You should have something like this:

$scope.inputKeyEvent = function(event, id) {
    // prevent default 
    event.preventDefault();

    // blur on the unfocused element
    event.target.blur();

    // focus on next element
    // wrapped in timeout so it will run
    // in "another thread" 
    $timeout(function() {
      // If you want to follow all angular best practices
      // Make a broadcast and read the event in the link function
      // of your directive
      var obj = document.getElementById(nextId);

      // Check if object exists
      if(obj) {
       obj.focus();
      }

    });
}
like image 129
atc Avatar answered Oct 21 '22 06:10

atc