Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid WebView - Setting HTML Field focus using Javascript
    primarykey
    data
    text
    <p>I have an application with just a visible <code>WebView</code> component to it which is used to display some dynamically generated HTML (can run Javascript too). It's enabled for the <code>WebView</code>.</p> <p>For a few pages I am trying to set the focus of one of the input text boxes after the page load has finished - <strong>not through</strong> Body <code>onLoad()</code>, but instead by a JS call after the page has finished loading i.e. in <code>onPageFinished()</code>. Most of the javascript executes fine </p> <pre><code> webview.loadURL("javascript:JSMethod();"); </code></pre> <p>But when I use the same call to do a <code>document.getElementById('text1').focus()</code> - the cursor does reach the element but the <code>Soft Keyboard</code> won't pop out. The same javascript code when executed from a button on the page does have the desired effect. </p> <p>I am attaching the source code which has <strong>3 buttons</strong></p> <ol> <li><code>Focus Text1</code> - Put the cursor on the text1 and pops up the Softkeyboard.</li> <li><code>Java Focus Text1</code> - Calls Java to execute the same JS. Only shows the cursor there and doesn't pop out the keyboard</li> <li><code>Java Focus Text1 And Keyboard Open</code> - Calls JS from Java and Forces Keyboard open.</li> </ol> <p>My understanding is that the JS execution should work the same whether executed from the browser using a button/event or as sent from Java through <code>WebView.loadURL()</code>. </p> <p>Here's my <strong>Queries</strong></p> <ol> <li>Am I missing something when using <code>Button#2</code>? That's how my current code is and I only see the cursor is set but the SoftKeyboard won't open.</li> <li>When I use logic as written in <code>Button#3</code>, I some times don't see the cursor on the field but gives me the desired effect and the cursor becomes visible when I type something in the popped up keyboard.</li> <li>Could the behavior I see in <code>Button#2</code> be a bug in Android JS execution? Or could it be that the <code>WebView</code> doesn't have focus that's why only the cursor is displayed? I also tried <code>webview.requestFocus()</code> - I can't write <code>requestFocusOnTouch()</code> as it's the only View I have and am expecting it's focused automatically.</li> </ol> <p>The Java code which demos the behavior is </p> <pre><code> import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.inputmethod.InputMethodManager; import android.webkit.JsResult; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; public class WebViewProjectTestJSHTMLFocusActivity extends Activity { Activity _current = null; WebView wv = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); _current = this; //setContentView(R.layout.main); String data = "&lt;html&gt;&lt;body&gt;" + "&lt;script&gt;function focusser() { document.getElementById(\"text1\").focus(); } &lt;/script&gt;" + "&lt;script&gt;function javaFocusser() { javautil.javaFocus(false); } &lt;/script&gt;" + "&lt;script&gt;function javaFocusserKeyboard() { javautil.javaFocus(true); } &lt;/script&gt;" + "Text 1&lt;input type='text' id='text1'/&gt;&lt;br/&gt;" + "Text 2&lt;input type='text' id='text2'/&gt;&lt;br/&gt;" + "&lt;input type='button' value='Focus Text1' onClick='focusser()'/&gt;" + "&lt;input type='button' value='Java Focus Text1' onClick='javaFocusser()'/&gt;" + "&lt;input type='button' value='Java Focus Text1 And Keyboard Open' onClick='javaFocusserKeyboard()'/&gt;" + "&lt;/body&gt;&lt;/html&gt;"; wv = new WebView(this); wv.getSettings().setJavaScriptEnabled(true); // Set some HTML wv.loadDataWithBaseURL("file:///android_asset/", data, "text/html", "UTF-8", null); // Call back required after page load finished wv.setWebViewClient(new CustomWebViewClient()); // Enable Alert calls wv.setWebChromeClient(new CustomWebChromeClient()); // For JS-&gt;Java calls wv.addJavascriptInterface(this, "javautil"); setContentView(wv); } /** * Calls the same javascript and forces the keyboard to open */ public void javaFocus(final boolean shouldForceOpenKeyboard) { Thread t = new Thread("Java focusser thread") { public void run() { wv.loadUrl("javascript:focusser();"); if(shouldForceOpenKeyboard) { InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mgr.showSoftInput(wv, InputMethodManager.SHOW_IMPLICIT); } } }; // Run on the View Thread. _current.runOnUiThread(t); } /** * Calls focus method after the page load is complete. */ final class CustomWebViewClient extends WebViewClient { @Override public void onPageFinished(WebView view, String url) { // javaFocus(true); Log.d("TestExamples", "focusser call complete"); } } final class CustomWebChromeClient extends WebChromeClient { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { Log.d("TestExamples", "JS Alert :: " + message); return false; } } } </code></pre> <p><strong>Solution Update 24-06-2011</strong> To make this work, you need to use <code>wv.requestFocus(View.FOCUS_DOWN)</code> just before the actual JS focus call. I modified the <code>javaFocus()</code> method above to the correct version below. Earlier when I mentioned that I was using requestFocus(), I was using that when the <code>WebView</code> was initialized in the method <code>onCreate()</code>. The primary difference is now we're forcing the <code>WebView</code> to get focus each time just before the Javascript <code>document.getElementById("text1").focus();</code> is executed. </p> <pre><code>public void javaFocus(final boolean shouldForceOpenKeyboard) { Thread t = new Thread("Java focusser thread") { public void run() { wv.requestFocus(View.FOCUS_DOWN); wv.loadUrl("javascript:focusser();"); if(shouldForceOpenKeyboard) { InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mgr.showSoftInput(wv, InputMethodManager.SHOW_IMPLICIT); } } }; // Run on the View Thread. _current.runOnUiThread(t); } </code></pre> <p>Also to ensure that this issue wasn't fixed because of focus triggered through touch etc, I am using a background thread to initiate the javaFocus() after 5 seconds of WebView Displayed. The modified <code>onCreate()</code> is below. </p> <pre><code>..... More onCreate code before.... // Enable Alert calls wv.setWebChromeClient(new CustomWebChromeClient()); // For JS-&gt;Java calls wv.addJavascriptInterface(this, "javautil"); setContentView(wv); new Thread("After sometime Focus") { public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } javaFocus(true); } }.start(); .... onCreate() ends after this.... </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload