How to dynamically insert text in Ckeditor5 for Vue 2 - vuejs2

My application provides many selectable standard paragraphs which users can insert at any point. In a previous version insertion was simple: CKEDITOR.instances[editorId].insertHTML(text).
I'm trying to use v5 api with model.insertContent(text) but get error:
"vue.runtime.esm.js:3020 TypeError: t2.is is not a function
at bl.rp (converters.js:771:21)
at bl.fire (emittermixin.js:199:30)
at <computed> (observablemixin.js:262:16)
at VueComponent.testInsert (Test.vue:29:1)"
Here's the composition file. I have tried accessing the insertContent method from this.editor and from the apiReference returned from the #ready event;
<template>
<div>
<button #click="testInsert('abracadabra')">Insert literal content</button>
<ckeditor tag-name="textarea" :editor="editor" v-model="doc.HTML" #ready="editorReady" :config="editorConfig"></ckeditor>
</div>
</template>
<script>
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default {
name: 'testEditorInsert',
mounted() {
},
data() {
return {
doc: {ID: 0, HTML: "This is a sample text. Insert here? This is the remainder of the sample text"},
editor: ClassicEditor,
editorData: 'loading',
editorConfig: {
toolbar: [ 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
},
editorApi:null ,
}
},
methods: {
testInsert: function(text) {
console.log(this.editorApi, text);
//this.editor.model.insertContent(text);
this.editorApi.model.insertContent(text);
},
editorReady: function(editor) {
this.editorApi = editor;
}
},
}
</script>

Related

How to show default value in Quill text editor in Vue3

As you can see in the picture, I have a text editor with Quill. this is admin panel in my project and when I write something in my text editor and want to display it, it is working fine. For example, if I want to write a description in bold it goes to the front end like this: Description and I can display it with this code:
<div v-html="product.attributes.description"></div>
But my problem is I want to show this value inside of y text editor. So I want to show bold written 'Description' in my text editor instead of undefined but I couldnt figured out how to do it with Quill text editor. Here is my text-editor component:
<template>
<div class="form-control" v-bind:class="inputClasses" ref="editor"></div>
</template>
<script>
import Quill from 'quill';
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.bubble.css';
import 'quill/dist/quill.snow.css';
export default {
props: {
modelValue: { type: String, default: '' },
defaultValue: "",
},
data() {
return {
editor: null,
};
},
mounted() {
var _this = this;
this.editor = new Quill(this.$refs.editor, {
modules: {
toolbar: [
[{ header: [1, 2, 3, 4, false]} ],
["bold", "italic", "underline", "link", "image"],
],
},
theme: "snow",
formats: ["bold", "underline", "header", "italic", "link"],
placeholder: this.placeholder
});
this.editor.root.innerHTML = this.defaultValue;
this.editor.on("text-change", function () {
return _this.update();
});
},
methods: {
update: function update() {
this.$emit(
"update:modelValue",
this.editor.getText() ? this.editor.root.innerHTML : ""
);
},
},
}
</script>
If I understood your question properly, you want to set the value of the editor?
If so, I had the same problem and was able to resolve using this answer: How to use v-model in quill editor
<quill-editor v-model:content="modelname" contentType="html" />
Then you can set and retrieve the editor content using the 'modelname' property. Hope it helps!
How I got rid of the undefined value when contentType='html'.
<QuillEditor theme="snow" ref="quill" v-model:content="modelName" contentType="html" placeholder="Type job description here..." style="height: 300px"/>
mounted() {
this.$refs.quill.setContents('')
}

Vuemapbox markers are showing at the bottom of the page

I am trying to build a map application with the vuemapbox library , but the strange thing is , all the markers are showing at the bottom of the page which is strange , can any one help me with it ?
<template>
<div class="home">
<MglMap :accessToken="accessToken" :mapStyle="mapStyle" #load="onMapLoaded">
<MglMarker
:coordinates.sync="locations"
color="blue"
v-for="(location, index) in pins"
:key="index"
/>
</MglMap>
</div>
</template>
<script>
// # is an alias to /src
import Mapbox from "mapbox-gl";
import {
MglMap,
MglMarker
} from "vue-mapbox";
export default {
name: "Home",
components: { MglMap, MglMarker },
data() {
return {
accessToken:"xxx",
mapStyle: "mapbox://styles/mapbox/streets-v11",
pins: [
[20.341979525348204, 85.8345150468384],
[25.581627613058714, 80.87795332144299],
[25.199370930176993, 95.86881932189225],
],
};
},
beforeMount() {
this.$store.dispatch("set_user_location");
},
computed: {
locations() {
return this.$store.getters.getThisUserMarker;
},
},
created() {
this.mapbox = Mapbox;
},
methods: {
async onMapLoaded(event) {
// in component
this.map = event.map;
const asyncActions = event.component.actions;
await asyncActions.flyTo({
center: this.locations,
zoom: 4,
speed: 1,
});
},
},
};
</script>
This is what i have done so far , but having this strange issue , please help , Every help is appreciated .
Make shure that you have loaded mabpox css.
Try to set height for MglMap
<MglMap
width="100%"
height="100%"
...
/>

how can i get the formId of form element?

i'm trying to get the formId of the form element.
formId is used to send the template message for push notification.
i have poor knowledge of vuejs and its components so i wrote bad code.
please don't care the definition of the variable but only form element.
i tried v-el, $ref, el, but i only got element undefined. please help me.
<template>
<view class="center" style="height:100vh;background-color:#ededed;">
<uni-list class="my_data">
<uni-list-item :title=name :note=user_id :thumb=avatar #click="to_detail('profile','profile')"/>
</uni-list>
<view class="center-list-top" v-if="userRole == roles.ADMIN"></view>
<uni-list class="relative_data" v-if="userRole == roles.ADMIN">
<uni-list-item :title="title_userlist" #click="viewUserList"></uni-list-item>
<uni-list-item :title="title_stabyuser" #click="viewStatistics('user')"/>
<uni-list-item :title="title_stabyeq" #click="viewStatistics('eq')"/>
</uni-list>
<view>
<form ref="myForm" v-el:elForm report-submit=true>
<view>
<button v-on:click="submit()">submit</button>
<!-- <button form-type="submit">Submit</button> -->
<!-- <button form-type="submit" #click="sendTemplate()">Submit</button> -->
<button form-type="reset">Reset</button>
</view>
</form>
<!-- <button type="submit" #click="sendTemplate()">Send Template</button> -->
</view>
</view>
</template>
<script>
import uniList from '#/components/uni-list/uni-list.vue'
import uniListItem from '#/components/uni-list-item/uni-list-item.vue'
import config from '../../config.js'
export default {
components: {
uniList,
uniListItem
},
data() { // don't care this
//////////////////////
return {
avatar:'/static/default/user_default_512.png',
name : '',
user_id : '',
// user:{},
extraIcon1: {
color: '#008000',
size: '22',
type: 'list'
},
comment:false,
pending:{},
userRole: '',
roles: {},
title_userlist: this.$i18nMsg('User list'),
title_stabyuser: this.$i18nMsg('Statistics by user'),
title_stabyeq: this.$i18nMsg('Statistics by eq'),
title_about: this.$i18nMsg('About'),
is_id_Guest:true,
template_id: '',
/////////////////////////////////
}
},
onLoad() {
},
methods: {
submit: function(){
console.log(this);
///////////////////////////////////////
console.log(this.$els.elForm); //
console.log(this.$refs.myForm); //
/////////////////////////////////////
}
}
</script>
only 'undefined'.
you don't need to wrap methods inside onLoad, instead
<script>
import uniList from '#/components/uni-list/uni-list.vue'
import uniListItem from '#/components/uni-list-item/uni-list-item.vue'
import config from '../../config.js'
export default {
components: {
uniList,
uniListItem
},
data() { // don't care this
//////////////////////
return {
avatar:'/static/default/user_default_512.png',
name : '',
user_id : '',
// user:{},
extraIcon1: {
color: '#008000',
size: '22',
type: 'list'
},
comment:false,
pending:{},
userRole: '',
roles: {},
title_userlist: this.$i18nMsg('User list'),
title_stabyuser: this.$i18nMsg('Statistics by user'),
title_stabyeq: this.$i18nMsg('Statistics by eq'),
title_about: this.$i18nMsg('About'),
is_id_Guest:true,
template_id: '',
/////////////////////////////////
}
},
methods: {
submit: function(){
console.log(this);
///////////////////////////////////////
console.log(this.$els.elForm); //
console.log(this.$refs.myForm); //
/////////////////////////////////////
}
}
}
</script>

Unable to trigger render when switching between multiple objects containing content in different languages

I read Reactivity in Depth but can't solve the issue.
I'm creating a small single page app that contains images and text.
When the user clicks a button I want the language to change.
Currently I am storing the content in two files that export an object.
export default {
projects: [
{
title: 'Project Title',
year: 2016,
...
},
]
}
and importing that
import contentEn from './assets/content.en.js'
import contentDe from './assets/content.de.js'
new Vue({
el: '#app',
components: { App },
data: {
mainContent: {
content: contentEn
}
},
methods: {
switchToGerman(){
this.mainContent.content = contentDe
}
},
template: '<App :mainData="mainContent"/>',
})
When I assign another object to mainContent.content the rendering is not triggered.
I understand that adding and deleting properties from object don't lead to change detection but I switch out a whole object. I tried assigning it with this.$set with no success.
I also tried this and googled a lot but can't get it work.
Or is my approach just wrong?
Thank you for helping,
best,
ccarstens
EDIT:
See below the code for the App component and the ProjectElement
// App.vue
<template>
<div id="app">
<button #click="switchGerman">Deutsch</button>
<ProjectElement v-for="(project, key) in fullData.content.projects" :key="key" :content="project"/>
</div>
</template>
<script>
import ProjectElement from './components/ProjectElement'
export default {
name: 'App',
props: [
'mainData'
],
data () {
return{
fullData: {}
}
},
methods: {
switchGerman(){
this.$root.switchToGerman()
}
},
created(){
this.fullData = this.$props.mainData
},
watch: {
mainData: {
handler: function(newData){
this.fullData = newData
},
deep: true
}
},
components: {
ProjectElement,
}
}
</script>
And the ProjectElement
//ProjectElement.vue
<template>
<article :class="classObject" v-observe-visibility="{
callback: visibilityChanged,
throttle,
intersection: {
threshold
}
}">
<header v-html="description"></header>
<div class="content">
<carousel :per-page="1" :pagination-enabled="false">
<slide v-for="(slide, index) in projectContent.media" :key="index">
<VisualElement :content="slide" ></VisualElement>
</slide>
</carousel>
</div>
</article>
</template>
<script>
import {Carousel, Slide} from 'vue-carousel'
import VisualElement from './VisualElement'
export default {
name: "ProjectElement",
components: {
Carousel,
Slide,
VisualElement
},
props: [
'content'
],
data () {
return {
projectContent: {},
isVisible: false,
throttle: 300,
threshold: 0.8
}
},
created(){
this.projectContent = this.content
},
methods: {
visibilityChanged(isVisible){
this.isVisible = isVisible
}
},
computed: {
description(){
return `
<p>${ this.projectContent.title } - ${this.projectContent.year}</p>
<p>${ this.projectContent.description }</p>
`
},
classObject(){
return {
visible: this.isVisible,
'project-element': true
}
}
}
}
</script>
Did you try doing deep copy:
switchToGerman () {
const copyContent = JSON.parse(JSON.stringify(this.mainContent))
copyContent.content = contentDe
this.mainContent = copyContent
}
I found the solution (thank you #EricGuan for pointing out that the mistake must lay somewhere else)
As you can see in the original post I created a watcher for the mainData property and expected that this would trigger the re render.
What was missing is, that I didn't watch the content property on the ProjectElement component, thus not triggering a re render there.
I added this to ProjectElement.vue and now it works like a charm:
watch: {
content(newContent){
this.projectContent = newContent
}
},
Thank you everybody for helping me! <3

Error with prop definition in vuejs

I use datatable (https://github.com/pstephan1187/vue-datatable) component in VueJs 2.
My component is the following:
<template>
<div>
<div id="desktop">
<div v-if="visibility.personsTable">
<datatable-persons
:columns="persons_table_columns"
:data="rows"
filterable paginate
></datatable-persons>
</div>
</div>
</div>
</template>
<script>
import VueJsDatatable from 'vuejs-datatable';
import Profile from './user/Profile';
import ConnectionService from '../components/services/ConnectionService';
const connectionService = new ConnectionService();
Vue.component('showuser', {
template: `
<button class="btn btn-xs btn-primary" #click="goToUpdatePage">Профиль</button>
`,
props: [row],
methods: {
goToUpdatePage: function(){
}
}
});
export default {
components: {
datatablePersons: VueJsDatatable,
usersTable: VueJsDatatable,
},
data() {
return {
rows: [],
persons_table_columns: [
{label: 'id', field: 'id'},
{label: 'Имя', field: 'firstname'},
{label: 'Фамилия', field: 'lastname'},
{label: 'Отчетство', field: 'middlename'},
{label: 'Профиль', component: 'showuser'}
],
visibility: {
personsTable: false,
}
}
},
methods: {
showPersons() {
this.$http.get(hostname + 'name=person_list&session_id=' +
sessionApiId).then(response => {
this.rows = connectionService.renderMultipleInstances(response.body);
this.visibility.usersTable = false;
this.visibility.personsTable = true;
}, response => {
// error callback
});
},
}
}
</script>
I have the following error:
Uncaught ReferenceError: row is not defined
at Object.defineProperty.value (app.js:5309)
at webpack_require (app.js:20)
Due to documentation of "table" component, it should watch for "row prop" And using official example it works properly.
In the definition of your showuser component props should be an array of strings:
props: ['row']
These strings should match the names of the attributes you use to pass data to the component.
Also from the sinppet I would guess you want it to be 'rows' not 'row'.