watusi / jquery-mobile-iscrollview

JQuery Mobile widget plug-in for easy use of the iScroll javascript scroller.
408 stars 183 forks source link

Need to scroll the page when keyboard is visible #124

Open hadi77makkawi opened 10 years ago

hadi77makkawi commented 10 years ago

I have a page with form element when keyboard popup I can't scroll to the end or the top of page to access other form element i have to click in the native next/prev keyboard buttons to navigate between input fields.

jtara commented 10 years ago

What platform?

on-screen keyboard support is impossible on iOS at least up to iOS 6 unless in a native application. It is possible in a native app but requires some native code.

The problem is that the browser or UIWebView think that they can scroll the focused field into position by scrolling the webview container. (NOT the page within the webview, or even the webview, but the native container that the webview is in.)

That obviously won't work if you have input elements inside of an iScroller. I've made some attempts at making this work without native code, but it's not an acceptable result, because no matter what you do, you are "fighting" against the behavior of the browser.

The only way to tame is to disable to scrolling of the container. This is only possible from native code.

I have written an extension that works with Rhodes and supports the on-screen iOS keyboard. It disables the normal scrolling and provides keyboard show/hide/size notifications via jQuery events. Then a bit of JS code acts on the events and scrolls the element into place using iScroll But I currently lack both time and permission to make it a distributable open-source project and to create a similar plugin for PhoneGap.

I think there is some hope for iOS7 and Android without needing native code, and so might work in browsers and webapps. But I will not be supporting that until I rewrite this for iScroll5/jQuery Mobile 1.4.

iOS7 has a change of behavior. At least for a UIWebView in an app built for iOS7, it now sends a Javascript resize event to the HTML viewport when the keyboard shows or hides. It did not do this prior to iOS7. I believe that at least some Android versions have similar behavior.

That solves half the problem. But I don't know if iOS7 provides any way to disable the scrolling of the container via JS.

hadi77makkawi commented 10 years ago

Platform is iOS version 6 and up. Currently I have worked around this issue by the following: 1- In Cordova 3.1.0 setting I set KeyboardShrinksView to true, it disable the pushing that iOS does to UIWebView when keyboard opens. 2- In JS I write this function $(document).on('focus', 'input, textarea, select', function() {

            id_element="#"+$(this).attr('id');
             setTimeout(function() {
                        $.mobile.activePage.find('.ui-content').iscrollview("scrollToElement",id_element,500);  

             }, 50);

});

Its working perfectly but sometimes when you click in the text input filed that at the end of the page the focus event did not triggered i don't know why ? also I have a weird issue that iScrollView re-size function fired many times around 5 times during opening the keyboard which causes some problem you will see I a lot of space at the bottom of the page when keyboard is opened

jtara commented 10 years ago

I didn't know about the Cordova KeyboardShrinksView option. This is similar to what I do in my Rhodes extension. Note that iOS 7 now does this by default. I've taken a bit of a different approach, but the end result really is the same. With the Rhodes extension, I prevent the scrolling. Instead of shrinking the view in the extension, though, some JS code gets a notification that the keyboard appeared, and then changes the size of the scroller to accommodate the keyboard.

Your JS is also very similar to what I have been using, though, instead I do some math and scroll so that it will center the element that is being focused. This way it works generically rather than having to be aware of a particular content structure.

jtara commented 9 years ago

FYI, there is at least one Cordova plugin that will help with this. There may be similar ones as well:

https://github.com/driftyco/ionic-plugins-keyboard

As well, I now have permission to open-source the native code for iOS that I have developed to deal with this. I've examined the Ionic plugin above, and the code is very similar to my own. You need some native code to send keyboard events and prevent scrolling of the WebView, and you need some companion Javascript code to then scroll the content when the keyboard events are received.

The code that I have is a native extension for the RhoMobile Rhodes platform. I had planned on re-writing it for PhoneGap/Cordova, but there is no need since Ionic beat me to it. I will coordinate with them once I release my Rhodes extension as open-source, and make sure that they are aware of features in my own code that their plugin is missing. (I'm also now looking at their code to fix some iOS8 issues!)

Unfortunately, without some native code like this, this is impossible. You cannot do it just in a browser window. But it is possible in hybrid applications (e.g. PhoneGap, Rhodes, Titanium) with a bit of help from some native code.