Art
Art

Reputation: 227

Run some Javascript in Flutter Webview

How can I run Javascript in flutter_webview_plugin? I tried with this:

onPressed: () {
   flutterWebviewPlugin.evalJavascript('<script language="JavaScript" type="text/javascript">alert("Hello World")</script>');
},

But nothing happens.

I thought with flutterWebviewPlugin.evalJavascript it's possible to run Javascript in a Webview. Did I do something wrong?

Upvotes: 18

Views: 65615

Answers (7)

Abdulazeez Oriaje
Abdulazeez Oriaje

Reputation: 129

I got this to work by registering my custom javascript function to the global window object.

  window.onMessageSending = (running)=> {
      console.log("state is running")
    }

Then I called in flutter_webview widget this way:

   _controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..setNavigationDelegate(NavigationDelegate(
    onPageStarted: (String url) {},
    onPageFinished: (String url) {
    },
  ));


 _controller.runJavaScript("onMessageSending(true)");

Upvotes: 0

Cesar Devesa
Cesar Devesa

Reputation: 1307

My best way with onPressed function using the webview_flutter. Use 'runJavascript' or evaluateJavascript or 'runJavascriptReturningResult':

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';


dynamic ctrl; // Created here to keep working with Hot Reload

void main() {
  runApp(
    MaterialApp(
      home: WebViewExample(),
    ),
  );
}

class WebViewExample extends StatefulWidget {
  @override
  WebViewExampleState createState() => WebViewExampleState();
}

class WebViewExampleState extends State<WebViewExample> {
  @override
  void initState() {

    super.initState();

    // Enable virtual display.
    if (Platform.isAndroid) WebView.platform = AndroidWebView();

  }


  @override
  Widget build(BuildContext context) {

    void runJS(command) async {
      ctrl.runJavascript(command);

      // If you get any result
      // dynamic r = await ctrl.runJavascriptReturningResult(command);
      // print(r);
    }

    return Scaffold(
      appBar: AppBar(
          title: Container(
        child: ElevatedButton(
          onPressed: () => {
            runJS('alert("Hello: Button Clicked! "+new Date())')
          },
          child: const Text('Click on the button'),
        ),
      )),
      body: WebView(
        initialUrl:
            'https://www.google.com',

        debuggingEnabled: true,

        onWebViewCreated: (WebViewController webViewController) {
         
          ctrl = webViewController;
         
          ctrl.runJavascript('alert("Hello: created!")');
          // ctrl.evaluateJavascript('alert("Hello: created!")');
          // ctrl.runJavascriptReturningResult('alert("Hello: created!")');
        },

        onPageStarted: (String url) async {
          // ctrl.runJavascript('alert("Hello: started!")');
          // ctrl.evaluateJavascript('alert("Hello: started!")');
          // ctrl.runJavascriptReturningResult('alert("Hello: started!")');
        },

        onPageFinished: (String url) async {
          // ctrl.runJavascript('alert("Hello: finished!")');
          // ctrl.evaluateJavascript('alert("Hello: finished!")');
          // ctrl.runJavascriptReturningResult('alert("Hello: finished!")');
        },
      ),
    );
  }
}

Upvotes: 0

Lorenzo Pichilli
Lorenzo Pichilli

Reputation: 3429

You can try my plugin flutter_inappwebview, which is a Flutter plugin that allows you to add inline WebViews or open an in-app browser window and has a lot of events, methods, and options to control WebViews.

To run some js, you can use:

  • Future<dynamic> evaluateJavascript({@required String source}): Evaluates JavaScript code into the WebView and returns the result of the evaluation.
  • Future<void> injectJavascriptFileFromUrl({@required String urlFile}): Injects an external JavaScript file into the WebView from a defined url.
  • Future<void> injectJavascriptFileFromAsset({@required String assetFilePath}): Injects a JavaScript file into the WebView from the flutter assets directory (see more here on how to load a file from the assets folder).

Full example:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialUrl: "https://www.example.org/",
                    initialHeaders: {},
                    initialOptions: InAppWebViewWidgetOptions(
                      inAppWebViewOptions: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

                    },
                    onLoadStop: (InAppWebViewController controller, String url) async {
                      int result1 = await controller.evaluateJavascript(source: "10 + 20;");
                      print(result1); // 30

                      String result2 = await controller.evaluateJavascript(source: """
                        var firstname = "Foo";
                        var lastname = "Bar";
                        firstname + " " + lastname;
                      """);
                      print(result2); // Foo Bar

                      // inject javascript file from an url
                      await controller.injectJavascriptFileFromUrl(urlFile: "https://code.jquery.com/jquery-3.3.1.min.js");
                      // wait for jquery to be loaded
                      await Future.delayed(Duration(milliseconds: 1000));
                      String result3 = await controller.evaluateJavascript(source: "\$('body').html();");
                      print(result3); // prints the body html

                      // inject javascript file from assets folder
                      await controller.injectJavascriptFileFromAsset(assetFilePath: "assets/myJavascriptFile.js");
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

Upvotes: 4

Pranay Dutta
Pranay Dutta

Reputation: 2591

This is how your Webview widget should look like

WebView(
    initialUrl: 'http://<domain>',
    javascriptMode: JavascriptMode.unrestricted,
    onWebViewCreated: (WebViewController webViewController) {
      webViewController.evaluateJavascript(
          'alert('hello from flutter)');
    }

Make use of webViewController anywhere in your code

Upvotes: 2

alexdabest
alexdabest

Reputation: 71

Well, nothing happened because flutter webview does not support javascript alert function. Try writing a javascript function that changes the value of the innerText of an HTML element and then call the function using .evalJavascript to see the result.

Upvotes: 1

JerryZhou
JerryZhou

Reputation: 5166

I have debug with iOS part of flutter_webview_plugin.

For iOS part

Found it's related to iOS native part iOS WKWebView not showing javascript alert() dialog .

Good example of implement code are at gist.

I have create a fix for this.

Temp solution

You can use

flutter_webview_plugin:
    git:
      ref: "dev/fix_alert_not_work_in_webview"
      url: "https://github.com/jerryzhoujw/flutter_webview_plugin"
      source: git

this as temp in pubspec.yaml before merge PR.

Upvotes: 0

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657476

flutterWebviewPlugin.evalJavascript('<script language="JavaScript" type="text/javascript">alert("Hello World")</script>')

expects JavaScript, not HTML

<script language="JavaScript" type="text/javascript">alert("Hello World")</script>

is HTML.

Try

flutterWebviewPlugin.evalJavascript('alert("Hello World")')

Upvotes: 21

Related Questions