Skip to content

Instantly share code, notes, and snippets.

@matinfo
Last active July 20, 2018 13:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matinfo/52214f7f34ce6b746b483f0f92e6b5e5 to your computer and use it in GitHub Desktop.
Save matinfo/52214f7f34ce6b746b483f0f92e6b5e5 to your computer and use it in GitHub Desktop.
RedactorEditor.vue
import Vue from 'vue'
import VeeValidate from 'vee-validate'
...
import RedactorEditor from './components/RedactorEditor.vue'
Vue.use(VeeValidate)
// Custom validator for RedactorEditor
VeeValidate.Validator.extend('required_editor', {
getMessage: field => `The ${field} field is required.`,
validate: (value) => {
if (value === undefined || value === null) {
return false;
}
return !! String(value).replace('<p></p>', '').replace('<p><br></p>', '').trim().length
}
});
// app
const app = new Vue({
el: '#my-app',
data: {
editorButtons: ['undo', 'redo', 'bold', 'italic', 'lists', 'link'],
editorPlugins: [],
beyondgrammarSettings: {}
editorHTMLContent: '',
},
components: {
RedactorEditor
}
}
...
<redactor-editor
v-model="editorHTMLContent"
:text-value="editorHTMLContent"
:id="'editor_1"
:name="'editor_1"
v-validate="'required_editor'"
:data-vv-as="Editor 1"
:plugins="editorPlugins"
:buttons="editorButtons"
:class="{'has-error': errors.has('editor_1')}"
></redactor-editor>
...
<template>
<div class="redactor">
<textarea ref="redactorContainer" :id="id" :value="value"></textarea>
</div>
</template>
<script>
import 'addons/redactor/css/redactor.css'
import 'addons/redactor/redactor'
//import 'addons/redactor/plugins/wordslimiter/wordslimiter'
//import 'addons/redactor/plugins/beyondgrammar/beyondgrammar'
export default {
name: 'redactor-editor',
props: {
value: {
required: true,
twoWay: true
},
id: {
type: String,
default: 'editor'
},
minHeight: {
type: String,
default: '300px',
},
maxHeight: {
type: String,
default: '800px',
},
buttons: {
type: Array,
default: () => ['html', 'format', 'bold', 'italic', 'deleted', 'lists', 'link']
},
plugins: {
type: Array,
default: () => []
},
wordslimiter: {
type: Number,
default: 0
},
beyondgrammarSettings: {
type: Object,
default: null
}
},
data () {
return {
propValue: this.value
}
},
created () {
this.isChanging = false;
this.app = null;
},
mounted () {
var me = this;
this.app = $R(this.$refs.redactorContainer, {
style: true,
breakline: false,
shortcodes: false,
pasteClean: true,
autoparseImages: false,
autoparseVideo: false,
multipleUpload: false,
clipboardUpload: false,
pasteLinkTarget: '_blank',
placeholder: 'Write your biography here ...',
minHeight: this.minHeight,
maxHeight: this.maxHeight,
buttons: this.buttons,
plugins: this.plugins,
wordslimiter: this.wordslimiter,
beyondgrammar: this.beyondgrammarSettings,
callbacks: {
start: function() {
// set initial data
this.source.setCode(me.propValue);
},
blur: function (e) {
// keyup not work with last typed text, fix sync with v-model by using blur
if (!me.isChanging) {
me.isChanging = true;
var code = this.source.getCode()
me.propValue = (code === null || code.length === 0 ? null : code);
me.$emit('input', me.propValue);
me.$nextTick(function() {
me.isChanging = false;
});
}
}
}
})
},
destroyed () {
this.app = $R(this.$refs.redactorContainer)
if (this.app) {
this.app.destroy()
}
}
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment