So I have this v-select:
<v-select
v-model="myModel"
label="My Label"
:items="items"
multiple
chips
></v-select>
I would like to add the behavior that clicking on a v-chip removes it from the selected list.
Can anyone help on that? I checked the documentation, but there is not attribute nor events regarding this use case.
Thanks for the help
There is selection slot in v-select https://vuetifyjs.com/en/api/v-select/#slots
const vuetifyOptions = {}
Vue.use(Vuetify)
new Vue({
el: '#app',
vuetify: new Vuetify(vuetifyOptions),
data: () => ({
myModel: [],
items: [
"https://picsum.photos/200/200",
"https://picsum.photos/300/200",
"https://picsum.photos/250/200"
],
}),
methods: {
deleteItem(item) {
this.myModel = this.myModel.filter(find => find !== item);
}
},
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet"/>
<div id="app">
<v-app>
<v-select
v-model="myModel"
label="My Label"
:items="items"
multiple
chips
>
<template #selection="selection">
<v-chip #click="deleteItem(selection.item)" v-text="selection.item"></v-chip>
</template>
</v-select>
</v-app>
</div>
Related
I use standard v-list component of vuetifyjs. For create menu and show list of items.
But if I click second time the active element is hide. And I don't see active element of menu. It is bad for my menu. Link for example v-list
If use pug template below
v-list(dense)
v-list-item-group(color="success" v-model="selectedItem")
v-list-item(v-for="(gallery, key) in galleries" :key="key")
v-list-item-content
v-list-item-title(v-text="gallery")
I have solution. It needs watch variable and set force index by key of clicked item. If we have 'undefined' set force data method
Run examle solution Solution
Code below:
<template>
<div id="app">
<v-app id="inspire">
<v-card max-width="300" >
<v-list dense>
<v-list-item-group
v-model="selectedItem"
color="primary"
>
<v-list-item
v-for="(item, i) in items"
:key="i"
>
<v-list-item-content #click="setItem(i)">
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
</template>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
index: 0,
selectedItem: 0,
items: [
{ text: 'Real-Time'},
{ text: 'Audience' },
{ text: 'Conversions'},
],
}),
watch: {
selectedItem() {
if (typeof this.selectedItem === 'undefined') {
setTimeout(() => {
this.selectedItem = this.index;
}, 500);
}
},
},
methods: {
setItem(index) {
this.index = index;
},
},
})
Another solution would be to disable the v-list-item that has the same index as the selectedItem
<template>
<div id="app">
<v-app id="inspire">
<v-card max-width="300" >
<v-list dense>
<v-list-item-group
v-model="selectedItem"
color="primary"
>
<v-list-item
v-for="(item, i) in items"
:key="i"
:disabled="i == selectedItem"
>
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
</template>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
selectedItem: 0,
items: [
{ text: 'Real-Time'},
{ text: 'Audience' },
{ text: 'Conversions'},
],
}),
})
I using a Vuetify.js for my project
when I used v-dialog component I got a problem that closing the v-dialog and open again.
here is my code.
<div #click="dialog=true">click here</div>
<v-dialog v-model="dialog">
<alert-popup />
</v-dialog>
data() {
return {
dialog : false
}
this is work when I open dialog first time but when I open again only can see the opacity black page
I don`t know which part is wrong. please reply this question. thanks
You didn't provide any code to reproduce the behavior. But I guess the you need provide <v-card> component inside the dialog component. If you don't provide that it just shows the opacity issue.Putting a v-card will eliminate the opacity issue.
<div id="app">
<v-app id="inspire">
<v-container>
<v-row justify="start">
<v-btn #click="openDialog">Open</v-btn>
<v-dialog v-model="dialog" max-width="300px">
<v-card>
<v-card-title>My Dialog</v-card-title>
<v-divider></v-divider>
<v-card-text>
This is text for dialog
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn x-small color="blue darken-1" text #click="dialog = false">Close</v-btn>
<v-btn x-small color="blue darken-1" text #click="dialog = false">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</v-container>
</v-app>
</div>
Here is the working code where there is a v-card component inside v-dialog.
I also see that you've used a custom component called alert-popup inside the v-dialog.If that is the case it needs to be refactored a bit to achieve what you're looking for.
Creating a separate component which you are already doing except <v-dialog>.
Emitting a close event from <alert-popup> component so that open/close and clicking open won't cause issue.
HTML:
<div id="app">
<v-app id="inspire">
<v-container>
<v-row justify="start">
<v-btn #click="openDialog">Open</v-btn>
<alert-popup :dialog="dialog" #close="closeMyDialog" />
</v-row>
</v-container>
</v-app>
</div>
Javascript:
let AlertPopup = Vue.component("AlertPopup", {
props: {
dialog: {
type: Boolean,
default: false
}
},
data: () => ({
open: false
}),
methods: {
close() {
this.open = false;
this.$emit("close");
}
},
watch: {
dialog(value) {
this.open = value;
}
},
created() {
this.open = this.dialog;
},
template: `
<v-dialog v-model="open" max-width="300px">
<v-card>
<v-card-title>My Dialog</v-card-title>
<v-divider></v-divider>
<v-card-text>
This is text for dialog
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn x-small color="blue darken-1" text #click="close">Close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
`
});
new Vue({
el: "#app",
vuetify: new Vuetify(),
components: {
AlertPopup
},
data: (vm) => ({
dialog: false
}),
computed: {},
methods: {
closeMyDialog() {
this.dialog = false;
},
openDialog() {
this.dialog = true;
}
}
});
If look at the AlertPopup component, it just take a prop named dialog and that we can pass from the main component, when button is clicked, it sets to true, which triggers the AlertPopup component.
NOTE:
If we don't emit the close event from the AlertPopup component, then the modal dialog will not open on the second time onwards. The reason for this behavior is the fact that, when the button is clicked from the parent component,which set the dialog to true and pass it to the AlertPopup and whatever things happens inside the AlertPopup remains inside that component and dialog property of parent component never changes.
Here is a working example of how the modal component are triggered from parent component. If we remove the close event, it will not open the modal second time.
Update: It turns out we are unnecessary complicating things, we don't
even need to emit an event, we can pass in the close function as a
prop and react to that, whenever the close button is clicked, it would
call the closeAlert().
Thanks to #Pratik149 for pointing out the bug, I have attached the click outside event handler.
Here is the completely re-factored code.
<div id="app">
<v-app id="inspire">
<v-container>
<v-row justify="start">
<v-btn #click="openDialog">Open</v-btn>
<alert-popup :dialog="dialog" #close="closeMyDialog" :close="closeMyDialog" />
</v-row>
</v-container>
</v-app>
</div>
And the component logic is updated as follow
let AlertPopup = Vue.component("AlertPopup", {
props: {
dialog: {
type: Boolean,
default: false
},
close: {
type: Function,
default: () => {}
}
},
data: () => ({
open: false
}),
methods: {
closeAlert() {
this.close();
}
},
template: `
<v-dialog v-model="dialog" max-width="300px" #click:outside="closeAlert">
<v-card>
<v-card-title>My Dialog</v-card-title>
<v-divider></v-divider>
<v-card-text>
This is text for dialog
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn x-small color="blue darken-1" text #click="closeAlert">Close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
`
});
new Vue({
el: "#app",
vuetify: new Vuetify(),
components: {
AlertPopup
},
data: (vm) => ({
dialog: false
}),
computed: {},
methods: {
closeMyDialog() {
debugger;
this.dialog = false;
},
openDialog() {
this.dialog = true;
}
}
});
Finally here is the updated codepen
I need to make right aligned v-menu with "attach" option.
Template:
<div id="app">
<v-app id="inspire">
<h1>VMenu bug with "right" option</h1>
<div class="place"></div>
<div class="text-center">
<v-btn
color="primary"
dark
#click="show = !show"
>
Dropdown
</v-btn>
</div>
<v-menu attach=".place" v-model="show" :right="true">
<v-list>
<v-list-item
v-for="(item, index) in items"
:key="index"
#click=""
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-app>
</div>
JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
show: false,
items: [
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me 2' },
],
}),
})
I expect right aligned menu in ".place" element. But the menu is left aligned. Also top border of menu is under the ".place" element. It is strange. How can I fix it?
Demo
It is possible to align the content of v-menu to right border of the page
Here is the working codepen: https://codepen.io/chansv/pen/OJyjWmX
<div id="app">
<v-app id="inspire">
<h1>VMenu bug with "right" option</h1>
<div>
<div id="attachMenu" style="float: right;position: relative;width: 134px;left: 27px;"></div>
</div>
<div class="text-center">
<v-btn
color="primary"
dark
#click="show = !show"
>
Dropdown
</v-btn>
</div>
<v-menu attach="#attachMenu" v-model="show" :right="true">
<v-list>
<v-list-item
v-for="(item, index) in items"
:key="index"
#click=""
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
show: false,
items: [
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me 2' },
],
}),
})
You almost got the right solution, the position with the right and left prop is inverted
So this is what you need to do:
<v-menu attach=".place" v-model="show" left>
I am using Vuetify 3 and I had the same problem. I solved it by using
<v-menu location="bottom end">
See :
https://next.vuetifyjs.com/en/components/menus/#location
https://next.vuetifyjs.com/en/components/overlays/#location-strategies
I have input data from v-textarea with enter key and the result like
Hello\nWorld
Rendering this in v-data-table with default or rawHtml not working
<v-data-table
:headers="headers"
:items="dataTable"
hide-default-footer>
<template v-slot:item="props">
<tr>
<td><span v-html="props.item.s"></span></td> <!-- rawHtml -->
<td>{{ props.item.s }}</td> <!-- default-->
</tr>
</template>
</v-data-table>
Vuetify uses browser conventions to render tables,
To render a line break inside a <td>, the suggestion is to either use a pre tag or the CSS style td { white-space:pre }
See answers to this post.
I included the CSS inline using a template within the v-data-table
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: 'ID',
align: 'start',
sortable: false,
value: 'name'
},
{
text: 'Description',
align: 'start',
sortable: false,
value: 'description'
}
],
items: [
{
name: "001",
description: `First line of content.
Second line of content.
Third line of content (with left tab).`
},
{
name: "002",
description: `First line of content.
Second line of content.
Third line of content (with left tab).`
},
]
}
},
})
<!-- begin snippet: js hide: false console: true babel: false -->
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
<div id="app">
<v-app id="other">
<v-data-table :headers="headers" :items="items" item-key="name" class="elevation-1">
<template v-slot:item.description="{ item }">
<div style="white-space: pre-wrap;">{{ item.description }}</div>
</template>
</v-data-table>
</v-app>
</div>
I am trying to use Vue Multiselect V2 in my Laravel 5.3 project. I am using this example, http://monterail.github.io/vue-multiselect/#sub-single-select
I have the following setup, in my app.js file:
Vue.component('multiselect', require('./components/Multiselect.vue'));
var vm = new Vue({
el: '#app'
});
In the Multiselect.vue file
<script>
import Multiselect from 'vue-multiselect'
export default {
components: {
Multiselect
},
data () {
return {
value: '',
options: ['Select option', 'options', 'selected', 'mulitple', 'label', 'searchable', 'clearOnSelect', 'hideSelected', 'maxHeight', 'allowEmpty', 'showLabels', 'onChange', 'touched']
}
}
}
</script>
And I am calling it in the blade as below:
<div id="app">
<label class="typo__label">Single select</label>
<multiselect v-model="value" :options="options" :searchable="false" :close-on-select="false" :show-labels="false" placeholder="Pick a value"></multiselect>
<pre class="language-json"><code>#{{ value }}</code></pre>
</div>
This is how it displays in the DOM
<div id="app">
<label class="typo__label">Single select</label>
<!---->
<pre class="language-json"><code></code></pre>
</div>
Currently the dropdown does not display, and I don't see any errors in the console. I would have expected to add a template in somewhere but I couldn't find any mention of that in the Vue Multiselect docs.
For anyone having these issues, do not follow the examples on the official documentation. They do not work, rather use this from their Github page. https://github.com/monterail/vue-multiselect/tree/2.0#install--basic-usage
Basic example
<template>
<div>
<multiselect
v-model="selected"
:options="options">
</multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data () {
return {
selected: null,
options: ['list', 'of', 'options']
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
For updating the array from vue multiselect use #select and #remove events
Example: <multiselect #select="selectionChange" #remove="removeElement"> </multiselect>
Into methods add the next functions
methods: {
removeElement() {
this.$forceUpdate();
},
selectionChange() {
this.$forceUpdate();
},
}
this.$forceUpdate(); will update the state.