Froala and Aurelia integration - aurelia

I use the Froala editor plugin inside my Aurelia app. It works pretty well.
We can pass custom parameters to the plugin in main.ts like below:
// Use the aurelia-froala-editor plugin.
aurelia.use.plugin('aurelia-froala-editor', config => {
config.options({
toolbarInline: true
})
});
Then inject the froala component inside a page:
<froala-editor></froala-editor>
But now I pass parameters directly inside my froala componont on my page:
<froala-editor value.two-way="post.content" config.bind="{
toolbarInline: true,
charCounterCount: false,
imageUploadURL: 'http://localhost:5000/api/froala/UploadImage',
fileUploadURL: 'http://localhost:5000/api/froala/UploadFile',
imageManagerLoadURL: 'http://localhost:5000/api/froala/LoadImages',
imageManagerDeleteURL: 'http://localhost:5000/api/froala/DeleteImage',
imageManagerDeleteMethod: 'POST'
}" event-handlers.bind = "{
'image.uploaded': imageUploaded,
'image.removed': imageRemoved,
'image.file.unlink': imageFileUnlink
}"></froala-editor>
It works pretty well also.
What did not seems to works is mixing parameters passed in main.ts and in the component on a page. The component on the page seems to ignore completely parameters passed at initialization of the plugin in main.ts.
For example if I move the charCounterCount parameter from the component on my page to the initialization in main.ts it is simply ignored.

Related

Cannot map custom js to my custom template in bigcommerce shopica theme with stencil

I 've added custom page and js for it in stencil bigcommerce.
It works fine locally but when I push it on bigcommerce, it does not work well.
I have added custom template template/pages/custom/page/custom-layout.html and I've added custom js for it in assets/js/custom/custom.js.
I've configured some loading settings in assets/js/app.js as follows:
const customClasses = {
'pages\\custom\\page\\custom-layout': () => import('./custom/custom')
}
It works locally; but, on a server, it does not at all.
Your customClasses object should use forward slashes like so:
"pages/custom/page/custom-layout": () => import("./custom/custom")
You should also make sure that your custom.js file is extending the PageManager class like so:
import PageManager from "../page-manager";
export default class CustomClass extends PageManager {
constructor(context) {
super(context);
// other constructor code here
}
onReady() {
// your code for the onReady event here
}
// ... any other code
}
If this is done properly your custom JS class will be injected to the page. However, once you bundle and upload your theme, you must also make sure to apply your custom template to the page, as the config.stencil.json file is not packaged with your theme. This can be done from within the BigCommerce control panel by going to Storefront > Web Pages > [Your page] and changing the Template Layout File accordingly.

Vue.js - Embed Swagger UI inside a Vue component?

I have a form in my Vue component which uploads the api file. Now I want to render the contents of the file like this:
I have imported swagger client library: https://github.com/swagger-api/swagger-ui.
Now, here
is an example of how you do it in a static page. But I need to do it inside a Vue component (or Quasar, specifically), so I do it like that:
Register swagger-ui inside my register components file:
<link rel="stylesheet" type="text/css" href="swagger-ui.css">
Now it is available as:
this.swaggerUI({})
anywhere in my components. Inside my component I have a div in a template to render the api file:
<template>
<q-form>here lies q-file element, submit button and other stuff</q-form>
<div id="swagger-ui"></div>
</template>
In the mentioned question he had something like:
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "https://yourserver.com/path/to/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
]
})
window.ui = ui
}
</script>
Here's the difference: first of all, no window.onload, I must render it on submit button. Then, I deal with an uploaded file stored in my model, so no URL here. Now, I don't get how to make it work with locally stored file, when I try with the remote url, it gives me:
vue.esm.js?a026:628 [Vue warn]: Error in v-on handler: "Invariant Violation: _registerComponent(...): Target container is not a DOM element."
I was getting a similar error (Target container is not a DOM element) trying to use a static swagger spec. Instead of using window.onload, I found that Vue has the mounted() function, so this Vue 3 file worked for me:
<template>
<div class="swagger" id="swagger"></div>
</template>
<script>
import SwaggerUI from 'swagger-ui';
import 'swagger-ui/dist/swagger-ui.css';
export default {
name: "Swagger",
mounted() {
const spec = require('../path/to/my/spec.json');
SwaggerUI({
spec: spec,
dom_id: '#swagger'
})
}
}
</script>
This one appeared to be a simple yet very unobvious typo: in windows.onload function:
dom_id: '#swagger-ui',
must instead be
dom_id: 'swagger-ui',
without hash sign, that's it!

How to insert content inside tinymce editor using vue js?

I want to insert content like <span class="some-class">text</span> inside tinymce editor using a button in vue js template. How could I accomplish that using the tinymce-vue wrapper?
Here's the code:
<template>
<tinymce-editor
api-key="my-api-key-here"
/>
<button #click="addContent">button</button>
</template>
import Editor from '#tinymce/tinymce-vue'
export default {
components: {
tinymceEditor: Editor
},
methods: {
addContent () {
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
}
}
}
Edit:
I also installed tinymce using npm i tinymce --save and added the import import tinymce from 'tinymce/tinymce to the code above. Now I don't get the error 'tinymce' is not defined anymore, but the editor doesn't appear either.
If you want to use tinymce in vue with typscritt to set up your content and avoid the undefined error you need to import tinyMCE as
import { getTinymce } from '#tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE';
Then you can set your content
getTinymce().activeEditor.setContent('coucou');
In your event handler for the button click, you can call TinyMCE's .setContent() method to set editor content.
Here is a demo:
https://codesandbox.io/s/set-content-in-tinymce-in-vue-jzciu
Don't forget, tinymce-vue doesn't include the code for TinyMCE itself. You'll either have to use an API key (which you can get for free at tiny.cloud) or use a self-hosted installation of TinyMCE. (For more info, see Step 6, here: https://www.tiny.cloud/docs/integrations/vue/#procedure)
I finally gave up trying to get access to tinymce in Vue 3 component. It either undefined or if it is not undefined - setContent command just do nothing - no errors but still no content inserted.
I just used recommended for "#tinymce/tinymce-vue" way of data binding using v-model
It looks like this:
<Editor
v-model="someLocalVar"
api-key="no-api-key"
:init="{
plugins: 'lists link image table code help wordcount',
}"
/>
then
watch(someLocalVar, () => {
//do whatever you like with your someLocalVar
});
If you want to insert content into TinyMCE you should use its APIs to do so:
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#setcontent
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#insertcontent
For example:
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
tinymce.activeEditor.insertContent('<span class="some-class">text</span>');

Multiple Aurelia Instances - Aurelia Webpack Plugin - aureliaApp option - "module not found"

I am composing my web app as a number of Aurelia "feature" apps - although I'm not using Aurelia features as such. Consequently in my html markup I have two entry points pointing to different apps:
<!-- Top Navigation Bar -->
<div aurelia-app="topnav"></div>
<!-- Main App-->
<div aurelia-app="main"></div>
I am using webpack and everything works perfectly using the single "main" app. Webpack generates a JS file "main.bundle.js" which I include in the src tag.
Things are not so straightforward when I added the "topnav" app. In webpack I tell the plugin to use a different aureliaApp name:
new AureliaPlugin({ aureliaApp: "topnav"}),
and, as you can see my HTML entrypoint also calls "topnav". Webpack generates a JS file "topnav.bundle.js" which I also include. I have a file called "topnav.ts" which contains the aurelia Cionfigure function which ends:
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName("nav")));
And a pair of files "nav.ts", "nav.html" which constitute my viewmodel and view.
When I run the app aurelia loads and the "nav" module code executes. But I then get an error - see below.
The module which it reports that it cannot find is the one entered into the HTML markup.
Should this work? Have I missed something?
I should add, everything seems to work. I can create and update properties in the viewmodel and these are bound to the view. It's just that this error is thrown.
You are doing nothing wrong, just unsupported scenario. Per official doc-wiki: https://github.com/aurelia/webpack-plugin/wiki/AureliaPlugin-options#aureliaapp
You can have only 1 auto entry module with aureliaApp configuration. To solve this, you just need to add PLATFORM.moduleName('topnav') to your main.ts (and put it on root level)
Another way to do is to bootstrap manually:
// in your index.ts
import { bootstrap } from 'aurelia-bootstrapper';
// bootstrap top nav application, with one instance of Aurelia
bootstrap(aurelia => {
// do your configuration
aurelia
.start()
.then(() => aurelia.setRoot(
PLATFORM.moduleName('topnav'),
document.querySelector('#topnav')
);
});
// bootstrap main application, with another instance of Aurelia
bootstrap(aurelia => {
// aurelia.use.standardConfiguration();
// ...
aurelia
.start()
.then(() => aurelia.setRoot(
PLATFORM.moduleName('app'),
document.querySelector('app')
)
});

How to mix Vue components with HTML outside the template

Think about a wordpress blog, or a standard CMS with some content. I use a wysiwyg editor (CKEditor) to write my contents and save them to db.
I want to use some Vue components inside this HTML, and so I add a wrapper div to my theme. HTML pages are wrapped by
<div id="#my-custom-app">
...html from server
</div>
Basically I want to add for example
<my-app-image-compare></my-app-image-compare>
using CKEditor inside my HTML, then I will create an app mounted on #my-custom-app div. I will insert the app at the end of the html body.
Vue.app file doesn't have a template, the template is basically my HTML page written with CKEditor, but every component is loaded and defined by the app and every component has a template.
How can I do? Is there a way to have a main Vue app file without a defined template?
Option 1:
First create a vue container on a basic template. This template will then load a component which gets your data from the sever and displays it, so:
// This is your main vue instance container
<div id="#my-custom-app">
<dynamic-html v-if="myHtmlFromServer" template="myHtmlFromServer"></dynamic-html>
</div>
Within this main component, you need to hook up created event and populate myHtmlFromServer with your HTML content from the editor.
import DynamicHtml from './myComponents/DynamicHtml'
new Vue({
el: '#my-custom-app',
data () {
return {
myHtmlFromServer: ''
}
},
components: {
DynamicHtml
}
created () {
// this.myHtmlFromServer = this.getDataFromServer()
}
})
The <dynamic-html> component, would have props: ['template'] and on the created event would assign this.$options.template = this.template.
This option will set the HTML template of that component and allow Vue to render it as normal (meaning you can then do {{someVal}} in your CKEditor.
Option 2:
Another option is if you're using a server side language like PHP, then you could just put that html on the page i.e echo $myHtmlContent and as long as that content contains <div id="#my-custom-app"> you Vue instance will mount. PHP will add the HTML to the page before the JS processes the page so it'll just work.