Make callback in Vue - vue.js

My vue widget works like this.
I use https://github.com/karol-f/vue-custom-element to make embed widget to any webpage.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Foo Page</title>
</head>
<body>
<vue-widget>...</vue-widget>
<script type="text/javascript" src="/js/app.js"></script>
</body>
</html>
My task is to make callback function in my app which can be triggered OUTSIDE <vue-widget>...</vue-widget>.
I tried this bit it don't work and I don't know why
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Foo Page</title>
</head>
<body>
<vue-widget>...</vue-widget>
<script type="text/javascript" src="/js/app.js"></script>
<script>
vueWidget_onInitCallback = function() {
console.log('foo')
}
</script>
</body>
</html>
App.vue:
methods: {
someFunction() {
if (typeof vueWidget_onInitCallback == 'function') {
vueWidget_onInitCallback();
}
},
},
mounted() {
this.someFunction()
}

Okay I figured it out.
index.html
<script>
function vueWidget_onInitCallback () {
console.log('plugin initiated');
}
</script>
App.vue
methods: {
someFunction() {
function onInit(callback) {
if (callback && typeof(callback) == "function") callback();
}
onInit(vueWidget_onInitCallback);
},
},
mounted() {
this.someFunction()
}
Everything works just fine.

Related

[Vue warn]: Failed to mount component: template or render function not defined, using Laravel 8

I'm trying to create a new project but I'm getting this error and I don't know why. I'm using Laravel 8, Vue and Inertia.js.
I'm not sure if these files are important but I'll add anyways
webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
mix.js('resources/js/app.js', 'public/js').vue({ version: 2 })
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'#': path.resolve('resources/js'),
},
},
})
.babelConfig({
plugins: ['#babel/plugin-syntax-dynamic-import'],
})
.version();
app.js
import InertiaApp from '#inertiajs/inertia-vue'
import Vue from 'vue'
Vue.use(InertiaApp);
const app = document.getElementById('app');
app.setAttribute(':class',"{'loaded': loaded}");
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => import(`#/Pages/${name}`).then(module => module.default),
},
data(){
return{
loaded:true
}
}
}),
}).$mount(app);
app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
#inertia
</body>
</html>
Finally the page I'm trying to show Login.vue
<template>
<div>
<h1>Login</h1>
</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
console.log('mounted');
}
}
</script>
I don't know why this is happening or how to fix it.
What am I doing wrong?

bulma-calendar not updating as Vue.js component

I am learning Vue.js and would like to implement the bulma-calendar module in my app. I came this far, but the calendar is somehow not updating, when I am selecting a new Date.
Sorry if I can't specify the problem more, as I said declarative programming is very new to me.
The template I got from the official website of bulma-calendar: https://demo.creativebulma.net/components/calendar/v6//#integration
Vue.component("comp-calendar", {
template: `
<div>
<input ref="calendarTrigger" type="date">
</div>
`,
data: function () {
return {
date: new Date(),
};
},
mounted: function () {
const options = {
type: "date",
color: "danger",
dateFormat: "DD-MM-YYYY",
startDate: this.date,
displayMode: "inline",
};
const calendar = bulmaCalendar.attach(
this.$refs.calendarTrigger,
options
)[0];
calendar.on("date:selected", (e) => (this.date = e.date));
},
});
var app = new Vue({
el: "#app",
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- import bulma -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma#0.9.1/css/bulma.min.css">
<!-- import bulma-calendar -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-calendar#6.0.9/dist/css/bulma-calendar.min.css">
</head>
<body>
<div id="app">
<comp-calendar></comp-calendar>
</div>
<!-- import bulma-calendar -->
<script src="https://cdn.jsdelivr.net/npm/bulma-calendar#6.0.9/dist/js/bulma-calendar.min.js"></script>
<!-- import https://vuejs.org -->
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
<script src="src/js/test.js"></script>
</body>
Any help? Thanks
EDIT: Did not help:
[...]
<input type="date">
[...]
const calendar = bulmaCalendar.attach('[type="date"]', options)[0];
calendar.on("select", (e) => (this.date = e.date))
Probably a bug in 6.0.9. Working with 6.0.0 (according to documentation here: https://creativebulma.net/product/calendar/demo) worked fine.
calendar.on("select", (e) => (this.date = e.date))
here this.date is incorect. this "this" is calendar object not the vue object

How to change initially generated title after file build in index.html

I have downloaded a vue.js template from the web. Whenever I build files via npm the title on the index.html keeps being swapped to the name of the template. Is there a way to change the default title?
As I understand your question - you need to configure your vue.config.js file something like this (pay attention on Webpack part) - these files are from working project, so you have maximum understanding on how it could look at the end:
module.exports = {
baseUrl: '/',
outputDir: (process.env.NODE_ENV === 'production' ? '../web/' : '../web/js/'),
indexPath: '../app/Resources/views/index.html.twig',
// Setting this to false can speed up production builds if you don't need source maps for production.
productionSourceMap: false,
// By default, generated static assets contains hashes in their filenames for better caching control.
// However, this requires the index HTML to be auto-generated by Vue CLI. If you cannot make use of the index HTML
// generated by Vue CLI, you can disable filename hashing by setting this option to false,
filenameHashing: false,
lintOnSave: false,
// https://cli.vuejs.org/ru/config/#devserver-proxy
devServer: {},
// https://cli.vuejs.org/ru/config/#chainwebpack
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = 'Ojok Deep Sales Platform';
args[0].template = './index.html.template';
return args;
})
}
};
And after you have updated your vue.config.js file, change your index.html template file to be like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title><%= htmlWebpackPlugin.options.title %></title>
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900' rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet">
<script type="text/javascript" src="../js/go.js"></script>
<script type="text/javascript" src="../js/momentjs.js"></script>
<script type="text/javascript" src="../js/webphone/flashphoner.js"></script>
<script type="text/javascript" src="../js/webphone/SoundControl.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Pay attention on what is being included in <title>-tag:
<title><%= htmlWebpackPlugin.options.title %></title>
After generating new index.html file your title should be set to whatever you have written into args[0].title option.
Hope this helps.
I'm still new at VueJS, but here were my findings. I'd love any suggested options or improvements. I went with option #2.
Option 1: set for Multiple Pages mode
vue.config.js
module.exports = {
pages: {
index: {
entry: 'src/main.js',
// template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title>
title: 'My Website Title',
},
}
}
Option 2: titleMixin (referenced from https://medium.com/#Taha_Shashtari/the-easy-way-to-change-page-title-in-vue-6caf05006863)
titleMixin.js added to mixins folder
function getTitle (vm) {
const { title } = vm.$options
if (title) {
return typeof title === 'function'
? title.call(vm)
: title
}
}
export default {
created () {
const title = getTitle(this)
if (title) {
document.title = title
}
}
}
added to main.js
import titleMixin from './mixins/titleMixin'
Vue.mixin(titleMixin)
Use in Component Pages
<script>
export default {
title: 'Foo Page'
}
</script>
Use in Vue instance with a function
<script>
export default {
title () {
return `Foo Page — ${this.someValue}`
},
data () {
return {
someValue: 'bar'
}
}
}
</script>
Option 1:
Edit your /public/index.html and replace this:
<title><%= htmlWebpackPlugin.options.title %></title>
with this:
<title>Your Title Here</title>
Option 2:
vue.config.js
module.exports = {
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].title = 'Your Title Here';
return args;
});
}
}
/public/index.html
<title><%= htmlWebpackPlugin.options.title %></title>

Having Issue On Adding A Package to Dojo

Can you please take a look at this code and let me why I am not able to add a Package dbootstrap into the dojo toolkit?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
</head>
<body class='dbootstrap'>
<div class="jumbotron">
<h1 id="greeting">app</h1>
</div>
<!-- load Dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="async: true"></script>
<script>
var dojoConfig = {
packages: [
{
location: '/dbootstrap',
name: 'dbootstrap'
}
]
};
require([
'dbootstrap',
'dojo/dom',
'dojo/dom-construct'
], function(dbootstrap, dom, domConstruct) {
var greetingNode = dom.byId('greeting');
domConstruct.place('<i> Test!</i>', greetingNode);
});
</script>
</body>
</html>
As you can see in this image I already added the dbootstrap folder into the root directory
but I am getting these errors:
The dojoConfig need to be declared before including dojo.js, so, this should work for you
<script type="text/javascript">
var dojoConfig = {
packages: [
{
location: '/dbootstrap',
name: 'dbootstrap'
}
]
};
</script>
<!-- load Dojo -->
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="async: true"></script>
<script type="text/javascript">
require([
'dbootstrap',
'dojo/dom',
'dojo/dom-construct'
], function(dbootstrap, dom, domConstruct) {
var greetingNode = dom.byId('nodeId');
domConstruct.place('<i> Test!</i>', greetingNode);
});
</script>

Dojo/dijit script library treeview loading

The dojo api doesn't seem to load on my system (IE 8, Windows 7 with IIS 7.5). I try to test these examples by linking to the dojo api like this
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
</script>
I also downloaded the library to link to it directly like this.
<script type="text/javascript" src="dojo.js">/*_*/</script>
<script type="text/javascript">
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
</script>
But got the same result. The library scripts don't load the treeview. Are there issues with IE8, Windows 7 or IIS 7.5 for the dojo libary 1.6.1?
Do you know of a treeview with this functionality: MySQL database support, context menu, add/delete node, hyperlink in tree support?
Thanks.
Complete HTML file where the dojo api doesn't load.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
<!-- load Dojo -->
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
dojo.addOnLoad() {
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
}
</script>
<script type="text/javascript">
var treeDat = {
treeNodes: [
{ title:"World" },
{ title:"Business",
children:[
{ title:"News",
children:[
{ title:"Main"},
{ title:"Company News" },
{ title:"Economy" }
]
},
{ title:"Markets" },
{ title:"Technology" },
{ title:"Jobs and Economy" }
]
},
{ title:"Sports" }
]
};
</script>
<script type="text/javascript">
var TreeBuilder = {
buildTreeNodes:function (dataObjs, treeParentNode){
for(var i=0; i<dataObjs.length;i++){
var node = dojo.widget.createWidget("TreeNode",{
title:dataObjs[i].title,
expandLevel:99,
widgetId:(((treeParentNode)?treeParentNode.widgetId:"root_")+"_"+i)
});
treeParentNode.addChild(node);
treeParentNode.registerChild(node,i);
if(dataObjs[i].children){
this.buildTreeNodes(dataObjs[i].children, node);
}
}
},
buildTree:function (){
var myTreeWidget = dojo.widget.createWidget("Tree",{
widgetId:"myTreeWidget",
DNDMode:"between",
DNDAcceptTypes:["myTreeWidget"]
});
this.buildTreeNodes(treeDat.treeNodes,myTreeWidget);
var treeContainer = document.getElementById("myWidgetContainer");
var placeHolder = document.getElementById("treePlaceHolder");
treeContainer.replaceChild(myTreeWidget.domNode,placeHolder);
}
}
function addTreeContextMenu(){
var djWdgt = dojo.widget;
var ctxMenu = djWdgt.createWidget("TreeContextMenu",{});
ctxMenu.addChild(djWdgt.createWidget(
"TreeMenuItem",{caption:"Add Child Menu Item"}));
ctxMenu.addChild(djWdgt.createWidget(
"TreeMenuItem",{caption:"Delete This Menu Item"}));
document.body.appendChild(ctxMenu.domNode);
var myTree = dojo.widget.manager.getWidgetById("myTreeWidget");
/* Bind the context menu to the tree */
ctxMenu.listenTree(myTree);
}
dojo.addOnLoad(function(){
TreeBuilder.buildTree();
addTreeContextMenu();
});
</script>
</head>
<body>
<h1>Programmatic Dojo Tree Demo</h1>
<hr />
<div id="myWidgetContainer"
style="width: 17em; border: solid #888 1px; height:300px;">
<span id="treePlaceHolder"
style="background-color:#F00; color:#FFF;">
Loading tree widget...
</span>
</div>
</body>
</html>
You need to wrap the dojo.require calls in the dojo.addOnLoad function. This is required when using Dojo cross-domain build.
See more at http://dojotoolkit.org/reference-guide/quickstart/cross-domain.html
dojo.addOnLoad(function() {
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
});