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.)
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();
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With