locked
WebView difficulties RRS feed

  • Question

  • User394407 posted

    I am new to Xamarin and am trying to port an application that I once wrote for Windows Phone to Android, iOS and eventually Duo. I have an html page that i need to display. There is embedded JavaScript in the html. In Windows Phone, once the page was loaded, I was able to execute the code with the following: webBrowser.IsScriptEnabled = true; webBrowser.InvokeScript("InitPage", dayOfWeek.ToString()....) where "InitPage" is a function inside the html document.

    (I am using the same html file for this app - I would would rather not change it if not necessary) I have decided to use WebView to display the html. I have added a callback: webView.Navigated += WebView_Navigated; and in the callback, I think i need to call EvaluateJavaScriptAsync

    I cannot figure out how to call the InitPage method and pass the required params with it.

    ALSO, I can't seem to get the view to scroll.

    Am I using the wrong control? I would appreciate any help in getting me past this roadblock thanks

    Tuesday, May 5, 2020 3:12 PM

Answers

  • User382871 posted

    Try to define the JavaScript function in a HTML file. Check the link. string result = await webView.EvaluateJavaScriptAsync($"factorial({number})"); Html code:

    <script type="text/javascript">

    function factorial(num) {

    ...

    }

    </script>

    If you want to call EvaluateJavaScriptAsync function using a script string directly, you need to inject the JavaScript code in the onPageFinished method of WebViewClient. You could google the keyword with Inject JavaScript into Android WebView to check the related tutorial on native android.




    Friday, May 15, 2020 8:18 AM

All replies

  • User382871 posted

    I cannot figure out how to call the InitPage method and pass the required params with it. You could create a custom WebView and achieve the function in each platform project.

    Custom webView class. ``` public class CustomWebView : WebView { public static BindableProperty EvaluateJavascriptProperty = BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func>), typeof(CustomWebView), null, BindingMode.OneWayToSource);

    public Func<string, Task<string>> EvaluateJavascript
    {
        get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
        set { SetValue(EvaluateJavascriptProperty, value); }
    }
    

    } WebViewRender class. [assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRender))] namespace Mobile.Droid {
    public class CustomWebViewRender : WebViewRenderer { protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e);

            var webView = e.NewElement as CustomWebView;
            if (webView != null)
                webView.EvaluateJavascript = async (js) =>
                {
                    ...
                };
        }
    }
    

    } ```

    You could goolge with the keyword as Xamarin Forms WebView Executing Javascript to check the related tutorial.

    Wednesday, May 6, 2020 9:45 AM
  • User394407 posted

    Thank you for your reply....
    I am not looking for a way to get a reply from the JS.
    The JS function hides sections of the document based on parameters that are passed. In other words the HTML page contains an entire document, including various versions of the same paragraph. I pass parameters to the JS function and some sections are hidden so that the final html document that is displayed shows only a subset.
    It seems that the function does get called. but it doesn't seem to do anything. I do not get an error either, but the result string is null

    string result = await webView.EvaluateJavaScriptAsync($"InitPage({parm1}, {parm2}, {parm3}");

    the HTML Page looks like this:

    MyPage

        function InitPage(parm1, parm2 parm3)

    {
    if (param1 == "1") {
    section1.style.display = HIDDEN;

    etc.

    A thought that i had is maybe the html is being changed, but since I am calling it on the Navigated event it is already displayed. is there a way to tell WebView to refresh without reloading the original page?

    Wednesday, May 6, 2020 10:46 AM
  • User382871 posted

    is there a way to tell WebView to refresh without reloading the original page? The refreshing operation should be added in the js, set JavaScriptInterface to injects the supplied Java object into this WebView in custom renderer class. You could do the updating work in the custom JavaScriptInterface class.

    Check the code: ``` protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e);

    Control.AddJavascriptInterface(new JavaScriptInterface(_context), "TextSelection");.
    

    }

    class JavaScriptInterface : Java.Lang.Object { Context context; public JavaScriptInterface(Context context) { this.context = context; }

    [Export]
    [JavascriptInterface]
    public void upatingMethod(string value)
    {
        //
    }
    

    } Call the method in js. function ButtonClick() { TextSelection.upatingMethod('value') } ``` Similar issue: https://forums.xamarin.com/discussion/comment/344622/#Comment_344622

    Thursday, May 7, 2020 10:00 AM
  • User394407 posted

    I am sorry, but i am very confused. so what I have done is gone back and simplified. I have removed the function from the origianl html page so all it does is load the page will all the sections in it.

    next i created a JS function that is supposed to hide some of the sections. i get the follwooing error System.Exception HResult=0x80020101 Message=Exception from HRESULT: 0x80020101 Source=System.Private.CoreLib StackTrace: at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Xamarin.Forms.Platform.UWP.WebViewRenderer.d12.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Xamarin.Forms.WebView.d25.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() atMyDocument.MyPage.d6.MoveNext() in C:\Users\MR\OneDrive\Projects\MyDocument\App1\MyPage.cs:line 128 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() atMyDocument.MyPage.d4.MoveNext() in C:\Users\MR\OneDrive\Projects\MyDocument\App1\MyPage.cs:line 88

    SO i simplified it even more an created a simple function as follows but still get the same error function RenderPage() { var a = 1; var b = a; }

    what is the format that the JavaScript should be for the webView.EvaluateJavaScriptAsync(JS) call?

    Friday, May 8, 2020 1:18 PM
  • User382871 posted

    System.Exception HResult=0x80020101 Message=Exception from HRESULT: 0x80020101 Source=System.Private.CoreLib That error occurs when there is a syntax error in the javascript. https://stackoverflow.com/questions/10312088/webview-invokescript-hresult-0x80020101

    what is the format that the JavaScript should be for the webView.EvaluateJavaScriptAsync(JS) call? Check the tutorial about the csutom webview renderer. https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview#create-the-custom-renderer-on-android And here is the official sample, you can refer to: https://docs.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/customrenderers-hybridwebview/

    Monday, May 11, 2020 8:40 AM
  • User394407 posted

    Again, I apologize. I think that what you are proposing is more complicated than I need. At this point I am just trying to test the WebView control i have created a JS function as a string, called stringJS like this:

    script language = 'javascript' type = 'text/javascript'< ( <> are swapped otherwise this comment would not show properly) function Alert() { alert('this is an alert') } /script<

    i then call: await webView.EvaluateJavaScriptAsync(stringJS)

    i get the exception 0x80020101

    i then tried

    script< function Alert() { alert('this is an alert') } /script<

    I get the same exception I do not see any syntax errors

    WHAT AM I DOING WRONG? :s (I am very frustrated)

    Thursday, May 14, 2020 9:06 AM
  • User382871 posted

    Try to define the JavaScript function in a HTML file. Check the link. string result = await webView.EvaluateJavaScriptAsync($"factorial({number})"); Html code:

    <script type="text/javascript">

    function factorial(num) {

    ...

    }

    </script>

    If you want to call EvaluateJavaScriptAsync function using a script string directly, you need to inject the JavaScript code in the onPageFinished method of WebViewClient. You could google the keyword with Inject JavaScript into Android WebView to check the related tutorial on native android.




    Friday, May 15, 2020 8:18 AM
  • User394407 posted

    this helped me resolve the problem!!!!! thanks!!!!!

    Friday, May 15, 2020 1:20 PM