Flutter won't pick up javascript file from script tag in html widget - javascript

I am displaying a Leaflet.js map by passing HTML to the EasyWebView widget (https://pub.dev/packages/easy_web_view). I do not want to include my JavaScript code inside the variable htmlData. Instead, I have created a tag that references my JavaScript file.
<script src="script.js" defer></script>
However, the problem I am facing is that it is not picking up the file. If I reference the JavaScript file in the index.html file located in the web folder, it does work.
Here is my code in the main.dart file
import 'package:easy_web_view/easy_web_view.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Web + JS'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final key = const ValueKey('key_0');
String htmlData = '''
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.9.3/dist/leaflet.css"
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.9.3/dist/leaflet.js"
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
crossorigin=""></script>
</head>
<body>
<div id="map" style="width: 100%; height: 800px;"></div>
<script src="script.js" defer></script>
</body>
''';
#override
Widget build(BuildContext context) {
return EasyWebView(
src: htmlData,
onLoaded: (key) {},
isMarkdown: false,
convertToWidgets: false,
key: key,
);
}
}
This is the structure of my folder.
dependencies
name: flutter_web_js
description: "".
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ">=2.17.1 <3.0.0"
dependencies:
flutter:
sdk: flutter
easy_web_view: ^1.6.0
js: ^0.6.4
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.1
flutter:
uses-material-design: true
assets:
- web
- web/script.js
- lib

Related

How to organize and use Web Components?

I want to use web components, but I don't want to write all the contents in the same file. How to implement it? person-panel in index.html has been added in the server,not js.
file structure
/index.html
/index.js
/PersonPanel/personPanel.js
/PersonPanel/template.html
index.html
<html>
<head>
<script src="index.js" type="module" />
</head>
<body>
<person-panel></person-panel>
</body>
</html>
index.js
import personPanel from './PersonPanel/personPanel.js';
// other operations that may require a PersonPanel
template.html
<template>
<label class="field"></label>
</template>
personPanel.js
class PersonPanel extends HTMLElement {
constructor() {
super();
this.attachShadow({mode : 'open'});
// how to fetch template?
}
static get observedAttributes() {
return ['field'];
}
attributeChangedCallback(name, oldValue, newValue) {
if(name == 'field'){
this.shadowRoot.querySelector('label.field').innerText = newValue;
}
}
}
window.customElements.define('person-panel', PersonPanel);
export default PersonPanel;

ArcGIS API for JavaScript 4.18.1 - Angular 11, Typescript, NPM

I am looking at ArcGIS Javascript API 4.18.1. But it is confusing, how I should add it to a new Angular 11 project. Is there an example project somewhere that shows the basic folder structure and getting a map setup in Angular 11? I want to get it set up with just ES modules using NPM.
https://developers.arcgis.com/javascript/latest/es-modules/
I did this:
npm install #arcgis/core
Then I added the following to app.component.ts
import WebMap from '#arcgis/core/WebMap';
import MapView from '#arcgis/core/views/MapView';
I am new to this. And It seems like all the documentation talks about React.
Then in the getting started with Map it has you enter a key:
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>ArcGIS API for JavaScript Tutorials: Display a map</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.18/"></script>
<script>
require(["esri/config","esri/Map", "esri/views/MapView"], function (esriConfig,Map, MapView) {
esriConfig.apiKey = "YOUR-API-KEY";
const map = new Map({
basemap: "arcgis-topographic" // Basemap layer service
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
But these docs are not for Typescript. Do they have typescript docs somewhere? How do you add the Key with the new API 4.18.1 and Typescript and NPM and Angular 11?
This is what I came up with.
It is based off https://github.com/TheKeithStewart/angular-esri-components which uses the arcgis-js-api library
https://github.com/Esri/jsapi-resources/tree/master/esm-samples/jsapi-angular-cli has the basic setup instructions for using #arcgis/core in an Angular application
esri-map.component.scss:
#mapViewNode {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
esri-map.component.ts:
import {
Component,
ElementRef,
Input,
OnInit,
NgZone,
OnDestroy,
ViewChild,
Output,
EventEmitter,
} from '#angular/core';
import config from '#arcgis/core/config';
import { EsriMapService } from './esri-map.service';
#Component({
// tslint:disable-next-line: component-selector
selector: 'esri-map',
template: '<div #mapViewNode></div>',
styleUrls: ['./esri-map.component.scss'],
})
export class EsriMapComponent implements OnInit, OnDestroy {
#ViewChild('mapViewNode', { static: true }) private elementRef!: ElementRef;
#Input() mapProperties!: any;
#Input() mapViewProperties!: any;
#Output() mapInit: EventEmitter<any> = new EventEmitter();
private mapView: any;
constructor(private zone: NgZone, private mapService: EsriMapService) {}
ngOnInit(): void {
config.assetsPath = 'assets/';
this.zone.runOutsideAngular(() => {
this.loadMap();
});
}
ngOnDestroy(): void {
this.mapView.destroy();
}
loadMap(): void {
this.mapService.isLoaded.subscribe((n: any) => {
this.mapView = n.view;
this.zone.run(() => {
this.mapInit.emit({ map: n.map, view: n.view });
this.mapInit.complete();
});
});
this.mapService.loadWebMap({
...this.mapProperties,
...this.mapViewProperties,
container: this.elementRef.nativeElement,
});
}
esri-map.service.ts:
import { EventEmitter, Injectable } from '#angular/core';
import MapView from '#arcgis/core/views/MapView';
import WebMap from '#arcgis/core/WebMap';
import Widget from '#arcgis/core/widgets/Widget';
import Layer from '#arcgis/core/layers/Layer';
export type Position =
| 'bottom-leading'
| 'bottom-left'
| 'bottom-right'
| 'bottom-trailing'
| 'top-leading'
| 'top-left'
| 'top-right'
| 'top-trailing'
| 'manual';
#Injectable({
providedIn: 'root',
})
export class EsriMapService {
map!: WebMap;
view!: MapView;
loaded = false;
isLoaded = new EventEmitter();
constructor() {}
loadWebMap(props: {
basemap: any;
container: any;
center: any;
zoom: any;
}): void {
this.map = new WebMap({ basemap: props.basemap });
this.view = new MapView({
container: props.container,
map: this.map,
center: props.center,
zoom: props.zoom,
});
this.loaded = true;
this.isLoaded.emit({
map: this.map,
view: this.view,
});
}
addLayer(layer: Layer, clearLayers?: boolean): void {
if (clearLayers) {
this.view.map.removeAll();
}
this.view.map.add(layer);
}
addWidget(
component: string | HTMLElement | Widget | any[],
position?: Position,
): void {
this.view.ui.add(component, position);
}
}
You would just instantiate the component like this:
<esri-map [mapProperties]="mapProperties" [mapViewProperties]="mapViewProperties" (mapInit)="onMapInit($event)">
</esri-map>
mapProperties sets the base map.
mapViewProperties sets the center and zoom.
mapInit lets you know when the map is loaded.
The service provides the map view for constructing the map.
You would then add your layers to the map view as usual.

Stencil EventEmitter don't emit data to Vue instance

I'm trying to create custom component using Stencil with input. My intention is to make component with input. After change input value It should emit It to my Vue instance and console log this event (later it will update value in Vue instance). But after change input value in Stencil nothing happen.
Learning how Stencil components works I used:
https://medium.com/#cindyliuyn/create-a-stencil-form-input-component-for-angular-and-vue-js-22cb1c4fdec3
Trying to solve problem I tried also:
https://medium.com/sharenowtech/using-stenciljs-with-vue-a076244790e5
HTML and Vue code:
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
<title>Stencil Component Starter</title>
<script src="https://unpkg.com/vue"></script>
<script type="module" src="/build/vox-wc-research.esm.js"></script>
<script nomodule src="/build/vox-wc-research.js"></script>
</head>
<body>
<div id="app">
<test-component :placeholder="placeholder" :label="label" :value="value" #valueChange="e => onValueChange"></test-component>
{{value}}
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
label: 'Nazwa Użytkownika',
value: '',
placeholder: 'Wpisz nazwę użytkownika',
},
methods: {
onValueChange(e) {
console.log(e);
},
},
});
</script>
</html>
Stencil Component:
import { h, Component, Element, Event, EventEmitter, Prop /* PropDidChange */ } from '#stencil/core';
#Component({
tag: 'test-component',
styleUrl: 'test-component.css',
//shadow: true,
})
export class FormInputBase {
#Element() el: HTMLElement;
#Prop() type: string = 'text';
#Prop() label: string;
#Prop() placeholder: string;
#Prop({ mutable: true }) value: string;
#Event() valueChange: EventEmitter;
handleChange(event) {
const val = event.target.value;
console.log(val);
this.value = val;
this.valueChange.emit(val);
}
render() {
return (
<div>
<label>
{this.label}
<div>
<input placeholder={this.placeholder} value={this.value} onInput={event => this.handleChange(event)}></input>
{this.value}
</div>
</label>
</div>
);
}
}
Vue doesn't support camel-case event names because all v-on: event listeners are converted to lower-case (see https://v2.vuejs.org/v2/guide/components-custom-events.html#Event-Names).
However when you load your component(s), you can use the options of Stencil's defineCustomElements to "transform" all your event names:
import { applyPolyfills, defineCustomElements } from 'my-component/loader';
applyPolyFills().then(() => {
defineCustomElements({
ce: (eventName, opts) => new CustomEvent(eventName.toLowerCase(), opts)
});
});
For a more full-blown example have a look at Ionic Framework's source:
https://github.com/ionic-team/ionic-framework/blob/b064fdebef14018b77242b791914d5bb10863d39/packages/vue/src/ionic-vue.ts

BokehJS Custom Tool for Toggling Legend Visibility

My bokeh app is dealing with a grid of several figures, each showing several glyphs. To improve readability, I'd like to be able to hide/show the legends of the figures on clicking on a button. Though this appeared to me as a perfect example for a tool button in the toolbar such as 'save' and 'reset', this functionality is not implemented in bokeh yet.
I found several hints on how to implement a custom tool myself, see here, here, here, here or here. An example on how to add a custom icon is shown here.
This is what I got so far:
main.py:
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource, Tool
from bokeh.plotting import figure
from os.path import dirname
from jinja2 import FileSystemLoader, Environment
from bokeh.embed.standalone import file_html
from bokeh.resources import CDN
class LegendToggleTool(Tool):
__implementation__ = """
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
import * as p from "core/properties"
export class LegendToggleToolView extends ActionToolView {
model: LegendToggleTool
doit(): void {
for(const r of this.plot_view.model.panels){
if (r.type=="Legend"){
r.visible = !r.visible
}
}
}
}
export namespace LegendToggleTool {
export type Attrs = p.AttrsOf<Props>
export type Props = ActionTool.Props
}
export interface LegendToggleTool extends LegendToggleTool.Attrs {}
export class LegendToggleTool extends ActionTool {
properties: LegendToggleTool.Props
__view_type__: LegendToggleToolView
constructor(attrs?: Partial<LegendToggleTool.Attrs>) {
super(attrs)
}
static init_LegendToggleTool(): void {
this.prototype.default_view = LegendToggleToolView
this.register_alias("legendtoggle", () => new LegendToggleTool())
}
tool_name = "LegendToggle"
icon = "legend-toggle-icon"
}
"""
env = Environment(loader=FileSystemLoader(dirname(__file__)))
template = env.get_template('template.html')
source01 = ColumnDataSource(data=dict(x=[0,1,2,3,4], y=[0,1,2,3,4],z=[4,3,2,1,0]))
source02 = ColumnDataSource(data=dict(x=[0,3,1,6,1], y=[0,1,2,3,4],z=[4,3,2,1,0]))
fig01 = figure(x_range=(0, 10), y_range=(0, 10),tools=[LegendToggleTool()])
fig01.line('x', 'y', source=source01, legend_label = 'line_01')
fig01.line('x', 'z', source=source01, legend_label = 'line_02')
fig02 = figure(x_range=(0, 10), y_range=(0, 10),tools=[LegendToggleTool()])
fig02.line('x', 'y', source=source02, legend_label = 'line_03')
fig02.line('x', 'z', source=source02, legend_label = 'line_04')
with open('out.html', 'w') as f:
f.write(file_html(gridplot([[fig01,fig02]]), resources=CDN, template=template))
template.html (in the same directory, copied from here):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ title|e if title else "Bokeh Plot" }}</title>
{{ bokeh_css }}
{{ bokeh_js }}
<style>
html {
width: 100%;
height: 100%;
}
body {
width: 90%;
height: 100%;
margin: auto;
}
.legend-toggle-icon {
background-image: url(data:image/png;base64,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);
}
</style>
</head>
<body>
{{ plot_div|indent(8) }}
{{ plot_script|indent(8) }}
</body>
</html>
Running main.py results in an output-file 'out.html'. Toggling the legends' visibility works as expected, but the icon remains blank. So here are my questions:
How do I get the icon to show up?
Let's say I wanted to run this via bokeh serve --show <dirname>, how would I need to organize the above code inside the folder <dirname>?

Using globally defined script inside the component

I am using global script declaration inside index.html
<!DOCTYPE html>
<html>
<head>
<script src='https://js.espago.com/espago-1.1.js' type='text/javascript'></script>
...
</head>
<body>
...
</body>
Now I want to use it inside the component.
import * as React from "react";
import * as $ from "jquery";
//how to import Espago?
export default class EspagoPayment extends React.Component<any, any> {
componentDidMount() {
$("#espago_form").submit(function(event){
var espago = new Espago({public_key: 'xxx', custom: true, live: false, api_version: '3'});
espago.create_token({
...
});
});
}
render() {
return (
...
);
}
}
Webpack gives an error on build.
error TS2304: Cannot find name 'Espago'
How to get Espago visible inside the component?
Maybe there is other way to link to online js resource?
You have to tell TypeScript that it's defined somewhere else.
declare var Espago: any;
See https://stackoverflow.com/a/13252853/227299

Categories