-
Install
webview_flutterflutter pub add webview_flutter
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:convert';
// This message type is prefixed by a special character to avoid collisions with
// other messages that may be sent from the webview.
// so just copy this to avoid errors
const String EMBED_EVENT_MSG = 'ƒ_wee';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late final WebViewController controller;
final flowUrl =
'https://formsorttemplatesdemo.formsort.app/flow/template-patient-onboarding-demo/variant/patient-onboarding-customization';
final String setUpJSWebViewMessaging = """
window.FlutterWebView = true;
window.postMessage = function(data) {
FlutterChannel.postMessage(JSON.stringify(data));
};
""";
@override
void initState() {
super.initState();
controller = WebViewController()
..loadRequest(
Uri.parse(flowUrl),
)
..setJavaScriptMode(JavaScriptMode.unrestricted) // enable javascript
..addJavaScriptChannel('FlutterChannel', onMessageReceived: (event) {
final eventData = jsonDecode(event.message);
if (eventData['type'] == EMBED_EVENT_MSG) {
// get messages from the flow
switch (eventData['eventType']) {
case 'FlowCompleted':
print('Flow completed');
break;
case 'FlowLoaded':
print('Flow loaded');
break;
default:
break;
}
}
})
..setNavigationDelegate(NavigationDelegate(onPageFinished: (ulr) {
controller.runJavaScript(setUpJSWebViewMessaging);
}));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: WebViewWidget(
controller: controller,
),
);
}
}Formsort flows will send messages to the parent window when certain events occur. You can listen for these events by setting up javaScriptChannel in WebViewController. The event data will be available in the event.message property. Full list of available events can be found in formsort docs here.
By default, formsort keeps user information locally and don't restart flows when the user comes back to the flow. You can change this behavior in two ways:
-
You can set returning responder behavior in flow settings in formsort studio. see formsort docs for more information.
-
Use the
flowUrlparameter?discardAnswers=trueto restart the flow every time the user comes back to the flow. e.g.final flowUrl = 'https://formsorttemplatesdemo.formsort.app/flow/template-patient-onboarding-demo/variant/patient-onboarding-customization?discardAnswers=true';