Vuetify data tables search not working - vue.js

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)

Related

Make the content of the column align left in vue datatable

I have a datatable in my vue component.
Following is my header array.
HeaderArray() {
return [
{text: 'Document', value: 'document',classList: 'w-1/3'},
{text: 'Added by', value: 'added_user_name',classList: 'w-1/3'},
{text: 'Expiration', value: 'valid_date'},
{text: 'Validity', value: 'validity_status',classList: 'w-1/3', align:'start'},
{text: '', value: 'actions'},
];
},
Cell content of the Validity column is centered, But I want them to be align left.
Eventhough I triedalign:'start' the content display center...
How to make them align left?
Column header is aligned to left though...
By default column data in vue-data-table is left aligned. Hence, all the columns are already left aligned but if you want to make other columns are center aligned and validity as left aligned then you have to apply align: 'center' property in all the other column headers object instead of changing for validity column.
Demo :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{text: 'Document', value: 'document',classList: 'w-1/3', align:'center'},
{text: 'Added by', value: 'added_user_name',classList: 'w-1/3', align:'center'},
{text: 'Expiration', value: 'valid_date', align:'center'},
{text: 'Validity', value: 'validity_status',classList: 'w-1/3'},
{text: 'Actions', value: 'actions', align:'center'},
],
documentDetails: [
{
document: 'Document 1',
added_user_name: 'user 1',
valid_date: '04-12-2022',
validity_status: 'valid',
actions: 'Edit'
},
{
document: 'Document 2',
added_user_name: 'user 2',
valid_date: '05-12-2022',
validity_status: 'invalid',
actions: 'Edit'
}
],
}
},
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.css"/>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="documentDetails"
class="elevation-1"
></v-data-table>
</v-app>
</div>

Vue-i18n and v-select - can't translate

I have a problem to translate the information with vue i18n in my v-select. All others translation work but not this one... And i don't find a solution ...
HTML :
<v-card-text>
<v-select v-model="model" :items="propsList" :items-text="propsList.text" label="Select a reason:" clearable />
</v-card-text>
DATA eg : ($t = i18n)
propsList: [
{ text: this.$t('XXX.A') as string, value: 'X' },
{ text: this.$t('XXX.B') as string, value: 'Y' },
{ text: this.$t('XXX.C') as string, value: 'Z' },
],
Traduction :
{ "en": {
"XXX" : {
"A": "A", ...}},
"fr": {
"XXX" : {
"A": "A", ...}},
In my App.vue :
data ... :
languages: [
{ text: 'English', value: 'en' },
{ text: 'Français', value: 'fr' },
],
watch: {
language(val: string) {
this.setLanguage(val);
this.$i18n.locale = val;
},
},
I'm keep trying ! But thanks by advance :)
There is a prop called :get-option-label that is useful for i18n, that way you can just pass the i18n key in your option array:
<v-select :options="options" :get-option-label="option => $t(option.text)"></v-select>
Then options would look like this:
options = [
{ text: "XXX.A", value: 0 }
{ text: "XXX.B", value: 1 }
{ text: "XXX.C", value: 3 }
]
More details: https://vue-select.org/api/props.html#getoptionlabel
v-select doesn't have a prop named 'items-text' (items with s). You probably mean item-text (without s).
the prop item-text is used to specify the "path" where each item of your data has the text, it defaults to the string "text" which means the text of the item is found at the property "text"
if for example, you have the item with the structure:
{
value: 'some value',
name: 'John'
}
You should pass the string "name".
since you have your data with the text as text property, your template should look like this:
<v-card-text>
<v-select v-model="model" :items="propsList" label="Select a reason:" clearable />
</v-card-text>
Other options for this prop are:
An array of strings
Use this for nested properties, say for example you have your item's structure as follows:
{
value: 'whatever',
data: {
name: {
en: 'John'
}
}
}
you should pass ['data', 'name', 'en'], Vuetify will resolve the name.
A callback function
The callback function you pass will be called for each item and the item itself will be passed as a parameter, you should return whatever string you want to be displayed, this might be useful if you want to concatenate two properties of your items, e.g. first name and last name. or to display a prefix based on some value

How to display Checkbox in DataTable body Vuetify

I have a Vue application which is built using Vuetify and I want to create a table where cell content is a checkbox v-checkbox but it renders html string instead of checkbox inside table body.
I use v-data-table as a main table.
For illustration:
My Code:
<v-data-table :headers="headers"
:items="menuaccess"
:search="search"
sort-by="alias"
class="elevation-3"
v-html="value"> <--- I tried add this but not working
<!-- other code -->
Data source snippet (I will get data from API later) :
headers: [
{ text: '', align: 'start', value: 'alias' },
{ text: 'ASSET_EDIT', value: '<v-checkbox class="mx-2" label="Example"></v-checkbox>' },
{ text: 'ASSET_VERIFICATION', value: '<v-checkbox class="mx-2" label="Example"></v-checkbox>' },
{ text: 'ASSET_VIEW', value: '<v-checkbox class="mx-2" label="Example"></v-checkbox>' },
{ text: 'CUSTOMER_COMPANY_EDIT', value: '<v-checkbox class="mx-2" label="Example"></v-checkbox>' },
],
You need to place code inside slot template.
<v-data-table :headers="headers"
:items="menuaccess"
:search="search"
sort-by="alias"
class="elevation-3">
<template v-slot:item.property_name="{ item }">
<v-simple-checkbox v-model="item.property_name" />
</template>
</v-data-table>
Where property_name is name of the property on your data object.
Read more about it in the documentation.

How to combine an Expandable Table with an Expansion Panel in Vuetify?

I'd like to combine two separate Vuetify functionalities into one:
https://vuetifyjs.com/en/components/data-tables --> Expandable Rows Table (but ideally with more than one data row upon expansion)
https://vuetifyjs.com/en/components/expansion-panels --> External Control Expansion Panel
Ultimately, the goal is to have a table that looks like this (Grouping Table with expand/collapse all one): https://codepen.io/lzhoucs/pen/aadaJx
The issue with this table is that despite fitting the code into my project, certain functionalities don't work -- such as clicking to open and close a table. I believe this is due to this being a different version of Vue than what I'm using, which is the most up to date, as I spotted some old styles.
I've tried a bunch of things, but my most successful attempt is creating a table within a table. Here is the code for that:
<template>
<v-container>
<v-data-table
:headers="headers"
:items="projects"
:expanded="expanded"
item-key="name"
show-expand
class="elevation-1"
#click:row="clicked"
>
<template v-slot:expanded-item="{ headers }">
<td :colspan="headers.length">
<v-data-table
:headers="peopleHeaders"
:items="people"
item-key='name'
hide-default-footer
class='elevation-1'>
<template slot="item" slot-scope="props">
<tr>
<td>{{props.item.name}}</td>
<td>{{props.item.major}}</td>
<td>{{props.item.preference}}</td>
<td>
<v-btn color='success'>Accept</v-btn>
<v-btn color='error'>Reject</v-btn>
</td>
</tr>
</template>
</v-data-table>
</td>
</template>
</v-data-table>
</v-container>
</template>
<script>
export default {
data() {
return {
expanded: [],
headers: [
{
text: 'Name',
align: 'left',
sortable: true,
value: 'name',
},
{ text: 'Status', value: 'Status' },
],
projects: [
{
name: '#this is the project they applied to',
Status: 'Status: Pending',
},
],
peopleHeaders: [
{
text: 'Name',
align: 'left',
sortable: true,
value: 'name',
},
{
text: 'Major',
align: 'left',
sortable: true,
value: 'major',
},
{
text: 'Preference',
align: 'left',
sortable: true,
value: 'preference',
},
],
people: [
{
name: 'BORB',
major: 'SWE',
preference: 'idk',
},
],
};
},
methods: {
clicked(value) {
this.expanded.push(value);
},
},
};
</script>
Any advice for how to combine the two features to achieve the table desired would be greatly appreciated.

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?
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