Modify the javascript to load on window load - javascript

Here is a javascript on "Speech to text recognition".The script runs on click.But I want to run the script on window/page load.I am not actually a javascript guy.Would you please help me to modify the script?
Extra[not essential to answer]: additionally I would like to modify the html code into simple html code from the existing "Vuitify" format.Can you help?
Note:Here I've addded the "snippet" that only will work on 'Goggle Crome' browser.
var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
var recognition = SpeechRecognition ? new SpeechRecognition() : false;
Vue.component('speech-to-text', {
template: '\n <v-card>\n <v-card-text>\n <v-layout row wrap justify-space-around>\n <v-flex xs8 sm9 text-xs-center>\n <p v-if="error" class="grey--text">{{error}}</p>\n <p v-else class="mb-0">\n <span v-if="sentences.length > 0" v-for="sentence in sentences">{{sentence}}. </span>\n <span>{{runtimeTranscription}}</span>\n </p>\n </v-flex>\n <v-flex xs2 sm1 text-xs-center>\n <v-btn\n dark\n #click.stop="toggle ? endSpeechRecognition() : startSpeechRecognition()"\n icon\n :color="!toggle ? \'grey\' : (speaking ? \'red\' : \'red darken-3\')"\n :class="{\'animated infinite pulse\': toggle}"\n >\n <v-icon>{{toggle ? \'mic_off\' : \'mic\'}}</v-icon>\n </v-btn>\n </v-flex>\n </v-layout>\n </v-card-text>\n </v-card>\n ',
props: {
lang: {
type: String,
default: 'en-US' },
text: {
type: [String, null],
required: true } },
data: function data() {
return {
error: false,
speaking: false,
toggle: false,
runtimeTranscription: '',
sentences: [] };
},
methods: {
checkCompatibility: function checkCompatibility() {
if (!recognition) {
this.error = 'Speech Recognition is not available on this browser. Please use Chrome or Firefox';
}
},
endSpeechRecognition: function endSpeechRecognition() {
recognition.stop();
this.toggle = false;
this.$emit('speechend', {
sentences: this.sentences,
text: this.sentences.join('. ') });
},
startSpeechRecognition: function startSpeechRecognition() {var _this = this;
if (!recognition) {
this.error = 'Speech Recognition is not available on this browser. Please use Chrome or Firefox';
return false;
}
this.toggle = true;
recognition.lang = this.lang;
recognition.interimResults = true;
recognition.addEventListener('speechstart', function (event) {
_this.speaking = true;
});
recognition.addEventListener('speechend', function (event) {
_this.speaking = false;
});
recognition.addEventListener('result', function (event) {
var text = Array.from(event.results).map(function (result) {return result[0]; }).map(function (result) {return result.transcript; }).join('');
_this.runtimeTranscription = text;
});
recognition.addEventListener('end', function () {
if (_this.runtimeTranscription !== '') {
_this.sentences.push(_this.capitalizeFirstLetter(_this.runtimeTranscription));
_this.$emit('update:text', '' + _this.text + _this.sentences.slice( - 1)[0] + '. ');
}
_this.runtimeTranscription = '';
recognition.stop();
if (_this.toggle) {
// keep it going.
recognition.start();
}
});
recognition.start();
},
capitalizeFirstLetter: function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
} },
mounted: function mounted() {
this.checkCompatibility();
} });
new Vue({
el: '#app',
data: function data() {
return {
text: '',
sentences: null };
},
methods: {
speechEnd: function speechEnd(_ref) {var sentences = _ref.sentences, text = _ref.text;
console.log('text', text);
console.log('sentences', sentences);
this.sentences = sentences;
} } });
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link rel='stylesheet' href='https://unpkg.com/vuetify#1.0.17/dist/vuetify.min.css'>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/animate.css#3.5.2/animate.min.css'>
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-layout row wrap justify-center class="mt-4">
<v-flex xs12 sm10 text-xs-center>
<v-text-field name="x"
label="The text"
v-model="text"
textarea
></v-text-field>
</v-flex>
<v-flex xs12 sm8 md4 text-xs-center>
<speech-to-text :text.sync="text" #speechend="speechEnd"></speech-to-text>
</v-flex>
<v-flex xs12 text-xs-center class="mt-4">
{{sentences}}
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
<script src='https://unpkg.com/babel-polyfill/dist/polyfill.min.js'></script>
<script src='https://unpkg.com/vue/dist/vue.js'></script>
<script src='https://unpkg.com/vuetify#1.0.17/dist/vuetify.min.js'></script>

You can wrap the JavaScript code into a function and call the wrapped function on body onload using <body onload="wrappedFunction();">
Make sure your scripts/dependencies are loaded before this. You can add the scripts in the <head>

Related

Vuetify Table - rendering column value based on a condition

I have a vuetify table and one of the columns is url. I need to add logic to either display URL or URL Group name. I can tell that based on the property of my rules array. If my rules[i].urlGroup != '' then I know
I have tried to add
<template v-slot:item.url="{ index, item }">
{{ displayURLInfo(index) }}
</template>
displayURLInfo(index) {
if (this.rules[index].urlGroup != '') {
// console.log('this.rules[index].urlGroup', this.rules[index].urlGroup) // here printed perfectly on console.
return this.rules[index].urlGroup
} else {
return this.url
}
}
I was inside the first if condition, it consoles log perfectly, but it didn't render to the UI.
My rules array structure look like this. It's only has 5 properties
What did I do wrong?
You have to do below correction in the displayURLInfo() method :
Use urlGroup instead of userGroup.
Instead of return this.url it should be return this.rules[index].url
Working Demo :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{ text: "Priority", value: 'priority' },
{ text: "Name", value: 'name' },
{ text: "URL", value: 'url' },
],
rules: [{
priority: 1,
name: "Alpha",
url: 'https://example.com',
urlGroup: ''
}, {
priority: 2,
name: "Beta",
url: 'https://example.com',
urlGroup: 'userGroup2'
}],
}
},
methods: {
displayURLInfo(index) {
if (this.rules[index].urlGroup != '') {
return this.rules[index].urlGroup
} else {
return this.rules[index].url
}
}
}
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.css"/>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="rules"
>
<template v-slot:item.url="{ index, item }">
{{ displayURLInfo(index) }}
</template>
</v-data-table>
</v-app>
</div>

Integrating third party js application to vue.js2

I am trying to integrate a third party js application to my vue.js project. It is a molecular editor that will load on my page as a component.
Link to the js application - https://jsme-editor.github.io/dist/index.html
And this is what I want to achive -
<html><head>
<script type="text/javascript" language="javascript" src="jsme/jsme.nocache.js"></script>
<script>
//this function will be called after the JavaScriptApplet code has been loaded.
function jsmeOnLoad() {
jsmeApplet = new JSApplet.JSME("jsme_container", "380px", "340px");
jsmeApplet.setAfterStructureModifiedCallback(showEvent);
document.getElementById("log").value = "";
}
function showEvent(event) {
var log = document.getElementById("log");
log.value = event.action + " at: " + event.atom + " b: " + event.bond + " m: " + event.molecule + " smiles:" + event.src.smiles() + "\n" + log.value;
}
</script></head>
<body>
<div id="jsme_container"></div>
<textarea id="log" rows="5" cols="50"> </textarea>
</body>
</html>
What I have done so far is I have declared it as component as seen below -
<template>
<div class="hello">
<button #click="notify">Notify</button>
<div id="jsme-container" ref="jsmeContainer"></div>
</div>
</template>
<script>
export default {
name: 'newcomp',
data() {
return {
jsmeIsLoaded : false,
div_select : null
}
},
props: {
txt: String,
height: {
type: String,
required: true
},
width: {
type: String,
required: true
},
smiles: String,
options: String,
onChange: Function
},
mounted() {
let script = document.createElement('script')
script.src = '/home/rathore/Desktop/test_component/src/assets/JSME_2020-12-26/jsme/jsme.nocache.js'
document.head.appendChild(script)
this.$nextTick(
window.jsmeOnLoad = () => {this.jsmeIsLoaded = true;}
)
},
watch: {
jsmeIsLoaded(){
this.div_select = this.$refs.jsmeContainer.id
const div_loader = document.createElement('script')
const applet_txt = 'jsmeApplet = new JSApplet.JSME("'+this.div_select+'","300px","400px");'
//console.log(applet_txt,this.div_select)
const div_applet = document.createTextNode(applet_txt);
div_loader.appendChild(div_applet);
document.head.appendChild(div_loader);
}
},
methods: {
//Unused method
handleJsmeLoad(){
if (this.props.options){
this.jsmeApplet = new window.JSApplet.JSME(this.div_select, this.props.width, this.props.height, {options: this.props.options});
}
else {
this.jsmeApplet = new window.JSApplet.JSME(this.div_select, this.props.width, this.props.height);
}
this.jsmeApplet.setCallBack("AfterStructureModified", this.handleChange);
this.jsmeApplet.readGenericMolecularInput(this.props.smiles)
},
handleChange(jsmeEvent){
if (this.props.onChange) {
this.props.onChange(jsmeEvent.src.smiles())
}
},
notify(){
if (this.jsmeIsLoaded){
alert("JSME LOADED!!");
}
}
},
}
</script>
and called the component -
App.vue
template>
<div id="app">
<newcomp :height="'300px'" :width="'400px'" :onChange="logsmile" />
</div>
</template>
<script>
import newcomp from './components/NewComponenet.vue'
export default {
name: 'App',
components: {
newcomp
},
methods: {
logsmile(smiles){
console.log(smiles)
}
},
}
</script>
Here I have tried injecting <script> tag in the <head>. It is injected as I expected, but it doesn't work it give me error -
Uncaught ReferenceError: JSApplet is not defined. and it doesn't render the editor.
but actually I want it render using handleJSMELoad() method. Please suggest me the resolution.

Vue not updating

I'm new to Vue js - the following is not updating:
<div id="error" class="col s12 red center">
<span v-if="seen">
Error fetching readings: {{ msg }}
</span>
</div>
Vue:
var error = new Vue({
el: '#error',
data: {
msg: '',
seen: false
},
methods: {
show: function(message) {
this.msg = message;
this.seen = true;
},
hide: function() {
this.seen = false;
}
}
});
Post fetch:
fetch( ... )
.then(...)
.catch(err => {
error.show( err );
loader.hide();
});
error.show() displays the previously hidden div, but displays:
Error fetching readings: {}
Why?
i created a CodeSandbox sample based upon your code, you need to have computed property to have the Vue reactivity
Sample can be found, check code in HelloWorld.vue in components folder
https://codesandbox.io/s/x2klzr59wo
<template>
<div id="error" class="col s12 red center">
{{ seen }}
<hr />
<span v-if="computedSeen"> Error fetching readings: {{ msg }} </span>
<hr />
<button #click="show('effe');">SHOW</button>
<button #click="hide();">HIDE</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
msg: "",
seen: false
};
},
methods: {
show: function(message) {
this.msg = message;
this.seen = true;
},
hide: function() {
this.seen = false;
}
},
computed: {
computedSeen: function() {
// `this` points to the vm instance
return this.seen;
}
}
};
</script>
Oops, problem was err from the fetch is an object, and I should have used err.message.
In my code I had a console.log('Error: %s', err) which appears to format the err object into text. Which is what threw me :(
Sorry.

Vue.js doesn't display calendars

I am using vue-full-calendar to display calendars on my webpage.
Here i iterate through my projects in my database and get the dates so i can fill the calendar events later (using props in my-message component).
<template>
<div class="row" >
<div #click="clickedDiv" v-for="val in allProjects" :key="val.projectName" class="col-md-5 margin-bottom-30" >
<my-message id ="calendar" v-bind:title="val.projectName" v-bind:dates= val.answeredDates v-bind:dateTitle = val.projectId v-bind:link="'/#/editstartup' + '?id=' + val.projectId + '&title='+ val.projectName "></my-message>
</div>
</div>
</template>
The my-message component is inside main class :*
Vue.component('my-message', {
props: ['dates', 'title', 'dateTitle', 'link'],
data: function () {
var customEvents = [];
this.dates.forEach((event) => {
customEvents.push({
title: this.dateTitle,
start: event,
color: 'rgb(0, 95, 206)',
textColor: 'rgb(0, 95, 206)',
clickedDate: '',
projectId: '',
answeredDateConfirmURI: 'http://...'
})
})
return {
isVisible: true,
events: customEvents,
config: {
defaultView: 'month',
},
}
},
methods: {
getAnsweredDateConfirm: function (id) {
axios.get('http://localhost:8081/webapi/projects/answers/' + id)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
},
eventRender: function (event, element) {
// console.log(event)
},
eventClick: (event) => {
this.selected = event;
console.log(event);
this.projectId = event.title;
this.clickedDate = event.start._i;
this.$router.push("mystartups?date=" + this.clickedDate + "&project_id=" + this.projectId + "&project_title=" + this.title);
},
dayClick(date, event, view) {
// console.log(date, event, view)
console.log(date.format())
console.log(event);
},
refreshEvents() {
this.$refs.calendar.$emit('refetch-events')
},
eventSelected(event) {
this.selected = event;
console.log(event);
}
},
template: `
<article class="tile is-child notification" v-show="isVisible">
<!--
<p class="title">{{ title }}</p>-->
<a class="title" v-bind:href=link style="text-decoration:none; font-family: 'Open Sans', sans-serif;"> {{title}}
<i class="far fa-edit"></i>
</a>
<button class="delete" aria-label="delete" #click="isVisible = false"></button>
<full-calendar ref="calendar" :config="config" :events="events" #event-selected="eventSelected"></full-calendar>
<p class="subtitle">{{ body }}</p>
</article>
`
});
This code works when i use it locally, but when i build it, the calendats don't show and i get this error :
> vue.esm.js:1741 ReferenceError: body is not defined
> at o.eval (eval at ko (vue.esm.js:10680), <anonymous>:3:642)
> at o.t._render (vue.esm.js:4544)
> at o.<anonymous> (vue.esm.js:2788)
> at je.get (vue.esm.js:3142)
> at new je (vue.esm.js:3131)
> at vue.esm.js:2795
> at o.hn.$mount (vue.esm.js:8540)
> at o.hn.$mount (vue.esm.js:10939)
> at init (vue.esm.js:4137)
> at vue.esm.js:5608

CSS/JS Image on-click change synchronized on multiple devices

I wanted to ask if it would be possible to do some script or css style for the fact that once I click on the image it will change to another. I found a lot like this, but I need it a little differently, I need to see the picture changed on one device when I click the picture on another device.
In the code I have an image type input and after clicking on the input I need to change the picture and remember the already changed value. So when I open the page on the new device, the image has already been changed.
<form method="get">
<input type="image" class="switch_img" src="switch_off.png" value="Zapnout" name="on1">
</form>
(The program works like switching off and on of LEDs. And I want the clicker to make the "animation" of the switch.)
I have the variables stored in the txt file in Raspberry, here is the part of the code that could theoretically be connected:
$fileName = __DIR__.'/txt/led2.txt';
if (!file_exists($fileName) || (file_get_contents($fileName) !== '1' && file_get_contents($fileName) !== '0')) {
file_put_contents($fileName, '1');
}
if (isset($_GET['on2']) && file_get_contents($fileName) === '1') {
shell_exec("/usr/local/bin/gpio -g write 15 1");
file_put_contents($fileName, '0');
}
else if (isset($_GET['on2']) && file_get_contents($fileName) === '0') {
shell_exec("/usr/local/bin/gpio -g write 15 0");
file_put_contents($fileName, '1');
}
Thanks for your help!
Projects like Vue, Vuetify and Axios make it easy to build out what you want with straightforward syntax, in just a few lines of "javascript".
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-content>
<v-container>
<h4>My Switch/s</h4>
<v-alert type="error" :value="error">
{{ error }}
</v-alert>
<v-card v-for="(item, index) in switches" :key="index">
<v-card-title primary-title>
<div>
<div class="headline"></div>
<span class="grey--text">{{ item.name }}</span>
</div>
</v-card-title>
<v-card-text>
<v-switch v-model="item.state" :label="item.state ? 'On' : 'Off'" color="success" hide-details #click="setState(item)"></v-switch>
</v-card-text>
</v-card>
</v-container>
</v-content>
</v-app>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
//
var vm = new Vue({
el: '#app',
data: () => ({
error: false,
pollId: 0,
switches: [{
name: 'LED 1',
state: false
}
]
}),
beforeDestroy: function() {
clearInterval(this.pollId);
},
mounted: function() {
this.getState()
this.poll()
},
methods: {
poll() {
clearInterval(this.pollId)
this.pollId = setInterval(() => {
this.getState()
}, 2000)
},
async getState() {
try {
const response = await axios.get('/switch.php')
this.switches = response.data
} catch (error) {
this.error = error
}
},
async setState(item) {
item.state = !item.state
try {
await axios.post('/switch.php', item)
} catch (error) {
this.error = error
}
}
}
});
</script>
</body>
</html>
Then the PHP part (switch.php):
<?php
$switches = file_get_contents('switches.json');
// handle toggle
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// get json body
$body = (array) json_decode(file_get_contents('php://input'), true);
// toggle the switch
shell_exec('/usr/local/bin/gpio -g write 15 '.intval(!empty($body['state'])));
// set its current state
if (isset($switches[$body['name']])) {
$switches[$body['name']]['state'] = $body['state'];
} else {
$switches[$body['name']] = $body;
}
// save
file_put_contents('switches.json', json_encode($switches, JSON_PRETTY_PRINT));
header('HTTP/1.1 204 No content');
} else {
header('Content-Type: application/json');
echo json_encode($switches);
}
Untested but should point you in the right direction.

Categories