Android Question Web View not running JavaScript

JohnK

Active Member
Licensed User
Longtime User
This seems soooo easy, and I have searched, but, it didn't seem to help.

I have a web view on my Activity

B4X:
Sub Globals
...snip...
    Dim htmlResults As WebView
...snip...
and it gets initialised later, and loads a web page, with javascript.
B4X:
                htmlResults.Initialize("htmlResults")
                htmlResults.JavaScriptEnabled = True
                htmlResults.LoadURL(sURL)
The web page is loading and displays the correct page (ie sURL), however, the Javascript on the page does not run. When I load the page in a desktop browser, it works correctly. If I load the page into one of my HTML Viewers on my Android device, it also works as expected.

The JavaScript/web page can be reduced down to:
HTML:
<!DOCTYPE html>
<html>
    <body onclick="if (event.target.title != '') { alert(event.target.title);}">
        <span title="Test JS Message" style="position:absolute; top: 0px; left: 0px; width:500px; height:500px; background: #FF0000;"/>
    </body>
</html>

What do I need to add to get this working?
 

JohnK

Active Member
Licensed User
Longtime User
or maybe in a WebView title is just empty?
That's why I supplied the HTML. The title property is filled in, and also the message box is displayed both on the desktop and also in an on device HTML Viewer.

When you click on the big red span element, title="Test JS Message"
 
Upvote 0

Brandsum

Well-Known Member
Licensed User
Do you want to get the website title from webview? Then that code is incorrect. It was for getting the title attribute value of that internal span element.
 
Upvote 0

JohnK

Active Member
Licensed User
Longtime User
Do you want to get the website title from webview? Then that code is incorrect. It was for getting the title attribute value of that internal span element.
That's EXACTLY what I want it to do! i.e. it works exactly as designed on the desktop. i do NOT want the website title; and hence I used "event.target". Think of a page with 100 of these unique elements, it would be pointless if every one of them displayed the exact same data, whereas each different individual element has unique data about that specific element, which is kept in the title attribute. My example above was to reduce it to most simplest, to remove any confusion, but obviously its simplicity caused confusion.

Maybe the next HTML will make it clearer:
HTML:
<!DOCTYPE html>
<html>
    <body onclick="if (event.target.title != '') { alert(event.target.title);}">
        <span title="Super Secret important code A123" style="position:absolute; top: 0px; left: 0px; width:500px; height:100px; background: #FF0000;"/>
        <span title="Super Secret important code B987" style="position:absolute; top: 100px; left: 0px; width:500px; height:100px; background: #00FF00;"/>
    </body>
</html>

When a user hovers over an element (in this case the span) it shows a tool-tip, and if they click on it, it shows a message box with the hidden information. I added the click event, because I don't know how to hover on an android phone.

All I need to know, is how to get Javascript working on a web page, in a webview?
 
Upvote 0

Brandsum

Well-Known Member
Licensed User
Ok now I got you. Your javascript is working fine. But as you want to show an alert popup you have to attach WebChromeClient using WebViewExtra to show the popup. Without WebChromeClient WebView itself cant show an alert popup.

On activity create just add these lines,
B4X:
Private wve As WebViewExtras
Private dcc As DefaultWebChromeClient
wve.Initialize(htmlResults)
dcc.Initialize("")
wve.SetWebChromeClient(dcc)
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Maybe the next HTML will make it clearer

This is the html used
HTML:
<html>
<head>
<title>WebViewExtra Sample</title>
</head>
<body onclick="if (event.target.title != '') { B4A.CallSub('TheContentIs', true, event.target.title);}">
<span title="Super Secret important code A123" style="position:absolute; top: 0px; left: 0px; width:500px; height:100px; background: #FF0000;"/>&nbsp;</span>
<span title="Super Secret important code B987" style="position:absolute; top: 100px; left: 0px; width:500px; height:100px; background: #00FF00;"/>&nbsp;</span>
<h1>WebViewExtra</h1>
This is sample of calling B4A sub in html javascript
</body>
    </body>
<script>
  function doCallBack() {
    var content = document.body.textContent;
    B4A.CallSub('TheContentIs', true, content);
  }
</script>
</html>

This does not show anything but send the value to the code in b4a where i do just LOGging here.

B4X:
Sub TheContentIs(content As String)
    Log($"ContentFrom JS = ${content}"$)
End Sub

*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
ContentFrom JS = Super Secret important code A123
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
ContentFrom JS = Super Secret important code B987
ContentFrom JS = Super Secret important code A123
ContentFrom JS = Super Secret important code B987
ContentFrom JS = Super Secret important code B987
ContentFrom JS = Super Secret important code B987
 

Attachments

  • webviewjs.zip
    9.9 KB · Views: 343
Last edited:
Upvote 0

JohnK

Active Member
Licensed User
Longtime User
This is the html used
HTML:
<html>
<head>
<title>WebViewExtra Sample</title>
</head>
<body onclick="if (event.target.title != '') { B4A.CallSub('TheContentIs', true, event.target.title);}">
<span title="Super Secret important code A123" style="position:absolute; top: 0px; left: 0px; width:500px; height:100px; background: #FF0000;"/>&nbsp;</span>
<span title="Super Secret important code B987" style="position:absolute; top: 100px; left: 0px; width:500px; height:100px; background: #00FF00;"/>&nbsp;</span>
<h1>WebViewExtra</h1>
This is sample of calling B4A sub in html javascript
</body>
    </body>
<script>
  function doCallBack() {
    var content = document.body.textContent;
    B4A.CallSub('TheContentIs', true, content);
  }
</script>
</html>

This does not show anything but send the value to the code in b4a where i do just LOGging here.

B4X:
Sub TheContentIs(content As String)
    Log($"ContentFrom JS = ${content}"$)
End Sub
Thanks for the code, and I have not tried the code, as the page is now not functional for use outside of the B4A web view. I would like the pages to stay functional in a standard browser (both on the device or on a desktop) as well as the webview.

I guess the worst case scenario if the above works for me, is to add extra JS code to enable the page to know if it is running under each of the different environments. However, It must be possible without the B4A specific code, as I can open the page in one of my on device HTML viewers, and the JavaScript works flawlessly.
 
Upvote 0

Brandsum

Well-Known Member
Licensed User
I can open the page in one of my on device HTML viewers, and the JavaScript works flawlessly.
Javascript works on the webview as well. But for alert popup you need WebChromeClient. It actually handles the javascript dialogs for webview. Webview itself cant do this.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
plus you don't have to modify your html and javascript, so everything works across platforms. webchromeclient is just a setting for webview to allow alerts. but, note: a webview is a subset of a browser. not everything that works in a browser works in a webview (alert being a case in point). be thankful that your current html and javascript work in a webview as is.
 
Upvote 0

JohnK

Active Member
Licensed User
Longtime User
Javascript works on the webview as well. But for alert popup you need WebChromeClient. It actually handles the javascript dialogs for webview. Webview itself cant do this.
👍 Yep! that did the trick! Thanks so much.
and just as a cross reference for others that read this, the library can be found at: https://www.b4x.com/android/forum/threads/webviewextras.12453/

plus you don't have to modify your html and javascript, so everything works across platforms. webchromeclient is just a setting for webview to allow alerts. but, note: a webview is a subset of a browser. not everything that works in a browser works in a webview (alert being a case in point). be thankful that your current html and javascript work in a webview as is.
I dont know what you are trying to say, since the JavaScript did NOT work without the above. As for the HTML, i think it would be a jokeon Android if the webview could not read and render valid HTML from over 15 years ago. And one of the big ideas of HTML, is that it is platform independent.
 
Upvote 0
Top