i copy example from https://next.vuetifyjs.com/en/components/selects/ , but it dosnt work
enter image description here
<v-select
v-model="select"
:items="items"
item-text="state"
item-value="abbr"
return-object
single-line
></v-select>
data() {
return {
select: {state: 'Florida', abbr: 'FL'},
items: [
{state: 'Florida', abbr: 'FL'},
{state: 'Georgia', abbr: 'GA'},
{state: 'Nebraska', abbr: 'NE'},
{state: 'California', abbr: 'CA'},
{state: 'New York', abbr: 'NY'},
],
}
}
package json:
"vuetify": "^3.0.0-beta.3",
if i click on dropdown element i get error:
Uncaught (in promise) TypeError: Cannot read properties of undefined
(reading '__asyncLoader')
at isAsyncWrapper (runtime-core.esm-bundler.js?d2dd:2246:1)
at unmount (runtime-core.esm-bundler.js?d2dd:6034:1)
at unmountChildren (runtime-core.esm-bundler.js?d2dd:6185:1)
at unmount (runtime-core.esm-bundler.js?d2dd:6065:1)
at unmountComponent (runtime-core.esm-bundler.js?d2dd:6156:1)
at unmount (runtime-core.esm-bundler.js?d2dd:6041:1)
at unmountChildren (runtime-core.esm-bundler.js?d2dd:6185:1)
at unmount (runtime-core.esm-bundler.js?d2dd:6065:1)
at unmountComponent (runtime-core.esm-bundler.js?d2dd:6156:1)
at unmount (runtime-core.esm-bundler.js?d2dd
:6041:1)
Related
So I have the following:
projects: {id: number, name: string, customer: string} =
[
{id:0,name:'foo',customer:'bar'},
{id:1,name:'foo2',customer:'bar2'}
]
I'm trying to build a v-select that uses the customer and name of the project as it's item-title.
By the documentation one would expect to be able to concatenate the attributes or put them in an array. That however isn't the case.
https://next.vuetifyjs.com/en/api/v-select/#props-item-title
The following works:
<v-select
:items="projects"
item-title="name"
return-object
label="Select project"
>
<!-- or -->
<v-select
:items="projects"
item-title=""
return-object
label="Select project"
>
But trying to pass multiple things into the array or concatenating the string will not work:
<v-select
:items="projects"
item-title="[name,customer]"
return-object
>
<!-- or -->
<v-select
:items="projects"
item-title="customer+name"
return-object
>
Clicking the empty selects works but I want to display customer + "/" + name in the title
Illustration of empty v-select
I also tried to achieve this with default approach but it was not working for me as well. You can achieve this by a workaround for now.
In onMounted() lifecycle hook, Manipulate the input array and add a new property in each object which will contain the concatenated value.
data () {
return {
items: [
{ state: 'Florida', abbr: 'FL' },
{ state: 'Georgia', abbr: 'GA' },
{ state: 'Nebraska', abbr: 'NE' },
{ state: 'California', abbr: 'CA' },
{ state: 'New York', abbr: 'NY' },
],
}
}
onMounted() {
this.items = this.items.map(obj => obj.title = obj.state + ' - ' + obj.abbr)
}
In HTML Template :
item-title="title"
As the title indicates I want to display a different collection without having to duplicate it
for example :
const items: IRoute[] = [{
id: 1,
name: 'Administrateur',
children: [
{
id: 2,
name: 'Catalogue',
routeName: RouteName.CATALOGUE
},
{
id: 5,
name: 'Catalogue',
routeName: RouteName.CATALOGUE
}]
const itemWithoutAdmin: IRoute[] = [{
id: 5,
name: 'Catalogue',
routeName: RouteName.CATALOGUE
}]
I make the verification on the role and according to the role I display the admin part otherwise I display only the catalog,
in the template for now I have :
<v-navigation-drawer
app
permanent
>
<v-treeview
v-if="role === 'Admin'
:items="items"
activatable>
</v-treeview>
<v-treeview
v-else
:items="items"
activatable />
</v-navigation-drawer>
Thank you for your help
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?
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
}
}
Real working minimal example with function checking per item.
<v-select
:items="items"
item-text="name"
item-value="id"
:item-disabled="checkIsItemDisabled"
/>
<script>
data: function(){
return {
items: [
{id: 1, name: 'Foo'},
{id: 2, name: 'Bar'},
],
},
methods: {
checkIsItemDisabled(item) {
return (item.id === 1)
},
}
},
</script>
Adding the function option to #Traxo's answer:
<v-select :items="items" item-disabled="disableItem">
...
methods: {
disableItem(item) {
if (item.prop === this.anyOtherPropValue) {
return true;
}
return false;
},
},
Yes is reactive in case this.anyOtherPropValue change
Im new in Vue and Vuetify. I use vuetify data table in my project. Everything working fine except the Search options. I use everything as the documentation. But still not get any solution.
As the basic requirements I use these code to adding search
Template
<v-text-field
v-model="search"
append-icon="search"
label="Search"
single-line
hide-details
></v-text-field>
<v-data-table
:headers="headers"
:items="sales"
:search="search"
:rows-per-page-items="rowsPerPageItems"
row
wrap
class="elevation-1"
>
Script
data(){
return{
search: '',
}
}
Here is the complete code
https://github.com/Shakilzaman87/pukucrm/blob/master/src/components/sales/Sales.vue
Vuetify should warn you in the console about this:
[Vuetify] Headers must have a value property that corresponds to a
value in the v-model array in "v-data-table"
So you can fix the search option by adding values:
headers: [
{ text: 'Item Name', value: 'item_name' },
{ text: 'Unit Price', value: 'price' },
{ text: 'Quantity', value: 'quantity' },
{ text: 'Customer', value: 'customer' },
{ text: 'Created', value: 'timestamp' },
{ text: 'Total', value: 'total' },
{ text: 'Action', value: 'item_name' }
]
(data from your repo)
As of date of posting, I cannot find any documentation to use the "custom filter" prop in data tables.
I just want to create a custom filter to filter my data table by headers.
I have a dropdown, and when user click on one of the options for the dropdown, it will filter the list for one specific header.
Example:
Dropdown options:
Food type: fruit, meat, vegetable
Bakchoi (vegetable)
Pork (meat)
Chicken Thigh (meat)
watermelon (fruit)
If I select dropdown as meat, it should only show me pork and chicken thigh.
Looking at the code on Github1, it looks like the customFilter prop is used to overwrite the default method used to determine how the filter prop is applied to the items in the table.
The default customFilter method applies the filter function to each property name of each item object and filters out any items that don't include one property name that passes the filter:
customFilter: {
type: Function,
default: (items, search, filter) => {
search = search.toString().toLowerCase()
return items.filter(i => (
Object.keys(i).some(j => filter(i[j], search))
))
}
},
You might want to overwrite this function if you wanted to prevent any columns from being included in the filter or if there were specific rows that you always wanted to prevent from being filtered out.
You'll notice that the method also depends on the search prop, which must be a string.
All that said, you really don't need to use that prop for what you want to do. You should just make a computed property to filter the items based on your dropdown value and pass that computed property as the items prop.
Here's an example:
new Vue({
el: '#app',
data() {
return {
food: [
{ name: 'Bakchoi', type: 'vegetable', calories: 100 },
{ name: 'Pork', type: 'meat', calories: 200 },
{ name: 'Chicken Thigh', type: 'meat', calories: 300 },
{ name: 'Watermelon', type: 'fruit', calories: 10 },
],
headers: [
{ text: 'Name', align: 'left', value: 'name' },
{ text: 'Food Type', align: 'left', value: 'type' },
{ text: 'Calories', align: 'left', value: 'calories' },
],
foodType: null,
};
},
computed: {
filteredItems() {
return this.food.filter((i) => {
return !this.foodType || (i.type === this.foodType);
})
}
}
})
<script src="https://unpkg.com/vue#2.4.2/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#0.15.2/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#0.15.2/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">
<div id="app">
<v-app>
<v-select
label="Food Type"
:items="['vegetable', 'meat', 'fruit']"
v-model="foodType"
></v-select>
<v-data-table
:headers="headers"
:items="filteredItems"
hide-actions
>
<template slot="items" scope="{ item }">
<td>{{ item.name }}</td>
<td>{{ item.type }}</td>
<td>{{ item.calories }}</td>
</template>
</v-data-table>
</v-app>
</div>
This answer was written when Vuetify was at v0.15.2. The source code for the VDataTable component at that version can be found here.
You can also go the customFilter approach like this, I've restricted the search to the type field.
new Vue({
el: '#app',
data() {
return {
food: [
{ name: 'Bakchoi', type: 'vegetable', calories: 100 },
{ name: 'Pork', type: 'meat', calories: 200 },
{ name: 'Chicken Thigh', type: 'meat', calories: 300 },
{ name: 'Watermelon', type: 'fruit', calories: 10 },
],
headers: [
{ text: 'Name', align: 'left', value: 'name' },
{ text: 'Food Type', align: 'left', value: 'type' },
{ text: 'Calories', align: 'left', value: 'calories' },
],
search: '',
};
},
methods: {
customFilter(items, search, filter) {
search = search.toString().toLowerCase()
return items.filter(row => filter(row["type"], search));
}
}
})
<script src="https://unpkg.com/vue#2.4.2/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#0.15.2/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#0.15.2/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">
<div id="app">
<v-app>
<v-select
label="Food Type"
:items="['vegetable', 'meat', 'fruit']"
v-model="search"
></v-select>
<v-data-table
:headers="headers"
:items="food"
:search="search"
:custom-filter="customFilter"
hide-actions
>
<template slot="items" scope="{ item }">
<td>{{ item.name }}</td>
<td>{{ item.type }}</td>
<td>{{ item.calories }}</td>
</template>
</v-data-table>
</v-app>
</div>
In my case I have 2 different way of filtering which are search bar and drop down. I tried to use custom-filter for both of them, but it doesn't work, so I came up with another approach
<v-text-field v-model="search" label="Label"></v-text-field>
<v-select
v-model="select"
:items="food"
item-text="type"
item-value="type"
:label="Types"
#change="filterFoodUsingDropDown"
>
</v-select>
<v-data-table
:search="search"
:headers="headers"
:items="food"
:custom-filter="filterFoodUsingSearchbar"
>
data() {
return {
food: [
{ name: 'Bakchoi', type: 'vegetable', calories: 100 },
{ name: 'Pork', type: 'meat', calories: 200 },
{ name: 'Chicken Thigh', type: 'meat', calories: 300 },
{ name: 'Watermelon', type: 'fruit', calories: 10 },
],
headers: [
{ text: 'Name', align: 'left', value: 'name' },
{ text: 'Food Type', align: 'left', value: 'type' },
{ text: 'Calories', align: 'left', value: 'calories' },
],
search: '',
select: '',
};
},
methods: {
filterFoodUsingSearchbar(items, search, filter) {
// Condition
}
filterFoodUsingDropDown() {
if (this.select !== '') {
// In this case I use vuex to store the original data of the
food so that all the data is still exist even we filtered it out
this.food = this.$store.state.food.filter((item) => item.type === this.select)
}
}