Dario M.
Dario M.

Reputation: 425

Pass some text with javascript into WebView from Xamarin.Forms

I try to send some text into a webView control from xamarin.forms. There are plenty of solution, which I almost all tried... ;-)

So actually they work great, but I have always to click a button on the html file, which I load into this webView, that I can pass some text into the html file. But I would like to pass the text without clicking on this button. The Text should be there, when the webView has loaded.

Here some code:

In the xaml.cs I load the WebView:

  protected override void OnAppearing()
    {
        base.OnAppearing();

        webViewElement.Source = new HtmlWebViewSource();
        webViewElement.Source = DependencyService.Get<IBaseUrl>().Get();

        webViewElement.RegisterAction(ExecuteActionFromJavascript);

        ExecuteSetFromJavascript();
    }

then with ExecuteSetFromJavascript() i call a function which is in the html file:

  private async void ExecuteSetFromJavascript()
    {
        var result = "Hello";
        if (result != null)
        {
          var test =  await webViewElement.EvaluateJavaScriptAsync($"updatetextonwebview('{result}')");
        }
    }

this is the function in the html file:

  function updatetextonwebview(text) {

                                alert(text);

                                   // document.getElementById("content").innerHTML = text;
                                }

So now the page should Alert "Hello" when the updatetextonwebview is called.

but that doesn't make it. Maybe the html page is not ready when i call this funciton!

Does anyone have an idea how I can get to my solution?

Thanks in advance...

Upvotes: 1

Views: 2046

Answers (2)

Dario M.
Dario M.

Reputation: 425

My solution now is: in the HybridWebView I added a property

using System;
using Xamarin.Forms;

namespace CustomRenderer

{
    public class HybridWebView : WebView
    {
        Action<string> action;

        public static readonly BindableProperty UriProperty = BindableProperty.Create(
            propertyName: "Uri",
            returnType: typeof(string),
            declaringType: typeof(HybridWebView),
            defaultValue: default(string));

        public static BindableProperty QuestionProperty = BindableProperty.Create(
            propertyName: "Question",
            returnType: typeof(string),
            declaringType: typeof(HybridWebView),
            defaultValue: default(string));

        public static BindableProperty AnswerProperty = BindableProperty.Create(
            propertyName: "Answer",
            returnType: typeof(string),
            declaringType: typeof(HybridWebView),
            defaultValue: default(string));

        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }

        public string Question
        {
            get { return (string)GetValue(QuestionProperty); }
            set { SetValue(QuestionProperty, value); }
        }

        public string Answer
        {
            get { return (string)GetValue(AnswerProperty); }
            set { SetValue(AnswerProperty, value); }
        }

        public void RegisterAction(Action<string> callback)
        {
            action = callback;
        }

        public void Cleanup()
        {
            action = null;
        }

        public void InvokeAction(string data)
        {
            if (action == null || data == null)
            {
                return;
            }
            action.Invoke(data);
        }
    }
}

which I can access in the JavaScriptWebViewClient and on the OnPageFinished I can submit the data to the webPage.

  public class JavascriptWebViewClient : FormsWebViewClient
{
    string _javascript;
    string _question;
    private string _answer;

    public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript, string question, string answer) : base(renderer)
    {
        _javascript = javascript;
        _answer = answer;
        _question = question;
    }

    public override void OnPageFinished(WebView view, string url)
    {
        base.OnPageFinished(view, url);


        view.EvaluateJavascript($"factorial({_question}, {_answer})", null);

        view.EvaluateJavascript(_javascript, null);
    }
}

Upvotes: 1

Mihail Duchev
Mihail Duchev

Reputation: 4821

What you want is being called a HybridWebView. This means that it can both receive and send data.

I see a lot of inconsistencies and issues with the code that you have provided - why do you configure the WebView in OnAppearing, why is the source being set twice, etc.

Since the provided code is not enough and full of issues and questions - instead of trying to figure out where it did go wrong, you should follow the official guide for creating a HybridWebView from Microsoft - Customizing a WebView.

This is working and also you have the end solution in GitHub available here.

If you have any more questions, feel free to ask them, but I feel that the guide is pretty straight forward.

Upvotes: 0

Related Questions