How to bring focused field into the view using iscroll and Android WebView
Asked Answered
P

2

13

When I focus into a form field at the bottom of iScroll view, it does not scroll up/bring the focused field above the softkeyboad. Any idea? Thank you!

field field

This is the Android project. https://dl.dropboxusercontent.com/u/75818136/webkitdemo.zip

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>iScroll demo: simple</title>

<style type="text/css" media="all">
body,ul,li {
    padding:0;
    margin:0;
    border:0;
}

body {
    font-size:12px;
    -webkit-user-select:none;
    -webkit-text-size-adjust:none;
    font-family:helvetica;
}

#header {
    position:absolute; z-index:2;
    top:0; left:0;
    width:100%;
    height:45px;
    line-height:45px;
    background-color:#d51875;
    background-image:-webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #fe96c9), color-stop(0.05, #d51875), color-stop(1, #7b0a2e));
    background-image:-moz-linear-gradient(top, #fe96c9, #d51875 5%, #7b0a2e);
    background-image:-o-linear-gradient(top, #fe96c9, #d51875 5%, #7b0a2e);
    padding:0;
    color:#eee;
    font-size:20px;
    text-align:center;
}

#header a {
    color:#f3f3f3;
    text-decoration:none;
    font-weight:bold;
    text-shadow:0 -1px 0 rgba(0,0,0,0.5);
}

#footer {
    position:absolute; z-index:2;
    bottom:0; left:0;
    width:100%;
    height:48px;
    background-color:#222;
    background-image:-webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #999), color-stop(0.02, #666), color-stop(1, #222));
    background-image:-moz-linear-gradient(top, #999, #666 2%, #222);
    background-image:-o-linear-gradient(top, #999, #666 2%, #222);
    padding:0;
    border-top:1px solid #444;
}

#wrapper {
    position:absolute; z-index:1;
    top:45px; bottom:48px; left:0;
    width:100%;
    background:#aaa;
    overflow:auto;
}

#scroller {
    position:absolute; z-index:1;
/*  -webkit-touch-callout:none;*/
    -webkit-tap-highlight-color:rgba(0,0,0,0);
    width:100%;
    padding:0;
}

#scroller ul {
    list-style:none;
    padding:0;
    margin:0;
    width:100%;
    text-align:left;
}

#scroller li {
    padding:0 10px;
    height:40px;
    line-height:40px;
    border-bottom:1px solid #ccc;
    border-top:1px solid #fff;
    background-color:#fafafa;
    font-size:14px;
}
</style>

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="iscroll.js"></script>

</head>
<body>

<div id="header"><a href="http://cubiq.org/iscroll">iScroll</a></div>
<div id="wrapper">
    <div id="scroller">
        <ul id="thelist">
            <li>Pretty row 1</li>
            <li>Pretty row 2</li>
            <li>Pretty row 3</li>
            <li>Pretty row 4</li>
            <li>Pretty row 5</li>
            <li>Pretty row 6</li>
            <li>Pretty row 7</li>
            <li>Pretty row 8</li>
            <li>Pretty row 9</li>
            <li>Pretty row 10</li>
            <li>Pretty row 11</li>
            <li>Pretty row 12</li>
            <li>Pretty row 13</li>
            <li>Pretty row 14</li>
            <li>Pretty row 15</li>
            <li>Pretty row 16</li>
            <li>Pretty row 17</li>
            <li>Pretty row 18</li>
            <li>Pretty row 19</li>
            <li>Pretty row 20</li>
            <li>Pretty row 21</li>
            <li>Pretty row 22</li>
            <li>Pretty row 23</li>
            <li>Pretty row 24</li>
            <li>Pretty row 25</li>
            <li>Pretty row 26</li>
            <li>Pretty row 27</li>
            <li>Pretty row 28</li>
            <li>Pretty row 29</li>
            <li>Pretty row 30</li>
            <li>Pretty row 31</li>
            <li>Pretty row 32</li>
            <li>Pretty row 33</li>
            <li>Pretty row 34</li>
            <li>Pretty row 35</li>
            <li>Pretty row 36</li>
            <li>Pretty row 37</li>
            <li>Pretty row 38</li>
            <li>Pretty row 39</li>
            <li><form><input type="text" value="hey" spellcheck="false"></form></li>
        </ul>
    </div>
</div>
<div id="footer"></div>

<script>

var myScroll;
function loaded() {
    myScroll = new iScroll('wrapper');
}

document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
window.addEventListener("resize", function() {
    console.error("=------======-=-=-==");
}, false);


</script>

</body>
</html>
Pettifog answered 2/6, 2013 at 1:26 Comment(2)
How about this link. #7027354Ceric
won't work. I tried this :PBookseller
P
8

I finally found the solution to my question. BTW, this solution will be in my book which will be published soon. I just wanted to share this with the developer community.

First of all, iscroll should handle this matter for us, but somehow it does not.

Also, I think there is a bug in Android API. When I use full-screen mode (in manifest or programmatically), the "resize" event does not get fired in the WebView. No idea why. I already reported this bug to Android team. If you know why this happens, please let us know here. Thanks.

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

// or

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

Here is the solution:

I removed the full-screen mode. Instead, I used res/values/style.xml, requestWindowFeature(android.view.Window.FEATURE_NO_TITLE); and android:theme="@style/Theme" in the application in order to remove the application native title. This solution also works when orientation occurs.

Then, using "focus" event, I captured which element has a focus.

var $elm;

$('input, textarea').bind('focus', function(e) {
    console.error("onFocus");
    $elm = $(this);
});

Then, using "resize" event, I refreshed the iscroll object and then scroll to the $elm.

$(window).bind('resize', function() {
    console.error("onResize");
    if (myScroll !== undefined) {
        setTimeout(function() {
            myScroll.refresh();
            myScroll.scrollToElement($elm[0], 200);
        }, 100);
    }
});

This is the answer to my question, WebKitDemo2.zip

Pettifog answered 9/6, 2013 at 8:17 Comment(1)
The link is not valid anymore. Please, update the link or tell how to use your solution.Termor
G
2

I am not sure whether this is a good answer for your question. I have already faced same issue with soft keyboard & iscroll in a POS device. To sort out this issue I have done a STUPID work.

Steps I have done.

Assume you attached iScroll like this

iScrollObj = new iScroll('ID');

  1. I append a empty div wrapper inside the scroll container at the last if I have input.
  2. When input element get focus but before keyboard pops up I calculate the position of the input field (pi) and height of input (hi)
  3. I get the height of screen (hs), height of keyboard (hk)
  4. By using hs, hk, hi and pi I had calculated an height to empty div wrapper and assigned to it.
  5. To avoid disappointment I had used iScrollObj.refresh() call back function.(because I had dynamically assign height to div wrapper, iScroll sometime response correctly for dynamic adjustments but sometime it fails)
  6. Then I had used iScrollObj.scrollTo(x, y, time) iScroll callback function to move the input up
  7. When I hide the keyboard I set the empty div wrapper height to 0
  8. Now you have to reset. iScrollObj.refresh() and iScrollObj.scrollTo(x, y, time)

Still you can use iScrollObj.scrollToElement(element, time) but I think this is more work. Because element should be the CSS selector of an element in which iScroll with automatically scroll to that element in which it displays that element at the top position in the view. It means in the screen you have attached will say if you use the CSS selector of the Pretty row 34 then it will display from Pretty row 34 to down.

Please Note

Soft keyboard which I use is developed by me (It is a jQuery plugin) therefore I was able to implement all the required callback functions. iScroll already providing lot of callback functions.

Therefore I was able to complete my task and it is working correctly without any problem as we expect.

I do not know the constrains you have. Just shared the STUPID work what I have done.

Pardon me if this is not a proper solution to you.

Thanks.

Gravitation answered 8/6, 2013 at 4:0 Comment(2)
Honestly, I am not looking for an hack. Although this may work, I am looking for an intuitive solution. It's also possible that iScroll examples uses position:absolute; which I am not fan of. It's likely the issue may resides within CSS as well. - nizamPettifog
@Nizzy: Yep I know my solution is intuitive. If you find a solution please update it here so in future it might help me to tackle these situations. I tried lot of ways to find solution then I used this hacking.. :)Gravitation

© 2022 - 2024 — McMap. All rights reserved.