We a create a html content using Vue Editor and save the data and close the dialog after saving . how do we remove the html content in the editor after the dialog box is closed
Using this editor for writing a html document in Vuejs --
import { VueEditor } from 'vue2-editor'
You just need to reset data property which has been passed to "v-model" attribute, something like that:
<template>
<vue-editor v-model="content" />
</template>
<script>
export default {
data() {
return {
content: '<p>Sample</p>',
};
},
methods: {
save() {
// Closing dialog code
this.content = null; // or this.content = ''
},
},
};
</script>
Related
As we know, we can have any html tag in vuejs via v-html, here in mounted() lifecycle function i want to make a simple link and attach it in to p tag. for example:
<template>
<p v-html="caption"></p>
</template>
<script>
export default {
name: "emulator",
props: {
caption: {
type: String,
required: false
}
},
mounted() {
this.$emit('caption', this.$el.innerText.replace(
/#([\p{L}\p{N}_-]+)/u,
'$&'
))
}
}
</script>
the this.$emit work fine but i don't have any link into p tag when i try to type for example:
hi #vuejs
it should be: <p>hi #vuejs</p>
replace method work fine too and we can test it from this link
I don't know if $emit in this component is necessary but the following works:
<template>
<p v-html="link"></p>
</template>
<script>
export default {
name: "emulator",
props: {
caption: {
type: String,
default: '#john'
}
},
computed: {
link(){
const anchorTag = this.caption.replace(
/#([\p{L}\p{N}_-]+)/u,
'$&'
)
this.$emit(anchorTag) // <--- remove this line if you don't need the HTML tag in your parent
return anchorTag
}
}
}
</script>
I have a Vue page which loads an json array from an api and displays the content in a list of multiple s by using v-for.
If you focus on one of the textarea's or change the text a function automatically resize's the textarea to fit the content.
<div v-for="post in posts">
<textarea v-model="post.body" rows="1" #focus="resizeTextarea" #keyup="resizeTextarea"></textarea>
</div>
resizeTextarea(e) {
let area = e.target;
area.style.overflow = 'hidden';
area.style.height = area.scrollHeight + 'px';
}
With my limited Vue knowledge, I can't find a solution to automatically resize all textarea's after loading the data from the API. There is no #load on a textarea.
I was trying to reach the same goal with using a watcher on the data but it feels like a long workaround.
Anyone a descent solution? Thank you!
https://jsfiddle.net/oehoe83/c1b8frup/19/
One solution would be to create a component for your textarea element and then resize it in the mounted() hook. Here's an example using single-file components:
// CustomTextarea.vue
<template>
<textarea
v-model="value"
ref="textarea"
rows="1"
#focus="resize"
#keyup="resize"
>
</textarea>
</template>
<script>
export default {
props: {
value: {
type: String,
required: true,
}
},
mounted() {
this.resize();
},
methods: {
resize() {
const { textarea } = this.$refs;
textarea.style.height = textarea.scrollHeight - 4 + 'px';
}
}
}
</script>
Then in your parent:
<template>
<div v-for="post in posts">
<CustomTextarea v-model="post.body" />
</div>
</template>
<script>
import CustomTextarea from './CustomTextarea.vue';
export default {
components: {
CustomTextarea,
}
// etc.
}
</script>
Note: if you're using Vue 3, replace value with modelValue in the child component.
Alternatively you could use a watch like you suggested, there's nothing wrong with that. Something like this:
watch: {
posts() {
// Wait until the template has updated
this.$nextTick(() => {
[...document.querySelectorAll('textarea')].forEach(textarea => {
this.resizeTextarea({ target: textarea });
});
});
}
}
you can add the ref attribute :
<div id="app">
<div v-for="post in posts" ref="container">
<textarea v-model="post.body" rows="1"#focus="resizeTextarea" #keyup="resizeTextarea" ></textarea>
</div>
</div>
and add the following code at the end of mounted() :
this.$nextTick(()=>{
this.$refs.container.forEach( ta => {
ta.firstChild.dispatchEvent(new Event("keyup"));
});
});
I am trying to integrate ckeditor 5 in my vue js app.I have successfully added ckeditor but now i want to add some text at the cursor position in ckeditor on click of a button. So to achieve that i tried insertText method. But i am not able to get the editor instance in vue while adding the code as editor.model.change(...)
Uncaught ReferenceError: editor is not defined
Code =>
<template>
<ckeditor
id="custom"
ref="custom"
name="custom"
:editor="editor"
:config="editorCustomConfig"
v-model="message">
</ckeditor>
Add Text In Editor
</template>
<script>
import ClassicEditor from "#ckeditor/ckeditor5-build-classic";
export default {
name: "topbar",
},
data() {
return {
editor: ClassicEditor,
editorConfig: {
},
message:''
};
},
methods: {
addCodeInMsg(e){
editor.change( writer => {
const insertPosition = editor.model.document.selection.getFirstPosition();
writer.insertText( 'CKEditor 5 rocks!', { linkHref: 'https://ckeditor.com/' }, insertPosition );
} );
}
}
</script>
I don't know what i am missing while using the ckeditor component.Any helps would be appreciated.
I ran into the same issue with Vue3 and CKEditor 5. Here is what I did for anyone that stumbles across this and still needs an answer.
Reference: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/architecture/editing-engine.html#model
Setup the editor:
<ckeditor id="templateEditor" :editor="editor" v-model="myModel.myProperty" #ready="onReady"></ckeditor>
In my case, I have a list of li tags and clicking on each would add some text to the editor.
<li><span class="clickable emailToken" #click="appendToken('{year}')">{year}</span> - current year</li>
Then add this block of code to your component code (I'm using TypeScript and the ClassicEditor - you should be able to replace ClassicEditor with the name of whichever editor you're using):
let editor = {} as ClassicEditor;
function onReady(useEditor: ClassicEditor) {
editor = useEditor;
}
function appendToken(token) {
editor.model.change(writer => {
writer.insertText(token, editor.model.document.selection.getFirstPosition());
});
editor.focus();
}
The ckeditor ready event passes the editor instance to the onReady function and stores that ready instance in editor. The appendToken function then uses that captured editor to make changes to the model.
forgot about this:
methods: {
addCodeInMsg(e){
this.editor.change( writer => {
const insertPosition = this.editor.model.document.selection.getFirstPosition();
writer.insertText( 'CKEditor 5 rocks!', { linkHref: 'https://ckeditor.com/' }, insertPosition );
} );
}
}
I was able to do this through the editor-object you get when the CKeditor is ready.
In the on-ready-event, you get a editor and then I save that one for using such actions.
source: https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs.html#using-the-document-editor-build
This is my code:
<template>
<div>
<div v-html="data"></div> <button v-on:click="replace">Click Me to replace div contents</button>
</div>
</template>
<script>
export default {
data() {
return {
data: "I will be replaced once you click on button"
}
},
methods: {
clickMe() {
alert("worked");
},
replace(){
this.data = "Why does click me not work? It is loaded from server via ajax <a href v-on:click.prevent='clickMe'>Click Me</a>";
}
}
};
</script>
Here if I click on Click Me to replace div contents the content is replaced but the event handler clickMe does not fire. This data would come from server and I need to compile this string and use it from within the Vue's context so Vue can handle events etc.
How can I have the dynamic string downloaded from server work? I am using Vue 2.
Since v-html isn't compiled you will have to create a mini component like this to get around the issue:
new Vue({
el: '#app',
data () {
return {
data: ``
}
},
computed: {
compiledData () {
return {
template: `<p>${this.data}</p>`
}
}
},
methods: {
replace () {
this.data = `Now click on me <a href='#' #click.prevent='alert("yo")'> here </a>`
}
}
})
<script src="https://unpkg.com/vue#2.5.3/dist/vue.min.js"></script>
<div id="app">
<component :is="compiledData" ></component>
<button v-on:click="replace">Click Me to replace div contents</button>
</div>
The above code compiles the string content and thus you can run/execute the function as intended
Other solution using Vue components (codepen):
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div id="someId"></div> <button v-on:click="replace">Click Me to replace div contents</button>
<component :is="currentView"></component>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
currentView: null
},
methods:{
replace: function(){
var templateFromServer = getTemplate();
var comp=Vue.component('template-from-server', {
template: templateFromServer,
methods:{
clickMe:function (){
console.log("click");
}
}
});
this.currentView = comp;
}
}
});
function getTemplate(){
return "<a href v-on:click.prevent='clickMe'>Click Me</a>"
}
</script>
v-html is not compiled as a Vue template. From the docs:
Note that the contents are inserted as plain HTML - they will not be compiled as Vue templates. If you find yourself trying to compose templates using v-html, try to rethink the solution by using components instead.
see: https://v2.vuejs.org/v2/api/#v-html
You can not render VueJS code from a html string.
You can solve this issue by using v-if
<div>
<div v-if="data">I will be replaced once you click on button</div>
<div v-else>Why does click me not work? It is loaded from server via ajax <a href #click.prevent='clickMe'>Click Me</a></div>
<button #click="replace">Click Me to replace div contents</button>
</div>
<script>
export default {
data() {
return {
data: true
}
},
methods: {
clickMe() {
alert("worked");
},
replace(){
this.data = !this.data;
}
}
};
You can call normal javascript function from string but not vuejs function so onclick event would also work.
I am working on a modal component using VueJS 2. Right now, it basically works -- I click on a button and the modal opens, etc.
What I want to do now is create a unique name for the modal and associate the button with that particular button.
This is what I have in mind. The modal has a unique name property:
<modal name='myName'>CONTENT</modal>
And this would be the associate button:
<button #click="showModal('myName')"></button>
What I need to figure out is how to pass the parameter of showModal to the modal component.
Here is the method that I'm using in the root vue instance (i.e, NOT inside my modal component):
methods: {
showModal(name) { this.bus.$emit('showModal'); },
}
What I want to do is to access the name property in the component -- something like this:
created() {
this.bus.$on('showModal', () => alert(this.name));
}
But this shows up as undefined.
So what am I doing wrong? How can I access the name property inside the modal component?
NOTE: If you are wondering what this.bus.$on is, please see the following answer to a previous question that I asked: https://stackoverflow.com/a/42983494/7477670
Pass it as a parameter to $emit.
methods: {
showModal(name) { this.bus.$emit('showModal', name); },
}
created() {
this.bus.$on('showModal', (name) => alert(name));
}
Also, if you want to give the modal a name, you need to accept it as a prop in the modal component.
Vue.component("modal",{
props:["name"],
...
})
Then I assume you will want to do something like,
if (name == this.name)
//show the modal
<!-- File name is dataTable.vue -->
<template>
<div>
<insertForm v-on:emitForm="close"></insertForm>
</div>
</template>
<script>
import InsertForm from "./insertForm";
import Axios from "axios";
export default {
components: {
InsertForm
},
data: () => ({
}),
methods: {
close(res) {
console.log('res = ', res);
}
}
};
</script>
<!-- File name is insertForm.vue -->
<template>
<div>
<v-btn #click.native="sendPrameter">
<v-icon>save</v-icon>
</v-btn>
</div>
</template>
<script>
export default {
data: () => ({
mesage:{
msg:"Saved successfully",
color:'red',
status:1
}
}),
methods: {
sendPrameter: function() {
this.$emit("emitForm", this.mesage);
}
}
};
</script>
https://vuejs.org/v2/guide/components-custom-events.html