How to implement Quill Emojis in vue2editor? - laravel

I tried to add Quill Emojis to editor but I am getting console error as
Uncaught ReferenceError: Quill is not defined
I am using Laravel 5.6 and vue js and definately new to vue and its components so I may sound silly to you but for the past 3 days I am searching on the google for the solution and even contacted author of vue2editor on github here is the link
This is what I have tried so far:
vue2editor.vue
<template>
<div id="app">
<vue-editor v-model="content"></vue-editor>
</div>
</template>
<script>
import { VueEditor, Quill } from 'vue2-editor';
import Emoji from 'quill-emoji/dist/quill-emoji';
Quill.register('modules/quill-emoji', Emoji);
export default {
name: 'vue2editor',
components: { VueEditor },
data() {
return {
content: "<h1>Some initial content</h1>",
editorSettings: {
modules: {
toolbar: {
container: [
[{'size': ['small', false, 'large']}],
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }],
[{ 'font': [] }],
[{ 'align': [] }],
['clean'],
['link', 'image', 'video'],
['emoji'],
],
handlers: {
'emoji': function () {}
},
},
toolbar_emoji: true,
short_name_emoji: true,
textarea_emoji:true,
},
},
text: null,
};
},
};
</script>
I even tried the method mentioned by one of the user on github for Quill-Emoji, here is the link.
I came here with lots of hopes; if anyone here is to help me out, at least tell me what I am missing will be more than a help for me.

Quill.register({
'formats/emoji': Emoji.EmojiBlot,
'modules/short_name_emoji': Emoji.ShortNameEmoji,
'modules/toolbar_emoji': Emoji.ToolbarEmoji,
'modules/textarea_emoji': Emoji.TextAreaEmoji}, true);
you need register the model, add the up code to you code.

Edit:
//1) Add plugin to laravel mix
const mix = require('laravel-mix')
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.ProvidePlugin({
"window.Quill": "quill/dist/quill.js",
Quill: "quill/dist/quill.js"
})
]
};
});
//2 example vue file
<template>
<div class="mt-1">
<vue-editor
ref="editor"
v-model="content"
:editor-toolbar="customToolbar"
:editorOptions="editorSettings"
/>
</div>
</template>
<script>
import { VueEditor, Quill } from "vue2-editor";
import Emoji from "quill-emoji/dist/quill-emoji";
Quill.register("modules/emoji", Emoji);
export default {
components: {
VueEditor,
},
props: {
bubble: Object,
contentCol: {
type: String,
},
},
data() {
return {
edit: false,
content: "<b>Content is here</b>",
customToolbar: [["bold", "italic", "underline"], ["link"], ["emoji"]],
editorSettings: {
modules: {
"emoji-toolbar": true,
"emoji-textarea": true,
"emoji-shortname": true,
},
},
};
},
beforeDestroy() {},
};
</script>
<style src="quill-emoji/dist/quill-emoji.css"/>

Related

load compont in vueJS 3 in laravel 9

i´m trying to do a component in laravel 9 and vueJS 3. And my component have a datatable and for this i´m using vue-good-table-next but i can´t show it in my blade i don´t know that i´m doing wrong.
in my web browser return this:
[Vue warn]: There is already an app instance mounted on the host container.
If you want to mount another app on the same host container, you need to unmount the previous app by calling `app.unmount()` first.
in my webpack.mix.js i have this:
mix.js('resources/js/app.js', 'public/js')
.vue()
.postCss('resources/css/app.css', 'public/css', [
//
]);
in my app.js i have this:
require('./bootstrap');
import { createApp } from "vue";
import datatableFisios from "./components/datatableFisios.vue";
createApp({
components: {
datatableFisios,
},
}).mount("#app");
and my component it´s
<template>
<div>
<vue-good-table :columns="columns" :rows="rows"/>
</div>
</template>
<script>
export default {
name: 'datatableFisios',
mounted(){
console.log(`The initial count is.`)
},
data(){
return {
columns: [
{
label: 'Name',
field: 'name',
},
{
label: 'Age',
field: 'age',
type: 'number',
},
{
label: 'Created On',
field: 'createdAt',
type: 'date',
dateInputFormat: 'yyyy-MM-dd',
dateOutputFormat: 'MMM do yy',
},
{
label: 'Percent',
field: 'score',
type: 'percentage',
},
],
rows: [
{ id:1, name:"John", age: 20, createdAt: '',score: 0.03343 },
{ id:2, name:"Jane", age: 24, createdAt: '2011-10-31', score: 0.03343 },
{ id:3, name:"Susan", age: 16, createdAt: '2011-10-30', score: 0.03343 },
{ id:4, name:"Chris", age: 55, createdAt: '2011-10-11', score: 0.03343 },
{ id:5, name:"Dan", age: 40, createdAt: '2011-10-21', score: 0.03343 },
{ id:6, name:"John", age: 20, createdAt: '2011-10-31', score: 0.03343 },
],
};
},
};
</script>
PD: it´s first time that i´m doing datatables with VUE, if anybody know any library better than this, say me please.
thanks for readme. and soyy for my bad english.
To resolve my problem i had to update vue-js-loader with this command npm update vue-loader with this i can mount my component and to do my datatable with vue-good-table-next

Display Nested data in vuetify

Hi guys new coder here... just need some help.
I want to display a nested data in vue having vuetify
here is my data:
{
"data": [
{
"id": 1,
"customer": {
"id": 88,
"name": "David Zulauf III",
"mobile": "240-545-5366 x7059"
},
"item": "rau",
"qty": "4",
"fit": {
"name": "fourth"
},
"shop": "Metz, Cole and McKenzie"
},
],
}
I am using Laravel as a back end. not sure about the proper term but I used the Laravel resource functionality to somewhat relate my table together that's why I got this nested data.
this is my vue file and I used vuetify data tables to display the above data
<script>
export default {
data () {
return {
search: '',
dialog: false,
edit:false,
items:[],
headers: [
{text: 'customer',align: 'start',sortable: false,value: 'customer',},
{ text: 'item', value: 'item' },
{ text: 'qty', value: 'qty' },
{ text: 'fit', value: 'fit' },
{ text: 'shop', value: 'shop' },
],
}
},
created(){
this.fetchItems();
},
methods: {
fetchItems(){
axios.get('api/item')
.then(res=>{
this.items = res.data.data;
});
}
}
}
</script>
<template>
<v-card>
<v-card-title>
Items
<v-spacer></v-spacer>
<v-btn depressed color="primary" #click="addNew"> ADD</v-btn>
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
</v-card-title>
<v-data-table :headers="headers" :items="items" :search="search"></v-data-table>
</v-card>
</template>
thank you for the help guys.
You could provide a path to that nested properties like :
headers: [
{text: 'name',align: 'start',sortable: false,value: 'customer.name',},
{text: 'mobile',align: 'start',sortable: false,value: 'customer.mobile',},
{ text: 'item', value: 'item' },
{ text: 'qty', value: 'qty' },
{ text: 'fit name', value: 'fit.name' },
{ text: 'shop', value: 'shop' },
],
Also you can completely customise your Datatable using "item" slot and others, you can look through Vuetify documentation for getting more details.
It can be more complicated but helps when you need to get both values in same column or get different nested levels in one column.

Fullcalendar does not display the events

I cannot display the events in the fullcalendar, I am using vue and vuex to develop a laravel nova compoment with a modal window, I already try in some many ways but without success. I hope anyone can help me.
my store is this:
import Vuex from 'vuex';
Nova.booting((Vue, router, store) => {
Vue.component('fullcalendar', require('./components/Tool'))
Vue.use(Vuex);
Nova.store = new Vuex.Store({
state: {
event: [],
events: [],
},
mutations: {
SET_EVENT(state, event) {
state.event = event;
},
ADD_TO_EVENTS(state, event) {
state.events.push(event);
}
},
actions: {
setEvent(context, event) {
context.commit('SET_EVENT', event);
},
addToEvents(context, event) {
context.commit('ADD_TO_EVENTS', event);
},
},
getters: {
event: state => state.event,
events: state => state.events,
},
});
})
my Tool.vue is this
<template>
<div>
event {{ events }}
<FullCalendar ref="fullcalendar" :options="calendarOptions"/>
<modal :show="showModal" #close="showModal = false"></modal>
<button id="show-modal" #click="showModal = true"></button>
</div>
</template>
<script>
import FullCalendar from '#fullcalendar/vue';
import dayGridPlugin from '#fullcalendar/daygrid';
import timeGridPlugin from '#fullcalendar/timegrid';
import listGridPlugin from '#fullcalendar/list';
import interactionPlugin from '#fullcalendar/interaction';
import modal from './Modal.vue';
export default {
props: ['resourceName', 'resourceId', 'panel'],
components: {
modal,
FullCalendar, // make the <FullCalendar> tag available
},
data() {
return {
showModal: false,
calendarOptions: {
plugins: [ dayGridPlugin, timeGridPlugin, listGridPlugin, interactionPlugin ],
initialView: 'dayGridMonth',
events: this.events,
editable: true,
select: this.handleDateClick,
eventClick: this.handleEventClick,
buttonText: {
today: 'Today',
month: 'Month',
week: 'Week',
day: 'Day',
list: 'Agenda'
},
headerToolbar : {
end: 'prevYear,prev today next,nextYear',
center: 'title',
start: 'dayGridMonth,timeGridWeek,timeGridDay listMonth',
},
stickyHeaderDates: true,
aspectRatio: 2.4,
navLinks: true,
selectable: true,
nowIndicator: true,
dayMaxEventRows: true,
dayMaxEvents: 10,
moreLinkClick: 'popover',
businessHours: {
daysOfWeek: [ 1, 2, 3, 4, 5 ], // Monday - Thursday
startTime: '8:00',
endTime: '18:00',
}
}
}
},
mounted() {
this.showModal = false;
},
computed: {
events: () => {
return Nova.store.getters.events;
},
},
methods: {
handleDateClick(arg) {
const event = {
title:'something',
start: moment(arg.start).format('YYYY-MM-DD'),
end: moment(arg.end).format('YYYY-MM-DD'),
allDay: true,
};
Nova.store.dispatch('setEvent', event);
this.showModal = true;
},
handleEventClick(event) {
this.showModal = true;
},
},
}
</script>
my modal window file is this
<template>
<div>
event {{ events }}
<FullCalendar ref="fullcalendar" :options="calendarOptions"/>
<modal :show="showModal" #close="showModal = false"></modal>
<button id="show-modal" #click="showModal = true"></button>
</div>
</template>
<script>
import FullCalendar from '#fullcalendar/vue';
import dayGridPlugin from '#fullcalendar/daygrid';
import timeGridPlugin from '#fullcalendar/timegrid';
import listGridPlugin from '#fullcalendar/list';
import interactionPlugin from '#fullcalendar/interaction';
import modal from './Modal.vue';
export default {
props: ['resourceName', 'resourceId', 'panel'],
components: {
modal,
FullCalendar, // make the <FullCalendar> tag available
},
data() {
return {
showModal: false,
calendarOptions: {
plugins: [ dayGridPlugin, timeGridPlugin, listGridPlugin, interactionPlugin ],
initialView: 'dayGridMonth',
events: this.events,
editable: true,
select: this.handleDateClick,
eventClick: this.handleEventClick,
buttonText: {
today: 'Today',
month: 'Month',
week: 'Week',
day: 'Day',
list: 'Agenda'
},
headerToolbar : {
end: 'prevYear,prev today next,nextYear',
center: 'title',
start: 'dayGridMonth,timeGridWeek,timeGridDay listMonth',
},
stickyHeaderDates: true,
aspectRatio: 2.4,
navLinks: true,
selectable: true,
nowIndicator: true,
dayMaxEventRows: true,
dayMaxEvents: 10,
moreLinkClick: 'popover',
businessHours: {
daysOfWeek: [ 1, 2, 3, 4, 5 ], // Monday - Thursday
startTime: '8:00',
endTime: '18:00',
}
}
}
},
mounted() {
this.showModal = false;
},
computed: {
events: () => {
return Nova.store.getters.events;
},
},
methods: {
handleDateClick(arg) {
const event = {
title:'something',
start: moment(arg.start).format('YYYY-MM-DD'),
end: moment(arg.end).format('YYYY-MM-DD'),
allDay: true,
};
Nova.store.dispatch('setEvent', event);
this.showModal = true;
},
handleEventClick(event) {
this.showModal = true;
},
},
}
</script>
Do you have any clue why I can see the event in the calendar?
I appreciate any help
Thks,
I had the same problem.
I put the calendaroptions in computed
you can check this repository (Vue-vuex)
https://github.com/fullcalendar/fullcalendar-example-projects

Inline Editor - disable editor and display HTML / render content (Vue)

I am using CKEditor5 with Vue. In my Vuex store, I have the following property:
const state = {
EditMode: false,
}
On a button click by a user with permission, I modify the Vuex store. If EditMode: true, I want to display the in-line editor. Else, display the raw HTML editorData (the user is not authorized to edit, or not in edit mode). I do that below:
<template>
<vx-card :title="editorName" v-if="this.$store.state.EditMode">
<ckeditor :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
</vx-card>
<vx-card :title="editorName" v-else>
<div v-html="editorData"></div>
</vx-card>
</template>
<script>
import InlineEditor from '#ckeditor/ckeditor5-build-inline'
export default {
name: "RichTextEditor",
props: {
editorName: {
type: String,
required: true,
},
},
data() {
return {
loaded: false,
time: null,
timeElapsedSinceEdit: 0,
editor: InlineEditor,
editorData: 'New entry!',
editorConfig: {
toolbar: {
items: [
'|',
'heading',
'fontFamily',
'fontSize',
'fontColor',
'bold',
'underline',
'italic',
'alignment',
'link',
'highlight',
'superscript',
'subscript',
'|',
'indent',
'outdent',
'|',
'blockQuote',
'horizontalLine',
'imageUpload',
'insertTable',
'mediaEmbed',
'undo',
'redo'
]
},
language: 'en',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:full',
'imageStyle:side'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'tableCellProperties',
'tableProperties'
]
},
},
}
},
// Below code is situation-specific and not completely relevant
watch: {
editorData: function() {
if (this.loaded) {
this.upsertData()
}
}
},
methods: {
async pollData() {
await
this.$http.get('/api/rte/' + this.editorName)
.then((response) => {
this.editorData = response.data.content
})
.catch((error) => {
if (window.environment == "production") {
location.href = 'pages/error-500/'
} else {
console.log(error.stack)
}
})
this.loaded = true;
},
async upsertData() {
console.log('up')
await
this.$http.post('/api/rte/' + this.editorName + '/upsert', {
data: this.editorData,
})
.then((response) => {
this.$vs.notify({
title: 'Action Completed',
text: response.data.message,
color: 'success',
position: 'top-right'})
})
.catch((error) => {
if (window.environment == "production") {
location.href = 'pages/error-500/'
} else {
console.log(error)
}
})
},
},
created() {
this.pollData();
},
}
</script>
This works, but the in-line styling isn't respected with v-html (sizing and centering). If this.$store.state.EditMode: false, I get the following output:
If this.$store.state.EditMode: true I get this in the in-line editor (as expected).
Raw HTML (editorData property after pollData() is called)
<figure class="image image_resized" style="width:25.51%;"><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTRJO0xRohucbxcjlRoiRaw2cWYTbilYch5NQ&usqp=CAU" alt="Free clipart megaphone announcement public domain vectors - Clipartix"></figure><h2 style="text-align:center;"><span style="color:hsl(30,75%,60%);"><strong>We have a new Intranet!</strong></span></h2><p style="text-align:center;">Summer / Fall Wellness Challenge Link</p>
Research showed that Vue's v-html doesn't respect scoped styling. I'm not entirely sure how that applies to in-line styling. To test output, I replaced my else with the raw HTML and got the same visual output as when I used v-html:
<vx-card :title="editorName" v-else>
<figure class="image image_resized" style="width:25.51%;"><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTRJO0xRohucbxcjlRoiRaw2cWYTbilYch5NQ&usqp=CAU" alt="Free clipart megaphone announcement public domain vectors - Clipartix"></figure><h2 style="text-align:center;"><span style="color:hsl(30,75%,60%);"><strong>We have a new Intranet!</strong></span></h2><p style="text-align:center;">Summer / Fall Wellness Challenge Link</p>
</vx-card>
What is the proper way to disable the inline editor and maintain visual consistency?
<template>
<vx-card :title="editorName" v-if="loaded">
<ckeditor :editor="editor" v-model="editorData" :config="editorConfig" :readonly="editorDisabled" :disabled="editorDisabled" ></ckeditor>
</vx-card>
</template>
//...
watch:{
'$store.state.EditMode'(value, oldValue) {
if(value) {
this.editorDisabled = false;
} else {
this.editorDisabled = true;
}
},
},
//...
Question answered here:
https://github.com/ckeditor/ckeditor5-vue/issues/154

column filter with data types displaying error:using data tables

I have used this code to generate search box for every fields. But it is showing syntax error at the line .columnFilter({. how to solve this problem
<script type="text/javascript" charset="utf-8">
//initialisation code
$(document).ready(function() {
$('#example').dataTable( {
"sPaginationType": "full_numbers",
.columnFilter({
sPlaceHolder: "head:before",
aoColumns: [ {
type: "select",
values: [ 'Gecko', 'Trident', 'KHTML',
'Misc', 'Presto', 'Webkit', 'Tasman']
},
{ type: "text" },
{ type: "number" },
{ type: "date-range" },
{ type: "number-range" }
]
} );
} );
</script>
looks like a javascript syntax problem. Try changing to this:
$(document).ready(function() {
$('#example').dataTable( {
"sPaginationType": "full_numbers"
})
.columnFilter({
sPlaceHolder: "head:before",
aoColumns: [ {
type: "select",
values: [ 'Gecko', 'Trident', 'KHTML',
'Misc', 'Presto', 'Webkit', 'Tasman']
},
{ type: "text" },
{ type: "number" },
{ type: "date-range" },
{ type: "number-range" }
]
} );
} );
$(document).ready(function(){
$('#example').dataTable().columnFilter();
})
make usure you have closed the dataTable() brackets before .columnFilter.
Hope it works.

Resources