Please try the code snippet.
I have many components in Vue Router, every component has its own TinyMCE editor to edit content. However, TinyMCE is only displayed for the first loaded router. There is an error in the console: Permission denied to access property "document" which only occurs when I use TinyMCE and Vue together, I don't know if it is the reason of my problem.
I appriciate if anyone has a solution!
I have another version of this problem at jsfillde: http://jsfiddle.net/tranduyhung/NF2jz/5105/ . I don't get the error Permission denied to access property "document" at jsfiddle.
var Foo = Vue.extend({
template: '#foo',
ready: function() {
// This doesn't help
//tinyMCE.remove()
tinyMCE.init({selector: "#tinymcefoo"})
// This is not working
//tinyMCE.execCommand('mceAddControl', false, '#tinymcefoo');
//tinyMCE.execCommand('mceAddEditor', false, '#tinymcefoo');
}
})
var Bar = Vue.extend({
template: '#bar',
ready: function() {
// This doesn't help
//tinyMCE.remove()
tinyMCE.init({selector: "#tinymcebar"})
// This is not working
//tinyMCE.execCommand('mceAddControl', false, '#tinymcefoo');
//tinyMCE.execCommand('mceAddEditor', false, '#tinymcefoo');
}
})
var App = Vue.extend({})
var router = new VueRouter()
router.map({
'/foo': {
component: Foo
},
'/bar': {
component: Bar
}
})
router.redirect({
'*': '/foo'
})
router.start(App, '#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.7/vue-router.min.js"></script>
<script src="//cdn.tinymce.com/4/tinymce.min.js"></script>
<div id="app">
<p>Menu: <a v-link="{ path: '/foo' }">Working</a> | <a v-link="{ path: '/bar' }">Not working</a></p>
<hr>
<router-view></router-view>
<script type="text/x-template" id="foo">
<p>Working</p>
<textarea id="tinymcefoo"></textarea>
</script>
<script type="text/x-template" id="bar">
<p>Not working</p>
<textarea id="tinymcebar"></textarea>
</script>
</div>
Intialize tinyMCE just once, you can make it at the start of your application
tinceMCE.init({
mode: 'none'
});
Use the ready and beforeDestroy events of Vue to reload the editor at every initialization
var Foo = Vue.extend({
// ...
ready: function() {
tinyMCE.execCommand('mceAddEditor', true, 'tinymcebar'); // id without '#'
},
beforeDestroy: function() {
tinyMCE.execCommand('mceRemoveEditor', true, 'tinymcebar');
}
}
link to updated jsfiddle
Yes I found a solution like this:
// load tinymce placeholder plugin from from local static file
tinymce.PluginManager.load('placeholder', '/static/js/tinymce/plugins/tinymce-placeholder.plugin.js');
Here is the full source of my TinyMceComponent:
https://github.com/Doogiemuc/liquido-vue-frontend/blob/master/src/components/TinyMceComponent.vue
Try giving your textareas the same class and choose that class as selector:
<textarea id="tinymcefoo" class="my_editor"></textarea>
<textarea id="tinymcebar" class="my_editor"></textarea>
On ready use
tinyMCE.init({selector: ".my_editor"});
Related
I have loaded the jitsi meet script in the body of my public.html, and i have a component as follows:
<template>
<div class="container">
<div id="meet"></div>
</div>
</template>
<script>
export default {
name: "ServiceMeet",
mounted() {
const domain = "meet.jit.si";
const options = {
roomName: "PickAnAppropriateMeetingNameHere",
width: 700,
height: 700,
parentNode: document.querySelector("#meet"),
};
const api = new JitsiMeetExternalAPI(domain, options);
console.log(api.getVideoQuality());
},
};
</script>
When I try to run I get an error saying 18:21 error 'JitsiMeetExternalAPI' is not defined no-undef, however in the background i can see that the meet is working fine, so I do I fix the error or dismiss it.
You could disable the linting error, but I would recommend specifying it as a global variable instead.
.eslintrc.js
module.exports = {
globals: {
JitsiMeetExternalAPI: true
}
}
It should work if you prefix the global with window:
const api = new window.JitsiMeetExternalAPI(domain, options);
I use conversation form package in my nuxt js project. I found custom component from github where used this package.
Component code:
<template>
<form id="my-form-element" cf-form></form>
</template>
<script>
import * as cf from 'conversational-form'
export default {
mounted: function() {
this.setupForm()
},
methods: {
setupForm: function() {
const formFields = [
{
tag: 'input',
type: 'text',
name: 'firstname',
'cf-questions': 'What is your firstname?'
},
{
tag: 'input',
type: 'text',
name: 'lastname',
'cf-questions': 'What is your lastname?'
}
]
this.cf = cf.startTheConversation({
options: {
submitCallback: this.submitCallback
},
tags: formFields
})
this.$el.appendChild(this.cf.formEl)
},
submitCallback: function() {
const formDataSerialized = this.cf.getFormData(true)
console.log('Formdata, obj:', formDataSerialized)
this.cf.addRobotChatResponse(
'You are done. Check the dev console for form data output.'
)
}
}
}
</script>
Now when I use this component get error message:
window is not defined
As solution of this error recomended this answer from stackowerflow
And after seen this answer I've change component code.
Changes:
1.Removedimport * as cf from 'conversational-form'
2.Replaced mounted() hook content to:
var cf = require('conversational-form')
this.setupForm()
After changes error fixed but package not work correctly. When call this library inside methods as this.cf nuxt js can't found cf var. How I can fix this problem?
Also you can see live demo of this package in vue js here
This is a rare situation that you may need to use the <client-only> tag. If you're using a version older than 2.9.0, then it is <no-ssr>. Docs found here.
Example:
<template>
<client-only>
<form id="my-form-element" cf-form></form>
</client-only>
</template>
<script>
import * as cf from 'conversational-form'
export default { ... }
</script>
This instructs Nuxt to only render the component client side, where window is defined.
I want to change a data property and run a method on my Vue instance within Laravel. However due to using webpack and laravel I can't seem to access the instance how I would expect to:
So window.app doesn't appear to be the correct instance of my Vue class.
Below is the Blade View i'm loading, as you can see I append a script tag to my main layout.blade.php, simply trying to change the Vue instance data property, and run a method.
#push('scripts')
<script>
app.unsaved = true;
app.triggerEvent(null, 'models', null);
</script>
#endpush
Below is part of my app.js (resources/assets/js/app.js):
const app = new Vue({
el: '#app',
components: {
'models-select': ModelsSelect
},
data: {
showModel: false,
unsaved: false
},
mounted: function() {
let _self = this;
(function() {
document.querySelectorAll("input, textarea, select").forEach(function(e) {
e.addEventListener('change', function() {
_self.unsaved = true;
e.classList.add('is-changed');
});
});
function unloadPage(){
if (_self.unsaved) return 'You appear to have un-saved changes!';
}
window.onbeforeunload = unloadPage;
})();
},
methods: {
triggerEvent: function(event, target, property)
{
app.$refs[target].update(event, property);
}
As you can see i'd expect to manipulate the Vue instance through the global app variable I have defined within the app.js. However this doesn't appear to be the case.
I get the following error when running the triggerEvent method:
app.triggerEvent is not a function
In your app.js file, change const app = new Vue({ to window.app = new Vue({.
Then within your <script> tags, change it to this.
<script>
window.app.unsaved = true;
window.app.triggerEvent(null, 'models', null);
</script>
I have been wracking my brain and the internet and have not found an answer to this issue. Setup a site using Hot towelette, upgraded it to durandal 2.0 and all the associated packages. Followed the guide for upgrading from 1.0 to 2.0 on Durandal's site and have everything working except the routes. The default route works and the site loads the default page as expected. However clicking on the navs on the top of the page, the url changes but nothing happens. The url changes to http://host/#view. I saw the missing slash after the hash and added the hash to the route to fix that, but still does not change the view. I've tried many different samples etc. but haven't found what the problem is.
main.js
require.config({
paths: {
"text": "../Scripts/text",
"durandal": "../Scripts/durandal",
"plugins": "../Scripts/durandal/plugins",
"transitions": "../Scripts/durandal/transitions",
}
});
define('jquery', [], function() { return jQuery; });
define('knockout', [], function () { return ko; });
define(['durandal/system', 'durandal/app', 'durandal/viewLocator', 'plugins/router', 'services/logger'],
function (system, app, viewLocator, router, logger) {
app.title = "Remedy Approvals";
app.configurePlugins({
router: true
})
// Enable debug message to show in the console
system.debug(true);
app.start().then(function () {
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.backgroundpositionClass = 'toast-bottom-right';
router.handleInvalidRoute = function (route, params) {
logger.logError('No Route Found', route, 'main', true);
};
// When finding a viewmodel module, replace the viewmodel string
// with view to find it partner view.
//router.makeRelative({ moduleId: 'viewmodels' });
viewLocator.useConvention();
// Adapt to touch devices
//app.adaptToDevice();
//Show the app by setting the root view model for our application.
app.setRoot('viewmodels/shell', 'entrance');
});
});
shell.js:
define(['durandal/system', 'plugins/router', 'services/logger'],
function (system, router, logger) {
var shell = {
router: router,
activate: activate
};
return shell;
function activate() {
var routes = [
{ route: ['approvals',''], moduleId: 'approvals', title: 'My Approvals', nav: true, hash: '#/approvals' },
{ route: 'alternate', moduleId: 'alternate', title: 'Alternate Approvals', nav: true, hash: '#/alternate' }
];
return router.makeRelative({ moduleId: 'viewmodels' })
.map(routes)
.buildNavigationModel()
.mapUnknownRoutes('approvals', 'not-found')
.activate();
}
// function log(msg, data, showToast) {
// logger.log(msg, data, system.getModuleId(shell), showToast);
// }
}
)
shell.html
<div>
<header>
<!--ko compose: {view: 'nav'} --><!--/ko-->
</header>
<section id="content" class="main container-fluid">
<!--ko compose: {model: router.activeItem,
afterCompose: router.afterCompose,
transition: 'entrance'} -->
<!--/ko-->
</section>
<footer>
<!--ko compose: {view: 'footer'} --><!--/ko-->
</footer>
</div>
nav.html
<div>
<ul class="nav nav-pills" data-bind="foreach: router.navigationModel">
<li role="presentation" data-bind="css: {active: isActive}"><a data-bind="attr: {href: hash}, html: title"></a></li>
</ul>
<label class="pull-right">username</label>
</div>
You're using the compose binding on the activeItem property of the router. I don't know if that's "wrong" as such, but I'm using the "router" binding for mine:
<div class="container page-host" data-bind="router"></div>
Excerpt from http://durandaljs.com/get-started.html:
At the bottom of the view is a special router binding which connects
to our router in the module. This serves as a placeholder where the
current "page" will be displayed. The transition property indicates
that whenever the page changes, Durandal should use the "entrance"
transition animation.
I'm getting the following error after upgrading Ember to the latest version:
Error while processing route: portfolio Cannot read property 'connectOutlet'
The error takes place whenever I navigate for example from:
http://localhost:8080/#/portfolio
to:
http://localhost:8080/#/publications
The weird thing is that if I refresh the pages many times sometimes it works and some times it's doesn't so feels like some file is loaded too late or maybe loaded twice.
aplication.hbs
The application view renders the header, footer and main container, which contains the application {{outlet}}.
<!-- ... -->
<div class="container" id="maincontainer">
<div class="maincontainer">
{{outlet}}
</div>
</div>
<!-- ... -->
index.hbs
My index view renders a couple of subviews:
<div class="jumbotron fadeInUp animated">
<div class="row">
<div id="summary_content">
{{view view.CvSummaryView}}
</div>
</div>
</div>
routes
In all my routes I'm only adding the model() function. I'm not overriding renderTemplate() or anything else.
define([
'Ember'
],
function (Ember) {
"use strict";
return Ember.Route.extend({
model: function()
{
var result = {};
$.ajax({
async: false,
dataType: "json",
url: './website/js/models/portfolio.json',
success: function(data){
result.portfolio = data;
}
});
return result;
}
});
}
);
I tried the following with no luck:
renderTemplate: function(){
this.render({
outlet: "main",
into: "application"
});
}
Do you have any ideas about what can be the root cause of this issue?
The entire app source code can be found at https://github.com/remojansen/remojansen.github.io/tree/master/website/js
UPDATE 1
I've been reading the Ember documentation and I added {{outlet "main"}} into my application template and tried with:
renderTemplate: function() {
this.render('blog', { // the template to render
into: 'application', // the template to render into
outlet: 'main' // the name of the outlet in that template
});
}
The I've been debugging the Ember code and I reached this function:
function appendView(route, view, options) {
if (options.into) {
var parentView = route.router._lookupActiveView(options.into);
var teardownOutletView = generateOutletTeardown(parentView, options.outlet);
if (!route.teardownOutletViews) { route.teardownOutletViews = []; }
replace(route.teardownOutletViews, 0, 0, [teardownOutletView]);
parentView.connectOutlet(options.outlet, view);
} else {
var rootElement = get(route.router, 'namespace.rootElement');
// tear down view if one is already rendered
if (route.teardownTopLevelView) {
route.teardownTopLevelView();
}
route.router._connectActiveView(options.name, view);
route.teardownTopLevelView = generateTopLevelTeardown(view);
view.appendTo(rootElement);
}
}
In the function above, in the line:
var parentView = route.router._lookupActiveView(options.into);
The variable parentView is null and options.into is "application". So the line below throws an exception:
parentView.connectOutlet(options.outlet, view);
I have defined the application template and view but not an application route I don't know if that could be the problem.
Thanks!
After some time debugging I noticed that the ember router._activeViews element didn't always contain the application view:
Works
Doesn't work
I tried to analyse why was this happening and because as I said in the question:
The weird thing is that if I refresh the pages many times sometimes it
works and some times it's doesn't so feels like some file is loaded
too late or maybe loaded twice.
I was almost sure that is was related with the usage of require.js and loading application components asynchronously.
The solution was use deferReadiness() and advanceReadiness(). Here is what I did in case it can help somebody in the future...
app.js
define(['Ember'], function (Ember) {
"use strict";
window.app = Ember.Application.create({
LOG_TRANSITIONS: false, // basic logging of successful transitions
LOG_TRANSITIONS_INTERNAL: false, // detailed logging of all routing steps
LOG_VIEW_LOOKUPS: false // detailed logging of view resolution
});
// Delay the app's initialization . We will invoke advanceReadiness()
// when are ready for the app to be initialized
window.app.deferReadiness();
return window.app;
});
main.js
require([
'website/js/app',
/* routes, views... */
], function (
app,
/* routes, views... */
){
"use strict";
// Configure Routes
app.Router.map(routes);
// Set Routes
app.IndexRoute = indexRoute;
// ...
// Set Views
app.IndexView = indexView;
// ...
// We're ready to launch the app!
app.advanceReadiness();
});