How to import js library properly in dart? Flutter web application - javascript

I want to render a YooKassa widget in flutter app, so I've written this code to implement it
https://yookassa.ru/checkout-widget/v1/checkout-widget.js
#JS()
library checkout-widget.js;
import 'package:js/js.dart';
#JS('YooMoneyCheckoutWidget')
class YooMoneyCheckoutWidget {
external YooMoneyCheckoutWidget(YooMoneyCheckoutWidgetParams params);
external render(String viewID);
}
#JS()
#anonymous
class YooMoneyCheckoutWidgetParams {
external factory YooMoneyCheckoutWidgetParams({
String confirmation_token,
String return_url,
Map<String, dynamic> customization,
Function error_callback
});
}
class YooKassa {
YooMoneyCheckoutWidget _checkoutWidget;
YooKassa({String confirmation_token,String return_url}):_checkoutWidget = YooMoneyCheckoutWidget(YooMoneyCheckoutWidgetParams(confirmation_token: confirmation_token, return_url: return_url, customization: {'colors': {'controlPrimary':'#00BF96'}},error_callback: null));
void render(String viewID) => _checkoutWidget.render(viewID);
}
then trying to call the constructor for a JS code
final widget = YooKassa(confirmation_token: 'ct-2834a83d-000f-5000-9000-1316627a4610',return_url: 'https://app.moneyhat.ru/');
and then render it in DivElement in a HTMLElement
final wrapper = html.DivElement()
..style.width = '100%'
..style.height = '100%'
..id = 'pay-form';
ui.platformViewRegistry.registerViewFactory(
viewID,
(int viewId) => wrapper,
);
widget.render('pay-form');
return Scaffold(
body: SizedBox(
height: 500,
child: HtmlElementView(
viewType: viewID,
),
));
}
What's wrong here? Flutter raises an error - YooMoneyCheckoutWidget is not a constuctor

Related

how can I remove header and footer in Flutter WebView?

This is what I used
There's this video by Joannes Mike on YouTube I followed on how to remove header and footer in Flutter WebView but it seems flutter had upgraded her library and this functions don't work anymore.
Been at this for days and it seems no recent info is available.
Heres my code
import 'package:sportybet_betting_tips/main.dart';
import 'package:webview_flutter/webview_flutter.dart';
class sportybet_tips extends StatefulWidget {
const sportybet_tips({super.key});
#override
State<sportybet_tips> createState() => _sportybet_tipsState();
}
class _sportybet_tipsState extends State<sportybet_tips>
{
late final WebViewController controller;
#override
void initState(){
super.initState();
controller = WebViewController()
..loadRequest(Uri.parse('https://accessbettingtips.com/sportybet/'),);
// controller.addJavaScriptChannel(
// "document.getElementsByTagName('header')[0].style.display='none'", onMessageReceived: (JavaScriptMessage ) { });
// controller.loadRequest(Uri.parse('http://accessbettingtips.com'),);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sportybet Betting Tips'),
),
body: WebViewWidget(controller: controller),
// controller.evaluateJavascript(
// "document.getElementsByTagName('header')[0].style.display='none'");
// controller.loadRequest(Uri.parse('http://accessbettingtips.com'),);
);
}
// webview_flutter({required JavaScriptMode JavaScriptMode, required String initialUrl}) {}
}
in your onPageFinished method write like that :
onPageFinished: (url) async {
controller.runJavascript("document.getElementsByTagName('header')[0].style.display='none'");
},

How can I use main.dart variable in my JS file?

I'm trying to create a calling app using flutter and I've created the backend using a node.js. This is how my main.dart file in flutter looks like:
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter_dialpad/flutter_dialpad.dart';
import 'dart:js';
import 'package:js/js.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child:
DialPad(
enableDtmf: true,
outputMask: "(000) 000-0000",
backspaceButtonIconColor: Colors.red,
makeCall: (number){
print(number);
}
)
),
),
);
}
}
I want to use this "number" variable in my app.js file which looks like this:
const accountSid = '***';
const authToken = '***';
const client = require('twilio')(accountSid, authToken);
client.calls.create({
url: 'http://demo.twilio.com/docs/voice.xml',
to: '+10000000',
from: '+1000000',
}, function(err, call){
if (err) {
console.log(err);
} else {
console.log(call.sid);
}
})
I want to be able to use the "number" variable from my main.dart file in the "to" field in my app.js file. Please help me out...
What you need is a way to pass data between applications, and the easiest way for that would be through a REST API
You can use the HTTP module in NodeJS or a third-party package like Express and set up a POST Route to your NodeJS Server, where the number is sent as data.
Once the data is received on your server, you can call your Twilio function, and send a response back.
On Flutter, you can use the http package to make the API call.

evaluate javascript takes too long in flutter webview?

I am trying to build a flutter app and I am trying to show up website in a webview I am using "flutter_webview_plugin: ^0.3.11" now I am trying to evaluate some javascript in order to delete some items before displaying the web page here is the code of the webview:
#override
Widget build(BuildContext context) {
return WebviewScaffold(
url: 'https://www.amazon.com',
appBar: AppBar(
title: Text('Amazon store'),
),
initialChild: WebviewAnimation(),
withJavascript: true,
);
and here is the code of evaluating I am listening to onStateChanged like below:
void initState() {
super.initState();
_onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((event) {
this.url = event;
});
_onStateChanged =
flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) {
if (mounted) {
setState(() {
flutterWebViewPlugin.hide();
var kiki = flutterWebViewPlugin.evalJavascript(
"document.getElementsByClassName(\"a-button-stack\")[0].style.display='none';");
_history.add('onStateChanged: ${state.type} ${state.url}');
kiki.then((value) {
setState(() {
flutterWebViewPlugin.show();
});
});
});
}
});
by doing this I am able to evaluate js, the problem is it takes too long to evaluate, therefore I want to show up the page once it has been evaluated...any ideas ...thanks in advance

Dart: Load an html file into a Flutter Webview

Sthg makes me crazy, I try to write an html file on the disk using the path_provider plugin with the dart:io library.
Here is what I tried (OKAY):
Future<File> writeFile() async {
final file = await _localFile;
return file.writeAsString('<!DOCTYPE html><html lang="fr"> <head> <meta charset="UTF-8"> <title>test_design</title> ...');
}
then the file is loaded in a webview: OKAY
But if I try with a longer html file, it doesn't work anymore, eg :
return file.writeAsString(' html file containing js ');
Any idea?
or how to load an html file (the file is not static) in a Flutter webview ?
I use flutter_webview_plugin.dart
(https://pub.dartlang.org/packages/flutter_webview_plugin)
webview code :
writeFile().then((file){
readFile().then((r){
_localPath.then((path){
var uri='file:///'+path+'/index.html';
flutterWebViewPlugin.launch(uri,
rect: new Rect.fromLTWH(
0.0,
400.0,
MediaQuery.of(context).size.width,
200.0,
),
);
IMO, this is the approach for this:
This is an example approach, I will be building a Flutter app that can read file and write data to file for later use.
It is an app that could write the String to text.txt file. Everytime the app is launched it will display the contents of text.txt.
I need a place to write data on disk and read it again when the app loads. So I used path_provider plugin to access Documents directory (on iOS, this corresponds to NSDocumentDirectory, on Android, this is the AppData directory).
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Create a reference to the File full location (in our case, the text.txt file), we use File class from the dart:io library.
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/text.txt');
}
Need to write a string to a file using File writeAsString() method. It returns a Future<File> that completes with this File object once the entire operation has completed.
By default, writeAsString() creates the file and truncates the file if it already exists.
To append data to existing file, pass FileMode.append mode as second parameter.
Future<File> writeFile(String text) async {
final file = await _localFile;
return file.writeAsString('$text\r\n', mode: FileMode.append);
}
Use File readAsString() method to read the entire contents as a string. It returns a Future<String> that completes with the string once contents has been read.
Future<String> readFile() async {
try {
final file = await _localFile;
String content = await file.readAsString();
return content;
} catch (e) {
return '';
}
}
Here is the complete sample code:
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'dart:io';
void main() {
runApp(
MaterialApp(
title: 'Read/Write Files',
home: MyApp(storage: TextStorage()),
),
);
}
class TextStorage {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/text.txt');
}
Future<String> readFile() async {
try {
final file = await _localFile;
String content = await file.readAsString();
return content;
} catch (e) {
return '';
}
}
Future<File> writeFile(String text) async {
final file = await _localFile;
return file.writeAsString('$text\r\n', mode: FileMode.append);
}
Future<File> cleanFile() async {
final file = await _localFile;
return file.writeAsString('');
}
}
class MyApp extends StatefulWidget {
final TextStorage storage;
MyApp({Key key, #required this.storage}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController _textField = new TextEditingController();
String _content = '';
#override
void initState() {
super.initState();
widget.storage.readFile().then((String text) {
setState(() {
_content = text;
});
});
}
Future<File> _writeStringToTextFile(String text) async {
setState(() {
_content += text + '\r\n';
});
return widget.storage.writeFile(text);
}
Future<File> _clearContentsInTextFile() async {
setState(() {
_content = '';
});
return widget.storage.cleanFile();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Read/Write File Example'),
backgroundColor: Colors.blue,
),
body: Container(
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
TextField(
controller: _textField,
),
Padding(
padding: EdgeInsets.all(20.0),
child: RaisedButton(
child: Text('Write to File'),
color: Colors.lightBlueAccent,
onPressed: () {
if (_textField.text.isNotEmpty) {
_writeStringToTextFile(_textField.text);
_textField.clear();
}
},
),
),
Padding(
padding: EdgeInsets.only(bottom: 20.0),
child: RaisedButton(
child: Text(
'Clear Contents',
style: TextStyle(color: Colors.white),
),
color: Colors.grey,
onPressed: () {
_clearContentsInTextFile();
},
),
),
Expanded(
flex: 1,
child: new SingleChildScrollView(
child: Text(
'$_content',
style: TextStyle(
color: Colors.blue,
fontSize: 22.0,
),
),
),
),
],
),
),
);
}
}
Here's how it looks when run:
You can play around depending on your requirement.
Also for your other question on how to load an html file in Flutter webview, here is my approach:
You can actually make it work using the webview_flutter plugin.
Create an assets folder in the root directory of your Flutter application, then put your .html file in the assets folder.
You should add your .html file to under assets in your pubspec.yaml file.
pubspec.yaml
assets:
- assets/SampleHtml.html
Here is a sample implementation to load an html from a local file:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<String> localLoader() async {
return await rootBundle.loadString('assets/SampleHtml.html');
}
#override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: localLoader(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return WebView(
initialUrl:
new Uri.dataFromString(snapshot.data, mimeType: 'text/html')
.toString(),
javascriptMode: JavascriptMode.unrestricted,
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
});
}
}
SampleHtml.html
<!DOCTYPE html>
<meta charset="utf-8">
<title>Sample HTML</title>
<html>
<head>
<link rel="stylesheet">
</head>
<body>
<h1>Flutter Webview</h1>
<p>A Flutter plugin that provides a WebView widget.</p>
<ul>
<li>List 1</li>
<li>List 2</li>
<li>List 3</li>
</ul>
</body>
</html>
This is how it looks like:

Aurelia Templating Engine compose

I'm trying to compose component dynamically through code (not with <compose>) and add it to the DOM from a service (similar to a popup).
From my understanding, the best way is to use the TemplatingEngine via .compose method.
I cannot find a decent documentation or small sample on how this is used exactly.
This is what I have so far
constructor(
loggerFactory: LoggerFactory,
private bindingEngine: BindingEngine,
private templatingEngine: TemplatingEngine,
private container: Container,
private viewResources: ViewResources
) {
const hostee = this.templatingEngine.compose({
host: document.body,
container: this.container,
bindingContext: {
},
viewModel: SnackbarHostElement,
viewResources: this.viewResources,
viewSlot: new ViewSlot(document.body, true)
});
hostee.then(x => {
x.attached();
});
I'm getting no errors and .then is being triggered, however, the component doesn't seem to be rendering. Any help would be appreciated!
This is the final code (thanks #Fabio)
async init(): Promise<View | Controller> {
const viewController = await this.templatingEngine.compose({
host: document.body,
container: this.container,
bindingContext: {
},
viewModel: this.container.get(SnackbarHostElement),
viewResources: this.viewResources,
viewSlot: new ViewSlot(document.body, true)
});
viewController.attached();
return viewController;
}
I just use the method like this, wishes to help you!
const View = await this.templatingEngine.compose({
host: this.element,
container: this.container,
bindingContext: this.bindingContext,
overrideContext: this.overrideContext,
viewModel: this.container.get(CustomComponent),
viewResources: this.viewResources,
viewSlot: new ViewSlot(this.element, true),
});

Categories

Resources