Skip to content Skip to sidebar Skip to footer

Sencha Touch 2.1: Form Panel Keyboard Hides Active Textfield On Android

When I tap a textfield at the bottom of the screen, the keyboard appears and hides the active element. On iOS, it works perfect. I'm able to scroll the form, so the textfield is in

Solution 1:

This is definitively a known-issue, I've seen this many times on Android. The only thing you can try to do is listen for a focus event on the input field and then scroll to the element. You might have to play around with the right Y-value, which suits your situation best.

{
    xtype: 'textareafield',
    name: 'bio',
    label: 'Bio',
    maxRows: 10,
    listeners: {
        focus: function(comp, e, eopts) {
            var ost = comp.element.dom.offsetTop;
            this.getParent().getParent().getScrollable().getScroller().scrollTo(0, ost);
        }
    }
},

This works for me. If you need any help implementing this, let me know!

enter image description here

Solution 2:

Less intrusive solution:

on Application launch method add the following lines:

launch: function() {
    if (Ext.os.is.Android) { //maybe target more specific android versions.Ext.Viewport.on('painted', function() {
            Ext.Viewport.setHeight(window.innerHeight);
        });
    }
    // ... rest of the launch method here
}

This works just fine on many cases I have been testing on. Both Cordova and Chrome implementations. You just need to take care, in case of Cordova/Phonegap app, that the fullscreen is set to false. (Tested on Cordova 3.5)

Solution 3:

The "Ext.Viewport.on('painted'"-solution gave me scrolling problem. The whole page could not be scrolled after orientation change, because viewport height would then be larger than window height. (Ext.Viewport.getHeight() will not be the same as Ext.Viewport.getWindowHeight() after orientation change.)

Made a work around using overidden input:

Create a file app/overrides/field/Input.js

Ext.define('myApp.overrides.field.Input', {
  override: 'Ext.field.Input',

  initialize: function() {
    var me = this;

    // Solves problem that screen keyboard hides current textfieldif (Ext.os.is.Android) {
        this.element.on({
            scope      : this,
            tap        : 'onTap',
        });
    }

    me.callParent();
  },

  onResize: function(input) {
    var me = input;
    //if input is not within window//defer so that resize is finished before scrollif(me.element.getY() + me.element.getHeight() > window.innerHeight) {
        Ext.Function.defer(function() {
            me.element.dom.scrollIntoView(false);
        }, 100);
    }
  },

  // Solves problem that screen keyboard hides current textfield in e.g. MyTimeRowForm//old solution with Viewport.on('painted', gave scroll problem when changeing orientationonTap: function(e) {
    me = this;
    window.addEventListener( "resize", functionresizeWindow () {
        me.onResize(me);
        window.removeEventListener( "resize", resizeWindow, true );
    }, true );
  },   
});

And add it to app.js

requires: ['myApp.overrides.field.Input']

Solution 4:

You may subscribe on show/hide events of keyboard and compensate input's offset. It's been tested on Android 4.2 & 4.4 (HTC One & Nexus 7).

if (Ext.os.is.Android4 && Ext.os.version.getMinor() >= 2) {
    (function() {
        var inputEl = null;
        var onKeyboardShow = function() {
            setTimeout(function() {
                if (!inputEl) {
                    return;
                }
                var currentClientHeight = window.document.body.clientHeight;
                var elRect = inputEl.getBoundingClientRect();
                var elOffset = elRect.top + elRect.height;
                if (elOffset <= currentClientHeight) {
                    return;
                }
                var offset = currentClientHeight - elOffset;
                setOffset(offset);
            }, 100);
        };
        var onKeyboardHide = function() {
            setOffset(0);
        };
        var setOffset = function(offset) {
            var el = Ext.Viewport.innerElement.dom.childNodes[0];
            if (el) {
                el.style.setProperty('top', offset + 'px');
            }
        };
        document.addEventListener('deviceready', function() {
            document.addEventListener("hidekeyboard", onKeyboardHide, false);
            document.addEventListener("showkeyboard", onKeyboardShow, false);
        }, false);
        Ext.define('Ext.field.Input.override', {
            override: 'Ext.field.Input',
            onFocus: function(e){
                inputEl = e.target;
                this.callParent(arguments);
            },
            onBlur: function(e){
                inputEl = null;
                this.callParent(arguments);
            }
        })
    })();
}

Solution 5:

It worked better for me

{
   xtype: 'passwordfield',
   name: 'pass',
   listeners: {
      focus: function (comp, e, eopts) {
        var contr = this;
        setTimeout(function () {
          if (Ext.os.is('Android')) {
            var ost = comp.element.dom.offsetTop;
            contr.getParent().getParent().getScrollable().getScroller().scrollTo(0, ost, true);
          }
        }, 400);
      }
   }
}

Post a Comment for "Sencha Touch 2.1: Form Panel Keyboard Hides Active Textfield On Android"