Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iframe does not change when the html string passed to data changes #337

Closed
sivaperumal644 opened this issue Jun 25, 2020 · 3 comments · Fixed by #539
Closed

Iframe does not change when the html string passed to data changes #337

sivaperumal644 opened this issue Jun 25, 2020 · 3 comments · Fixed by #539

Comments

@sivaperumal644
Copy link

I have same screen to display different html content. So my html string gets changed. When the string changes everything changes as expected except the iframe. The iframe renders the first html string data and it does not change when the html string is changed. It shows the same iframe it rendered before instead of the new one.

The iframe is rendered using webview, so I think this could be the issue. In webview when the initialUrl is changed the webview does not change. we must use webview controller to change the url of webview.

@The-Redhat
Copy link
Contributor

The-Redhat commented Aug 6, 2020

You can use a ValueKey with the Checksum of the Html: ValueKey(/**some html String**/),. A different ValueKey forces the framework to rerun initState.

Full example

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';

void main() => runApp(App());

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  String html =
      '<iframe src="https://heise.de" style="border: none;"></iframe>';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Html(
          data: html,
          key: ValueKey(html),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.print),
          onPressed: () => setState(() {
            html =
                '<iframe src="https://google.de" style="border: none;"></iframe>';
          }),
        ),
      ),
    );
  }
}

@erickok
Copy link
Collaborator

erickok commented Feb 8, 2021

This is a tricky one. You are spot-on with your analysis that changing webview's initialUrl won't change the content (as it is really just the initial url) and you need either a key (to force re-creating the iframe/webview) or use a navigation delegate. I guess the latter is better, but am wondering on the (performance) side-effect we create if flutter_html would do this itself. I don't have a great answer yet.

@tneotia
Copy link
Collaborator

tneotia commented Feb 11, 2021

I solved this in the above PR, basically it just checks to see if the url has changed since the last time it received a url, then loads it in the webview if it has. You can test this with the below code:

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/image_render.dart';
import 'package:flutter_html/style.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.deepPurple,
      ),
      home: new MyHomePage(title: 'flutter_html Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

String htmlData = """
      <h3>IFrame support:</h3>
              <iframe src="https://bing.com"></iframe>
""";

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text('flutter_html Example'),
        centerTitle: true,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            if (htmlData.contains("bing")) {
              htmlData = """<h3>IFrame support:</h3>
              <iframe src="https://google.com"></iframe>
              """;
            } else {
              htmlData = """<h3>IFrame support:</h3>
              <iframe src="https://bing.com"></iframe>
              """;
            }
          });
        },
        child: Icon(Icons.change_history),
      ),
      body: SingleChildScrollView(
        child: Html(
          data: htmlData,
        ),
      ),
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants