Search code examples
vuejs2vuetify.jsdisableselect-options

How can I disable literal values in Vuetify?


I am having problems when using the "item-disabled" prop on the v-select component from vuetify. I am trying to use this with literal options.

Here is the snippet which reproduces the issue:

In this example I would like to disable the option "Buzz".

Vue.use(Vuetify)

new Vue({
  el: '#app',
  data: () => ({
    items: ['Foo', 'Bar', 'Fizz', 'Buzz'],
    disabledItems: ['Buzz'],
  })
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.js"></script>

<div id="app">
  <v-app id="inspire">
    <v-container fluid grid-list-xl>
      <v-layout wrap align-center>
        <v-flex xs12 sm6 d-flex>
          <v-select :items="items" :item-disabled="disabledItems" box label="Box style"></v-select>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</div>

<v-select :items="items" :item-disabled="disabledItems"></v-select>
...
items: ['Foo', 'Bar', 'Fizz', 'Buzz'],
disabledItems: ['Buzz'],

I do realize that I could use the non-literal key-value pair like in this example: https://codepen.io/anon/pen/joyoaj and it would work. But I would prefer to not have to write a wrapper component to convert literal options to key-value just to work around this.

<v-select :items="items"></v-select>
...
items: [
  {text: 'Foo', value: 'Foo'}, 
  {text: 'Bar', value: 'Bar'}, 
  {text: 'Fizz', value: 'Fizz'}, 
  {text: 'Buzz', value: 'Buzz', disabled: true},
],

Does anyone know how to get disabling literal values working?


Solution

  • You cant do it like that because item-disabled property is actually for something else.

    From docs:

    item-disabled
    Default: disabled
    Type: string | array | function

    Set property of items's disabled value

    So item-disabled just specifies which field on the objects will be treated as "disabled-field". By default, that field is disabled.

    Without item-disabled you would have objects like this:

    items: [
      {text: 'Foo', value: 'Foo'}, 
      {text: 'Buzz', value: 'Buzz', disabled: true},
    ],
    

    And if objects have some other "disabled-property" (e.g. customDisabled) then use item-disabled prop like this:

     <v-select :items="items" item-disabled="customDisabled"
    
    // ...
    items: [
      {text: 'Foo', value: 'Foo'}, 
      {text: 'Buzz', value: 'Buzz', customDisabled: true},
    ],
    

    Codepen

    If you need to preserve your arrays of strings then you could just map items to the array of objects and pass it:

    <v-select :items="computedItems"
    // ...
    data: () => ({
      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],
      disabledItems: ['Buzz'],
    }), 
    computed: {
      computedItems() {
        return this.items.map(item => {
          return {
            text: item, 
            disabled: this.disabledItems.includes(item)
          }
        })
      }
    }
    

    Codepen


    Additionally, you can pass array to reach desired depth if your disabled field is nested, for example:

    :item-disabled="['meta', 'disabled']"
    // ...
    {
      text: item, 
      meta: {
        disabled: true 
      }
    }