Update html element from Javascript in Web Component - progressive-web-apps

I am developing a PWA app using web components and vaadin router, this is my flow
index.html (main entry to PWA app)
index.html has reference to local ./js/index.js and routes
index.js has references to web components for each path
Each individual web components loads tensorflow js and also references local js for model train, fit and evaluate.
I am able to load tensorflow JS and my local js script in my web component, my question is how do I update the result in web component. This is my glitch link where is it working with traditional html, js and css.
Below I am putting relevant pieces of code for reference. The sequence of the code
Defining template.innerHTML
In the template there are 2 sections with id "canvas" and "prediction"
I need to update them from "image-classifier-mlp-script.js" which is my custom JS, traditionally I would have used
const PREDICTION_ELEMENT = document.getElementById('prediction');
const CANVAS = document.getElementById('canvas');
but I cannot do it in web component, so my question
What is the best pattern to update my html element id from my custom javascript?
const template = document.createElement('template')
template.innerHTML = `
<body>
<link rel="stylesheet" href="./css/image-classifier-mlp.css" />
<h1>TensorFlow.js MNIST classifier</h1>
<p>See console for even more outputs.</p>
<section class="box">
<h2>Input Image</h2>
<p>Input image is a 28x28 pixel greyscale image from MNIST dataset - a real hand drawn digit!</p>
<canvas id="canvas" width="28" height="28"></canvas>
</section>
<section class="box">
<h2>Prediction</h2>
<p>Below you see what number the trained TensorFlow.js model has predicted from the input image.</p>
<p>Red is a wrong prediction, Green is a correct one.</p>
<p id="prediction">Training model. Please wait...</p>
</section>
`
let initCalled = false;
let customInitCalled = false;
function loadCustomScript() {
console.log(`Before : Value of customInitCalled ${customInitCalled}`)
if(!customInitCalled) {
const script = document.createElement('script');
script.type = 'module';
script.async = true;
script.onload = function () {
customInitCalled = true;
console.log(`After : Value of customInitCalled ${customInitCalled}`)
}
script.src = '/js/image-classifier-mlp-script.js'
document.head.appendChild(script);
}
}
function loadTf() {
console.log(`Before : Value of initCalled ${initCalled}`)
if (!initCalled) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.onload = function () {
initCalled = true;
console.log(`After : Value of initCalled ${initCalled}`)
}
script.src = '//cdn.jsdelivr.net/npm/#tensorflow/tfjs#3.11.0/dist/tf.min.js'
document.head.appendChild(script);
}
}
class ImageClassifierMultiLayerPerception extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
console.log('mlp')
loadTf()
loadCustomScript()
}
}
customElements.define('image-classifier-mlp', ImageClassifierMultiLayerPerception)

Related

Can I use save my forms into my local database?

I'd like to use form.io in order to allow my admin users to create a new forms but I want save all data into my database, not in form.io platform. Is it possible?
I want use form builder but at save time I want save the form structure into my database.
I don't understand if this option is possible.
Thanks
Yes.
Step 1: Store your components in your database. If you use the form builder, you can get them by a call to builder.schema.
Step 2: Retrieve your components from your database and render the form.
Step 3: Save the data to your DB.
components = {{component string from DB}}
let formio = new Formio.createForm(document.getElementById(element),
components,
{
saveDraft: true,
readOnly: ((readonly) ? readonly : false)
}
).then(function (form) {
if (data) {
var subm = JSON.parse(data)
form.submission = { data: subm };
}
form.on('submit', function (submission) {
//Submission Code
});
form.on('change', function (x) {
//Change Code
})
form.on('error', (errors) => {
//Error Code
})
form.on("render", function () {
//Any Render Overrides?
})
}).catch(function (ex) {
});
Some of this stuff is well documented. Some - not so much. Lots of trial and error. (Mostly error).
Something similar is what works for me. Note this is for saving the schema for the Form Builder. This schema can be deserialized and used as a source for the Form Renderer
#uglyCodeSry
JavaScript
var form;
var formTemplateToSave; // this is the serialized form template to save
window.onload = function() {
var builder = Formio.builder(document.getElementById('builder'), {}, {builder: {}
}).then((_form) => {
form = _form;
form.on('change', function(payload) {
formTemplateToSave = JSON.stringify(form.schema, null, 4);
});
formTemplateToSave = JSON.stringify(form.schema, null, 4);
});
};
HTML
<div>
<div id='builder'></div>
</div>
Don't forget to include the libraries (as well as your usual jquery stuff)
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://cdn.form.io/formiojs/formio.full.min.css'>
<script src='https://cdn.form.io/formiojs/formio.full.min.js'></script>
You can then save the formTemplateToSave variable as the JSON to rehydrate your forms

detect dynamically checkboxes/polymer elements ticked in Dart

A newbie to Dart with no experience in JS.
I have written code to populate a dropdown from JSON.
Edit:
i am trying to add polymer elements.
Polymer .dart
import 'package:polymer/polymer.dart';
#CustomTag('player-item')
class PlayerItem extends PolymerElement{
#observable String playerName='hello';
void removePlayer(){
playerName='';
}
PlayerItem.created(): super.created(){}
}
Initially was getting error of constructor not defined. added empty brackets to
super.created. error fixed
What am i doing wrong. how to do this correctly??
polymer.html
playername = name of player to be displayed dynamically.
right now using default string.
removeplayer = (ideas is to) remove entire polymer element.
<polymer-element name="player-item">
<template>
<input type="image" src="button_minus_red.gif" on-click="{{removePlayer}}">
<div>{{playerName}}</div>
</template>
<script type="application/dart" src="player-item.dart"></script>
</polymer-element>
Edited Dart Code:
Objective is first generate options then select one of them and the subsequently remove them if clicked on image(polymer element intended for this purpose).
Went through polymer example master. but couldnt find something related.
Help Needed:
1. how do i dynamically add polymer elements?
how to pass values (ie. in this case name of player) to the dynamically added
polymer element?
how to remove polymer elements?
How to remove appended text added via *.appendedtext ?
import 'dart:html';
import 'dart:convert' show JSON;
import 'dart:async' show Future;
import 'package:polymer/polymer.dart';
import 'player-item.dart';
//ButtonElement genButton,desButton;
SelectElement selectTeam;
FormElement teamPlayer;
FormElement yourPlayer;
InputElement teamPlayers;
//final subscriptions = <StreamSubscription>[];
List<String>teams=[];
List<String>players=[];
main() async{
selectTeam = querySelector('#teamNames');
teamPlayer = querySelector('#teamPlayers');
yourPlayer = querySelector('#yourPlayers');
selectTeam.onChange.listen(populateTeams);
try {
await prepareTeams1 ();
selectTeam.disabled = false; //enable
//genButton.disabled = false;
} catch(arrr) {
print('Error initializing team names: $arrr');
}
}
void populateYourPlayers(String name){
querySelector('#yourPlayers').children.add(new Element.tag('player-item'));
var input = new InputElement();
input.type = "image";
input.src = "button_minus_red.gif";
input.id = name;
print('yo');
input.width = 15;
input.height =15;
input.appendText(name);
input.onClick.listen((remove){
remove.preventDefault();
input.remove();
//yourPlayer.children.remove();
});
yourPlayer.append(input);
// yourPlayer.append(y);
yourPlayer.appendText(name);
yourPlayer.appendHtml("<br>");
}
void removeYourPlayers(Event e){
yourPlayer.querySelectorAll("input[type=checkbox]").forEach((cb) {
// print('${cb.checked}');
if(cb.checked == true){
print('${cb.id}');
yourPlayer.children.removeWhere((cb)=>cb.checked==true);
}
}
);
}
Future prepareTeams1()async{
String path = 'teams.json';
String jsonString = await HttpRequest.getString(path);
parseTeamNamesFromJSON(jsonString);
}
parseTeamNamesFromJSON(String jsonString){
Map team = JSON.decode(jsonString);
teams = team['Teams'];
print(teams);
for (int i =0; i< teams.length; i++){
var option = new OptionElement();
option.value = teams[i];
option.label =teams[i];
option.selected = false;
selectTeam.append(option);
}
}
Future prepareTeams2(String Team)async{
String path = 'teams.json';
String jsonString = await HttpRequest.getString(path);
parsePlayerNamesFromJSON(jsonString, Team);
}
parsePlayerNamesFromJSON(String jsonString,String Team){
Map team = JSON.decode(jsonString);
teamPlayer.children.clear();
teams = team[Team];
print(teams);
for (int i =0; i< teams.length; i++){
var input = new InputElement(type:"image");
// input.type = "image";
input.id = teams[i];
input.src = "button_plus_green.gif";
input.width = 15;
input.height =15;
input.onClick.listen((p){
p.preventDefault();
populateYourPlayers(teams[i]);
});
//input.onClick.listen((event){populateYourPlayers(teams[i]);});
//subscription.cancel();
teamPlayer.append(input);
teamPlayer.appendText(teams[i]);
teamPlayer.appendHtml("<br>");
}
}
void populateTeams(Event e){
print('selectTeam.length: ${selectTeam.length}');
print(selectTeam.value);
prepareTeams2(selectTeam.value);
if (selectTeam.length == 0){
}
}
Modified HTML:
<html>
<head>
<meta charset="utf-8">
<title>Pirate badge</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="piratebadge.css">
<link rel="import" href="player-item.html">
</head>
<body>
<h1>Team Names</h1>
<select id="teamNames">
</select>
<h1>Team players</h1>
<form id="teamPlayers">
</form>
<div>
<button id="generateButton" disabled>Add Player/Players</button>
</div>
<h1>Your players</h1>
<form id="yourPlayers">
</form>
<player-item></player-item>
<div>
<button id="destroyButton" disabled>Remove Player/Players</button>
</div>
<script type="application/dart" src="piratebadge.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
and based on that selection display a form with checkboxes.
The issue i am facing is how to detect them which checkboxes have been checked and if so how the value of that checkbox can be captured.
Possible duplicate
How to know if a checkbox or radio button is checked in Dart?
However them checkboxes not dynamically created.
If the above approach is wrong, kindly advise.
Depending on when you want to detect the checked state there are two ways.
You can add a click handler to the submit button and then query the checkboxes.
querySelector("input[type=submit]").onClick.listen((e) {
querySelectorAll("input[type=checkbox]").forEach((cb) {
print('${cb.id} {cb.checked}');
});
});
Currently you are assigning the same id to each checkbox. This is a bad choice because you have no way to know which checkbox represents what item.
Another way is to assign a click handler to each checkbox to get notified immediately when the checkbox is clicked.
(I simplified your checkbox creation code a bit by using continuations and forEach instead of for)
teams.forEach((team) {
var input = new InputElement()
..type = "checkbox"
..id = "player"
..onClick.listen((e) {
print('${cb.id} {cb.checked}');
});
teamplayer
..append(input)
..appendText(team)
..appendHtml("<br>");
}
In this case you might need to reset the click notifications when the selection changes.
import 'dart:async';
// ...
final subscriptions = <StreamSubscription>[];
// ...
subscriptions
..forEach((s) => s.cancel())
..clear();
teams.forEach((team) {
var input = new InputElement()
..type = "checkbox"
..id = "player";
subscriptions.add(input.onClick.listen((e) {
print('${cb.id} {cb.checked}');
}));
teamplayer
..append(input)
..appendText(team)
..appendHtml("<br>");
}
Caution: code not tested and it's a while I used checkboxes.
You can read the checked property of the CheckboxInputElement
parsePlayerNamesFromJSON(String jsonString,String Team){
Map team = JSON.decode(jsonString);
teams = team[Team];
print(teams);
for (int i =0; i< teams.length; i++){
var input = new CheckboxInputElement();
input.type = "checkbox";
input.id = "player";
input.onChange.listen((_) {
print("teamplayer ${input.checked}");
});
teamPlayer.append(input);
teamPlayer.appendText(teams[i]);
teamPlayer.appendHtml("<br>");
}

how to change GWT/SmartGWT theme at run time

I want to change the theme of my SmartGWT application at run time from the code
I can see this functionally in SmartGWT showcase , but I can't see any code for this in SmartGWT showcase.
What I am doing right now is
This is my XML class
<?xml version="1.0" encoding="UTF-8"?>
<inherits name="com.smartgwt.SmartGwtNoTheme"/>
<inherits name="com.smartclient.theme.graphite.Graphite"/>
<inherits name="com.smartclient.theme.blackops.BlackOps"/>
<inherits name="com.smartclient.theme.enterprise.Enterprise"/>
<inherits name="com.smartclient.theme.enterpriseblue.EnterpriseBlue"/>
This is my HTML class snippet
<title>My Web</title>
<script>
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for ( var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ')
c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0)
return c.substring(nameEQ.length, c.length);
}
return null;
}
// Determine what skin file to load
var currentSkin = readCookie('skin');
if (currentSkin == null){
currentSkin = "Enterprise";
}
alert(currentSkin);
</script>
<script type="text/javascript">
document.write("<" + "script src=testtheme/sc/skins/"
+ currentSkin + "/load_skin.js><"+"/script>");
</script>
This is my Java class
SelectItem selectItem = new SelectItem("skin", "Choose Skin");
DynamicForm df = new DynamicForm();
hpnlMain.add(df);
df.setItems(selectItem);
selectItem.setWidth(130);
java.util.LinkedHashMap<String, String> valueMap = new java.util.LinkedHashMap<String, String>();
valueMap.put("Enterprise", "Enterprise");
valueMap.put("EnterpriseBlue", "EnterpriseBlue");
valueMap.put("TreeFrog", "TreeFrog");
valueMap.put("BlackOps", "BlackOps");
valueMap.put("Graphite", "Graphite");
selectItem.setValueMap(valueMap);
String currentSkin = Cookies.getCookie("skin");
if (currentSkin == null) {
currentSkin = "Enterprise";
}
selectItem.setDefaultValue(currentSkin);
selectItem.addChangedHandler(new ChangedHandler() {
#Override
public void onChanged(ChangedEvent event) {
// TODO Auto-generated method stub
Cookies.setCookie("skin", event.getValue().toString());
Window.Location.reload();
}
});
The expected outcome is that when I select any skin form my SelectItem, that skin should be applied, but I am having no Effect .
Please look into this line in my HTML file
<script type="text/javascript">
document.write("<" + "script src=testtheme/sc/skins/"
+ currentSkin + "/load_skin.js><"+"/script>");
Here I'm not sure what will be the exact path ,
I have the smatgwt-skins.jar in my class path
Thanks
What does the 'alert(currentSkin)' line in your html file display when you change the skin and the application gets reloaded? Does it show the newly selected skin name?
It looks like you are using code from the SmartGWT showcase, or it just happens to appear almost identical to it.
http://code.google.com/p/smartgwt/source/browse/trunk/samples/showcase/src/com/smartgwt/sample/showcase/client/Showcase.java
Maybe this could help: Here
Check the Smartclient forum for this situation, there is plenty information on it.

Connecting a simple gain node to Web Audio API file buffers

I can't seem to understand why this isn't working. I have no errors.I have done this using oscillators and it works fine. FYI this is a continuation of this thread:
Using Web Audio API to assign two sounds to two Divs and play each independently via a click event with javascript
Code:
<div id="divElement"></div>
<style>
#divElement{
background-color: orange;
width:70px;
height:100px;
left:143px;
}
</style>
<script>
var context = new webkitAudioContext(),
savedBuffer;
var playAudioFile = function () {
var source = context.createBufferSource();
var gainNode = context.createGainNode();
source.buffer = savedBuffer;
// START OF PROBLEM AREA: Gain not working but file still plays with no errors.
source.connect(gainNode);
gainNode.connect(context.destination);
gainNode.gain = 0;
// END OF PROBLEM AREA
source.noteOn(0); // Play sound immediately
};
var request = new XMLHttpRequest();
request.open('get', 'audio/A.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function () {
context.decodeAudioData(request.response,
function(incomingBuffer) {
savedBuffer = incomingBuffer;
var divElement = document.getElementById("divElement");
divElement.addEventListener("click", playAudioFile , false);
}
);
};
request.send();
</script>
Try gainNode.gain.value = 0 instead. gainNode.gain is an AudioGain object, which has the attribute value.
http://www.w3.org/TR/webaudio/#AudioGainNode

HTML5 Geolocation data loaded in a form to send towards database

i'm busy with a school project and I have to build a web app. One function that I want to use is Google Maps and HTML5 Geo Location to pin point what the location of the mobile user is.
I have found this HTML5 Geo Location function on http://merged.ca/iphone/html5-geolocation and works very well for me. However, I want the adress data to be placed into a form so that I can submit it to my database when a mobile user Geo locates his position. This causes the marker to be saved and can be viewed on a global website.
Who know how to get the "Your address:" data loaded into a input field of a form?
Below you can find my Html file. Maybe somebody got a better suggestion perhaps?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<title>HTML 5 Geolocation</title>
<style>
#map {
height:300px;
width:300px;
}
</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1"); google.load("jqueryui", "1");</script>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAiUzO1s6QWHuyzxx-JVN7ABSUL8-Cfeleqd6F6deqY-Cw1iTxhxQkovZkaxsxgKCdn1OCYaq7Ubz3SQ" type="text/javascript"></script>
<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&appid=n2wY9mzV34Hsdslq6TJoeoJDLmAfzeBamSwJX7jBGLnjM7oDX7fU.Oe91KwUbOwqzvc-"></script>
<script type="text/javascript">
// Geolocation with HTML 5 and Google Maps API based on example from maxheapsize: http://maxheapsize.com/2009/04/11/getting-the-browsers-geolocation-with-html-5/
//
// This script is by Merge Database and Design, http://merged.ca/ -- if you use some, all, or any of this code, please offer a return link.
var map;
var mapCenter
var geocoder;
var fakeLatitude;
var fakeLongitude;
function initialize()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition( function (position) {
// Did we get the position correctly?
// alert (position.coords.latitude);
// To see everything available in the position.coords array:
// for (key in position.coords) {alert(key)}
mapServiceProvider(position.coords.latitude,position.coords.longitude);
}, // next function is the error callback
function (error)
{
switch(error.code)
{
case error.TIMEOUT:
alert ('Timeout');
break;
case error.POSITION_UNAVAILABLE:
alert ('Position unavailable');
break;
case error.PERMISSION_DENIED:
alert ('Permission denied');
break;
case error.UNKNOWN_ERROR:
alert ('Unknown error');
break;
}
}
);
}
else
{
alert("I'm sorry, but geolocation services are not supported by your browser or you do not have a GPS device in your computer. I will use a sample location to produce the map instead.");
fakeLatitude = 49.273677;
fakeLongitude = -123.114420;
//alert(fakeLatitude+', '+fakeLongitude);
mapServiceProvider(fakeLatitude,fakeLongitude);
}
}
function mapServiceProvider(latitude,longitude)
{
if (window.location.querystring['serviceProvider']=='Yahoo')
{
mapThisYahoo(latitude,longitude);
}
else
{
mapThisGoogle(latitude,longitude);
}
}
function mapThisYahoo(latitude,longitude)
{
var map = new YMap(document.getElementById('map'));
map.addTypeControl();
map.setMapType(YAHOO_MAP_REG);
map.drawZoomAndCenter(latitude+','+longitude, 3);
// add marker
var currentGeoPoint = new YGeoPoint( latitude, longitude );
map.addMarker(currentGeoPoint);
// Start up a new reverse geocoder for addresses?
// YAHOO Ajax/JS/Rest API does not yet support reverse geocoding (though they do support it via Actionscript... lame)
// So we'll have to use Google for the reverse geocoding anyway, though I've left this part of the script just in case Yahoo! does support it and I'm not aware of it yet
geocoder = new GClientGeocoder();
geocoder.getLocations(latitude+','+longitude, addAddressToMap);
}
function mapThisGoogle(latitude,longitude)
{
var mapCenter = new GLatLng(latitude,longitude);
map = new GMap2(document.getElementById("map"));
map.setCenter(mapCenter, 15);
map.addOverlay(new GMarker(mapCenter));
// Start up a new reverse geocoder for addresses?
geocoder = new GClientGeocoder();
geocoder.getLocations(latitude+','+longitude, addAddressToMap);
}
function addAddressToMap(response)
{
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode that address");
} else {
place = response.Placemark[0];
$('#address').html('Your address: '+place.address);
}
}
window.location.querystring = (function() {
// by Chris O'Brien, prettycode.org
var collection = {};
var querystring = window.location.search;
if (!querystring) {
return { toString: function() { return ""; } };
}
querystring = decodeURI(querystring.substring(1));
var pairs = querystring.split("&");
for (var i = 0; i < pairs.length; i++) {
if (!pairs[i]) {
continue;
}
var seperatorPosition = pairs[i].indexOf("=");
if (seperatorPosition == -1) {
collection[pairs[i]] = "";
}
else {
collection[pairs[i].substring(0, seperatorPosition)]
= pairs[i].substr(seperatorPosition + 1);
}
}
collection.toString = function() {
return "?" + querystring;
};
return collection;
})();
</script>
</head>
<body onLoad="initialize()">
<div id="content">
<div id="map"></div>
<p id="address"></p>
<form id="ContactForm" action="">
<p>
<label>Topic</label>
<input id="event" name="event" maxlength="120" type="text" autocomplete="off"/>
</p>
<p>
<label>Address</label>
<input id="address" name="address" maxlength="120" type="text" autocomplete="off"/>
</p>
<input id="send" type="button" value="Send"/>
<input id="newcontact" name="newcontact" type="hidden" value="1"></input>
</form>
</div>
</body>
</html>
You have to use JavaScript to set the value of address input field, this way
1- Add name attribute to the form and input.
2- document.formName.inputName.value=place.address;
Good Luck