When using Vuetify v-select
ponent and using the prop multiple
we can multi select values.
In my example I have several recipes with a parameter type
of Breakfast or Dinner.
I want to disable all options for type Breakfast if the user chooses any Dinner recipes, same the other way around.
Here is my codepen if anyone wants to have a go at this:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
selected: [],
recipes: [
{
'id': 1,
'name': 'Pizza',
'type': 'Dinner',
'disabled': false
},
{
'id': 2,
'name': 'Omelet',
'type': 'Breakfast',
'disabled': false
},
{
'id': 3,
'name': 'Scrambled Eggs',
'type': 'Breakfast',
'disabled': false
},
],
}
}
})
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-row align="center">
<v-col cols="12" sm="4">
<v-subheader v-text="'You can only select one type'"></v-subheader>
</v-col>
<v-col cols="12" sm="2">
<v-select
v-model="selected"
:items="recipes"
label="Select"
multiple
hint="Pick your meal"
persistent-hint
item-value="id"
item-text="name"
></v-select>
</v-col>
</v-row>
Selected: {{ selected }}<br>
Recipes: {{ recipes }}
</v-container>
</v-app>
</div>
When using Vuetify v-select
ponent and using the prop multiple
we can multi select values.
In my example I have several recipes with a parameter type
of Breakfast or Dinner.
I want to disable all options for type Breakfast if the user chooses any Dinner recipes, same the other way around.
Here is my codepen if anyone wants to have a go at this: https://codepen.io/5less/pen/eYmaazj
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
selected: [],
recipes: [
{
'id': 1,
'name': 'Pizza',
'type': 'Dinner',
'disabled': false
},
{
'id': 2,
'name': 'Omelet',
'type': 'Breakfast',
'disabled': false
},
{
'id': 3,
'name': 'Scrambled Eggs',
'type': 'Breakfast',
'disabled': false
},
],
}
}
})
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-row align="center">
<v-col cols="12" sm="4">
<v-subheader v-text="'You can only select one type'"></v-subheader>
</v-col>
<v-col cols="12" sm="2">
<v-select
v-model="selected"
:items="recipes"
label="Select"
multiple
hint="Pick your meal"
persistent-hint
item-value="id"
item-text="name"
></v-select>
</v-col>
</v-row>
Selected: {{ selected }}<br>
Recipes: {{ recipes }}
</v-container>
</v-app>
</div>
Share
edited Jan 30, 2020 at 10:10
adiga
35.3k9 gold badges65 silver badges87 bronze badges
asked Jan 30, 2020 at 9:57
5less5less
9701 gold badge10 silver badges18 bronze badges
1
- Please add all the relevant code to the question to create a minimal reproducible example. If the external link is deleted or modified, the question will have no future value. – adiga Commented Jan 30, 2020 at 10:09
3 Answers
Reset to default 4No need for events or watchers
Vuetify v-select
offers the item-disabled
prop, which accepts a function that should return true
if the item should be disabled and false
otherwise.
<template>
<v-select
v-model="selected"
:item-disabled="disableItem"
:items="items"
multiple
/>
</template>
<script>
export default {
data () {
return {
selected: ['name'],
items: [
{
text: 'Nome de A à Z',
value: 'name'
},
{
text: 'Nome de Z à A',
value: '-name'
},
{
text: 'Mais recente à mais antiga',
value: '-updated_at'
},
{
text: 'Mais antiga à mais recente',
value: 'updated_at'
}
]
}
},
methods: {
disableItem (item) {
let invertedValue
if (item.value.match(/^-/)) {
invertedValue = item.value.replace(/^(-)/, '')
} else {
invertedValue = '-' + item.value
}
return this.selected.includes(invertedValue)
}
}
}
</script>
Option 1 - change
event handler
Add change
event handler for v-select
. Like this:
<v-select
@change="onSelect"
v-model="selected"
:items="recipes"
label="Select"
multiple
hint="Pick your meal"
persistent-hint
item-value="id"
item-text="name"
></v-select>
Then in this handler disable all items that have different type:
methods: {
onSelect(e) {
if (e.length == 0) {
this.recipes.forEach((item) => item.disabled = false)
} else {
let chosen = this.recipes.filter((item) => item.id==e[0])
this.recipes.forEach((item) => {
if (item.type != chosen[0].type) {
item.disabled = true
}
})
}
}
}
Option 2 - watcher
Another way is just to add watcher for selected
:
watch: {
selected: function (e) {
if (e.length == 0) {
this.recipes.forEach((item) => item.disabled = false)
} else {
let chosen = this.recipes.filter((item) => item.id==e[0])
this.recipes.forEach((item) => {
if (item.type != chosen[0].type) {
item.disabled = true
}
})
}
}
},
Using a watcher on selected array we can check if the selected recipes is of the same type:
watch: {
selected: function() {
for (const i in this.recipes) {
if (this.selected.length && this.recipes[i].type != this.recipes[this.recipes.findIndex(x => x.id === this.selected[0])].type) {
this.recipes[i].disabled = true;
} else {
this.recipes[i].disabled = false;
}
}
}
}