How to use href in Vue and Quill - vue.js

I am using the Quill editor in Vue.js and it's working great. I have images, etc.
But...the link isn't working. I tried both the "snow" and "bubble" themes.
I type the text, highlight it and then click on the "link". I get the dialog to set the link, but then the link isn't there.
It's working in the JavaScript version, but not the Vue.
Below is my code.
Vue.component('editor', {
template: '<div ref="editor"></div>',
props: {
value: {
type: String,
default: ''
}
},
data: function() {
return {
editor: null
};
},
mounted: function() {
this.editor = new Quill(this.$refs.editor, {
modules: {
toolbar: [
[{ header: [1, 2, 3, 4, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block', 'link']
]
},
//theme: 'bubble',
theme: 'snow',
formats: ['bold', 'underline', 'header', 'italic', 'link'],
placeholder: "Type something in here!"
});
this.editor.root.innerHTML = this.value;
this.editor.on('text-change', () => this.update());
},
methods: {
update: function() {
this.$emit('input', this.editor.getText() ? this.editor.root.innerHTML : '');
}
}
})
new Vue({
el: '#root',
data: {
//model: 'Testing an editor'
model: '',
isShowing: true
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<link href="https://cdn.quilljs.com/1.3.4/quill.snow.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://cdn.quilljs.com/1.3.4/quill.core.css" rel="stylesheet"/>
<!DOCTYPE html>
<html>
<head>
<title>Trying to use the Quill Editor in Vue</title>
</head>
<body>
<div id="root">
<div v-if="isShowing">
<editor v-model="model"></editor>
</div>
<p>I need the v-html directive: <span v-html="model"></span></p>
<p>Raw data: <pre>{{ model }}</pre></p>
<button #click="isShowing = !isShowing">Toggle</button>
</div>
</script>
</body>
</html>
Any help is greatly appreciated.
Thanks, D

I had to place a 'link' into the "formats" as well:
formats: ['bold', 'underline', 'header', 'italic', 'link'],
I updated my code snippet with the correct answer in case anyone else is having this problem.
Thanks!

Related

How to customize the text on empty cell value using Bootstrap-Vue?

What I want to achieve is put "-" on every empty cell value. Like this (see the "Name" row):
How do I do that? Thanks
You can use add a formatter if you use the fields prop.
Here you can create a method which either returns your name if there is one, or - if there's none.
new Vue({
el: '#app',
data() {
return {
fields: [
{ key: "name", formatter: 'formatName' },
{ key: "age" }
],
items: [
{ age: 40, name: 'Dickerson Macdonald' },
{ age: 21, name: '' },
{ age: 89, name: 'Geneva Wilson' },
{ age: 38, name: 'Jami Carney'}
]
}
},
methods: {
formatName(value) {
return value || '-'
}
}
})
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/vue#2.6.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.js"></script>
<div id="app">
<b-table :items="items" :fields="fields"></b-table>
</div>
Alternatively, you can use slots to create the logic in your template, or maybe render something else if there's no name. But if it's simply displaying a -, I'd stick with a formatter.
new Vue({
el: '#app',
data() {
return {
fields: [
{ key: "name" },
{ key: "age" }
],
items: [
{ age: 40, name: 'Dickerson Macdonald' },
{ age: 21, name: '' },
{ age: 89, name: 'Geneva Wilson' },
{ age: 38, name: 'Jami Carney'}
]
}
}
})
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/vue#2.6.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.js"></script>
<div id="app">
<b-table :items="items" :fields="fields">
<template #cell(name)="{ value }">
{{ value || '-' }}
</template>
</b-table>
</div>

VueJS - Access multiple data within one methods

I'm pretty new in Vue and I'm trying to write down a function that returns true or false on a given data when input modified. I have 4 different data that I need possibly to change the truthiness.
My logic was to produce a function that accepts data as parameter but... It doesn't work. Maybe it's not the proper way to go for...
Here the HTML:
<input type="text" v-model="bannerContent.button" #input="checkMaxChar(48,bannerContent.button.length,isButtonTooLong)" id="banner-button">
And the JS
var app = new Vue({
el: '#app',
data: {
bannerContent: {
title : 'Title',
text: 'Text',
copyright: 'Copyright',
button: 'Button'
},
isButtonTooLong: false,
},
methods: {
checkMaxChar: function(a,b,c) {
var vm = this
if( a < b ) {
vm.c = true;
};
console.log(this.c);
}
}
})
I'm not sure why you are doing var vm = this and also where do you defined c?
for your purpose define c in the data section like code below and work wit your input:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<input
type="text"
v-model="bannerContent.button"
#input="checkMaxChar(48,bannerContent.button.length,isButtonTooLong)"
id="banner-button"
/>
</div>
</body>
<script>
var app = new Vue({
el: "#app",
data: {
bannerContent: {
title: "Title",
text: "Text",
copyright: "Copyright",
button: "Button",
},
isButtonTooLong: false,
c: false,
},
methods: {
checkMaxChar(a, b, c) {
if (a < b) {
this.c = true;
}
console.log(this.c);
},
},
});
</script>
</html>
Hope it helps You ;)

Vue-good-table - One record missing on the first page (pagination)

I'm using vue-good-table Vue's component but there's a problem with pagination. Basically, the first page always shows one record missing. I mean, if I set the 'perPage' option to 10, the first page shows 9 records, while all the others show 10 records. What could it be?
My code:
app.js
require('./bootstrap');
window.Vue = require('vue');
window.axios = require('axios');
Vue.component("my-table", require("./components/MyTable.vue").default);
const app = new Vue({
el: '#app',
});
MyTable.vue
<template>
<div>
<vue-good-table
#on-selected-rows-change="selectionChanged"
#on-select-all="selectAll"
:columns="columns"
:rows="rows"
styleClass="vgt-table striped condensed"
:select-options="{
enabled: true,
selectOnCheckboxOnly: true,
selectionText: 'record selezionati',
clearSelectionText: 'Pulisci',
selectionInfoClass: '',
}"
:search-options="{
enabled: true,
placeholder: 'Cerca',
}"
:sort-options="{
enabled: true,
initialSortBy: {field: 'numero_verbale', type: 'asc'}
}"
:pagination-options="{
enabled: true,
mode: 'records',
perPage: 10,
position: 'top',
perPageDropdown: [5, 10, 20],
dropdownAllowAll: true,
nextLabel: 'Prossima',
prevLabel: 'Precedente',
rowsPerPageLabel: 'Record per pagina',
ofLabel: 'di',
allLabel: 'Tutti',
}"
>
<div slot="selected-row-actions">
<button class="mr-4">Action 1</button>
<button class="mr-4">Action 2</button>
<button >this.routeURL</button>
</div>
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'elimina'">
<button #click="deleteOrdinanza(props.row.id, props.index)" class="bg-grey-200 text-sm"> ELI</button>
</span>
<span v-if="props.column.field == 'dettaglio'">
<button #click="rowId(props.row.id, props.index)" class="bg-grey-200 text-sm"> DETTAGLIO</button>
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
</div>
</template>
<script>
import 'vue-good-table/dist/vue-good-table.css'
import { VueGoodTable } from 'vue-good-table';
axios.defaults.baseURL = 'http://127.0.0.1:8000/api';
export default {
name: 'my-table',
props: {
ordinanze: String,
},
data(){
return {
columns: [
{
label: 'ID',
field: 'id',
type: 'number',
// hidden: true
},
{
label: 'N° Verbale',
field: 'numero_verbale',
type: 'number',
width: '130px'
},
{
label: 'Data Verbale',
field: 'data_verbale',
dateInputFormat: 'yyyy-MM-dd',
dateOutputFormat: 'MMM Do yy',
},
{
label: 'Cognome',
field: 'cognome',
},
{
label: 'Nome',
field: 'nome',
},
{
label: 'Codice Fiscale',
field: 'codice_fiscale',
},
{
label: 'Città',
field: 'citta',
},
{
label: 'Provincia',
field: 'provincia'
},
{
label: 'Data Notifica',
field: 'data_notifica',
dateInputFormat: 'yyyy-MM-dd',
dateOutputFormat: 'MMM Do yy',
},
{
label: '',
field: 'elimina',
sortable: false,
},
{
label: '',
field: 'dettaglio',
sortable: false,
},
],
rows : JSON.parse(this.ordinanze) ,
};
},
methods: {
rowId(idParam) {
console.log(idParam);
},
deleteOrdinanza(id, index){
console.log(id);
console.log(index);
axios.delete('/ordinanze/' + id)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error)
});
this.rows.splice(index,1);
}
},
components: {
VueGoodTable,
},
};
</script>
vuegoodtable.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue comp test </title>
<script src="/js/app.js" defer></script>
</head>
<body>
{{-- table component--}}
{{-- $ordinanze is the array with all the table records--}}
<div id="app" class="-mx-4 sm:-mx-8 px-4 sm:px-8 py-3">
<my-table :ordinanze='#json($ordinanze)'></my-table>
</div>
</body>
</html>
Thanks!
I'm wondering if you are using vue-good-table v2.19.2, because I've seen your problem with that version.
If so, you will not see this problem using 2.19.1 or 2.19.3 (that is the latest version currently).

Use Materializecss Alpha with Vue

Hearing of Materializecss Alpha release I was excited because I was a huge fan of it. But I am confused on how to import it into a typical vue.js app and initializing it plugins
for example, how we implement this in Vue:
var instance = new M.Carousel({
fullWidth: true,
indicators: true
})
Without JQuery and with webpack component
0) I tried to use 1.0.0-alpha.2 with npm (npm install materialize-css#next) but...
1) 1.0.0-alpha.2 has an error so meanwhile I cloned the last repo version directly from github and used with npm as local dependency (this will not be needed as soon as alpha.3 will be released):
2) I generated the webpack template with vue-cli
3) I substituted the HelloWorld component with the following one... where I put the carousel initialization code in the mounted method of the component
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<div class="carousel">
<div v-for="elem in images">
<a class="carousel-item" :href="elem.link"><img :src="elem.img" :alt="elem.link"></a>
</div>
</div>
</div>
</template>
<script>
import M from 'materialize-css'
export default {
name: 'Carousel',
mounted () {
var elem = document.querySelector('.carousel')
// eslint-disable-next-line
var t = new M.Carousel(elem, {
indicators: true
})
},
data () {
return {
msg: 'Welcome to Your Carousel Component',
images: [
{
img: 'http://quintagroup.com/cms/technology/Images/materialize.png',
link: 'https://github.com/Dogfalo/materialize'
},
{
img: 'https://vuejs.org/images/logo.png',
link: 'https://vuejs.org/'
},
{
img: 'https://avatars1.githubusercontent.com/u/9919?s=200&v=4',
link: 'https://github.com'
}
]
}
}
}
</script>
4) I added import 'materialize-css/dist/css/materialize.min.css' to main.js
I think that it could be as simple as that:
(function($){
$(function(){
$('.carousel').carousel({
fullWidth: true,
indicators: true
});
}); // end of document ready
})(jQuery); // end of jQuery name space
new Vue({
el: '#app',
data: {
images: [{
img: "http://quintagroup.com/cms/technology/Images/materialize.png",
link: "#link1"
},
{
img: "http://quintagroup.com/cms/technology/Images/materialize.png",
link: "#link2"
},
{
img: "http://quintagroup.com/cms/technology/Images/materialize.png",
link: "#link3"
},
{
img: "http://quintagroup.com/cms/technology/Images/materialize.png",
link: "#link4"
},
{
img: "http://quintagroup.com/cms/technology/Images/materialize.png",
link: "#link5"
}
]
}
})
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.1/css/materialize.min.css">
<script src="https://unpkg.com/vue"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.1/js/materialize.min.js"></script>
<div id=app>
<div class="carousel">
<div v-for="elem in images">
<a class="carousel-item" :href="elem.link"><img :src="elem.img" :alt="elem.link"></a>
</div>
</div>
</div>

Vue.js: Why won't my data display in this list containing multiple component types?

I am trying to get to a point where I can have multiple component types being rendered within a single parent. It's not something which is easy to search for answers on.
I know that it is differentiating the components by adding something to the templates to distinguish them, but if I pass data as you'll see below, I get nothing, any tips?
Edit: I also don't want to have to render out these components in the HTML for this to work, needs to be passed in via JS.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<component v-for="widget in widgets" :is="widget.type"></component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script>
Vue.config.debug = true
Vue.component('component-a', {
template: '<p>{{foo}}</p>',
props: ['foo',]
});
Vue.component('component-b', {
template: '<p>{{bar}}</p>',
props: ['bar',]
});
new Vue({
el: "#app",
data: {
widgets: [
{
type: "component-a",
foo: 'Hello'
},
{
type: "component-b",
bar: "World",
},
]
}
});
</script>
</body>
</html>
The issue is that you're not passing any props for the foo and bar elements
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<component v-for="widget in widgets" :is="widget.type" :foo="widget.foo" :bar="widget.bar"></component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script>
Vue.config.debug = true
Vue.component('component-a', {
template: '<p>{{foo}}</p>',
props: ['foo',]
});
Vue.component('component-b', {
template: '<p>{{bar}}</p>',
props: ['bar',]
});
new Vue({
el: "#app",
data: {
widgets: [
{
type: "component-a",
foo: 'Hello'
},
{
type: "component-b",
bar: "World",
},
]
}
});
</script>
</body>
</html>
jsFiddle
In your example the components are rendering with empty strings so you're not seeing the values you're trying to pass. when using interchangeable components it's often best to use a common value interface. Something along the lines of:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<component v-for="widget in widgets" :is="widget.type" :value="widget.value"></component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script>
Vue.config.debug = true
Vue.component('component-a', {
template: '<p>{{value.foo}}</p>',
props: ['value',]
});
Vue.component('component-b', {
template: '<p>{{value.bar}}</p>',
props: ['value',]
});
new Vue({
el: "#app",
data: {
widgets: [
{
type: "component-a",
value: {
foo: 'Hello'
}
},
{
type: "component-b",
value: {
bar: "World",
}
},
]
}
});
</script>
</body>
</html>
So that the components only pass the single value object to the component necessary and the component pulls the unique values from that object.