ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.52k forks source link

Tap on textarea outer edge opens keyboard but textarea is not focussed sometimes #5546

Closed SebastianSchirmer closed 8 years ago

SebastianSchirmer commented 8 years ago

Short description of the problem:

When clicking on the outer edge of a textarea, the keyboard opens but the textarea is sometimes not focussed. This is somehow strange because the keyboard is supposed to open on textarea focus. Therefore, I'd expect the textarea to be always focussed when the keyboard shows up. To close the keyboard, you must then first tap again the textarea so that it is focussed, and afterwards the ion-content area to unfocus and close the keyboard.

Analysis shows that the keyboard registers the tap and opens (keyboard plugin being used) but the textarea does not fire a focus event. Both ng-focus or a custom directive binding element.on('focus') do not get triggered.

What behavior are you expecting?

The textarea gets focus, the cursor is placed into the textarea and the keyboard opens. In other words, if the keyboard opens, the tapped element should fire a 'focus' event.

Steps to reproduce: This happens in a production app which is available in the App Store. To easily reproduce I have created a simple repository based on the tabs-starter project. In tab "Dash" there is an ion-footer-bar containing a textarea. Tapping the textarea mostly focusses it, sometimes not, especially when tapping along the textarea edges: https://github.com/leschirmeur/textareaApp

Ionic Version: 1.x / 2.x 1.2.4

Browser & Operating System: iOS / Android / Chrome iOS 8 and 9

Run ionic info from terminal/cmd prompt:

Your system information:

Cordova CLI: 5.4.1
Gulp version:  CLI version 3.9.0
Gulp local:   Local version 3.9.0
Ionic Version: 1.2.4
Ionic CLI Version: 1.7.14
Ionic App Lib Version: 0.7.0
ios-deploy version: 1.8.4
ios-sim version: 5.0.6
OS: Mac OS X El Capitan (wrongly detected, running on OS X Yosemite)
Node Version: v0.12.7
Xcode version: Xcode 7.2.1 Build version 7C1002
SebastianSchirmer commented 8 years ago

Having done some more investigation I found out the following:

Tapping on the textarea edge opens the keyboard. When putting a console.log into the function tapHandleFocus(ele) in line 3112 of ionic.bundle.js, the else block in line 3135 logs element as being the tapped one! So, to me it seems the keyboard opens although the was tapped and not the textarea, just very close to it.

Could anyone please have a look at this one?

aycron-dev commented 7 years ago

I think I'm having the same issue... how do you solved it?

SebastianSchirmer commented 7 years ago

We are using a directive as a workaround that we attach to any input fields to which we would like to apply the workaround directive:

<input qy-focus-on-keyboard-open>

The directive as such looks as follows:

angular
        .module('quiply')
        .directive('qyFocusOnKeyboardOpen', qyFocusOnKeyboardOpen);

/* @ngInject */
    function qyFocusOnKeyboardOpen($document, $window) {
        var directive = {
            restrict: 'A',
            link: link
        };
        return directive;

        function link(scope, element, attrs) {
            var domElement = element[0];
            var domDocument = $document[0];

            $window.addEventListener('native.keyboardshow', focusElement);

            function focusElement() {
                scope.$apply(function () {
                    if (domDocument.activeElement.tagName !== 'INPUT') {
                        console.log('qyFocusOnKeyboardOpen - active element !== INPUT: '
                            + domDocument.activeElement.tagName + ', therefore setting focus to input field');
                        domElement.focus();
                    }
                });
            }

            // remove event listener on destroy
            scope.$on('$destroy', handleDestroy);

            function handleDestroy() {
                $window.removeEventListener('native.keyboardshow', focusElement);
            }
        }
    }

If the document's active element is not an input field when the keyboard opens, we focus the input field explicitly.

aycron-dev commented 7 years ago

Thanks for this answer! I'm implementing this now.

SebastianSchirmer commented 7 years ago

Good luck

ionitron-bot[bot] commented 6 years ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.