i want to show a image in vuetify data table row. i tried this with below code.
<v-data-table :headers="headers" :items="desserts" :search="search" class="elevation-1">
<template slot="items" slot-scope="props">
<td>
<img :src="'/assets/img/' + props.item.name" style="width: 50px; height: 50px" />
</td>
<td class="text-xs-right">{{ props.item.calories }}</td>
<td class="text-xs-right">{{ props.item.fat }}</td>
<td class="text-xs-right">{{ props.item.carbs }}</td>
<td class="text-xs-right">{{ props.item.protein }}</td>
<td class="text-xs-right">{{ props.item.iron }}</td>
</template>
<template v-slot:item.action="{ item }">
<v-icon small class="mr-2" #click="editItem(item)">edit</v-icon>
<v-icon small #click="deleteItem(item)">delete</v-icon>
</template>
</v-data-table>
but this code not works properly. only shows data with v-data-table loop and template slot not working. my script like this.
search: "",
headers: [
{
text: "Images",
align: "left",
sortable: false,
value: "name"
},
{ text: "Calories", value: "calories" },
{ text: "Fat (g)", value: "fat" },
{ text: "Carbs (g)", value: "carbs" },
{ text: "Protein (g)", value: "protein" },
{ text: "Iron (%)", value: "iron" },
{ text: "Actions", value: "action", sortable: false }
],
desserts: [
{
value: false,
name: "notfound.png",
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: "1%"
}],
how can i show my image. this method only shows image text name only.
Presuming you use the last version of vuetify, the slots are working a little bit different, and you can define a slot only for the column you want to customize. (order is defined by the headers)
<div id="app">
<v-data-table :headers="headers" :items="desserts" class="elevation-1">
<template v-slot:item.name="{ item }">
<img :src="'/assets/img/' + item.name" style="width: 50px; height: 50px" />
</template>
<template v-slot:item.action="{ item }">
<v-icon small class="mr-2" #click="editItem(item)">edit</v-icon>
<v-icon small #click="deleteItem(item)">delete</v-icon>
</template>
</v-data-table>
</div>
Related
Expected Behavior: 1. On initial render, the component should auto open the corresponding v-list-item's subgroup. 2. Then, on clicking an adjacent subgroup item, the nav drawer should remain opened to the subgroup the user has click on.
Problem: When performing 2, the entire nav drawer will close rather than the expected behavior.
I still need to keep the :value v-binds, but I believe the problem has something to do with preventing the #activator from propagating v-on when clicking an item.
Oddity: Any subsequent clicks on nav drawer items will result in normal behavior after experiencing the initial problem.
Any help would be appreciated if you've come across this problem before. Thank you!
<template>
<div>
<v-app>
<v-list>
<v-list-group
v-for="(subObjects, fruit) in items"
:key="fruit"
:value="fruit === 'orange'"
no-action
>
<template #activator>
<v-list-item-title>
{{ fruit }}
</v-list-item-title>
</template>
<template>
<v-list-group
v-for="object in subObjects"
:key="object.name"
:value="object.name === 'navel'"
no-action
sub-group
>
<template #activator>
<v-list-item-content>
<v-list-item-title>
{{ object.name }}
</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="year in object.dates"
:key="year"
>
<template #activator="{ on, attrs }">
<v-list-item-title v-bind="attrs" v-on="on">
{{ year }}
</v-list-item-title>
</template>
</v-list-item>
</v-list-group>
</template>
</v-list-group>
</v-list>
</v-app>
</div>
</template>
<script>
export default {
data() {
return {
items: {
apples: {
0: {
color: 'red',
name: 'fuji',
dates: ['2016', '2018'],
},
1: {
color: 'green',
name: 'granny smith',
dates: ['2020', '2021'],
}
},
oranges: {
0: {
color: 'orange',
name: 'navel',
dates: ['2022']
},
1: {
color: 'red orange',
name: 'blood orange',
dates: ['2015', '2017'],
}
},
}
};
},
};
</script>
I have a vuetify data table, I've set width for every column and I want to fixed column's width of my table but it has grown up because of their content and it doesn't matter what is the width of them.
how can fixed column's width?
<template>
<v-data-table
v-if="physicianAccountsLocalData"
:headers="headers"
:items="physicianAccountsLocalData"
hide-default-footer
class="data-table"
:items-per-page="-1"
>
<template #[`item.isActive`]="props">
<BaseSwitch
v-model="props.item.isActive"
class="switch-siam-table"
#change="changeModel($event, props)"
/>
</template>
<template #[`item.location`]="props">
<span
class="location"
:class="{'text-disable-state': !props.item.isActive}"
>
{{ props.item.location }}
</span>
</template>
<template #[`item.name`]="props">
<span
class="name"
:class="{'text-disable-state': !props.item.isActive}"
>
{{ props.item.name }}
</span>
</template>
</v-data-table>
</template>
<script>
data() {
return {
headers: [
{ text: 'فعال', value: 'isActive', sortable: false, width: '110px', align: 'right' },
{ text: 'نوع', value: 'location', sortable: false, width: '13%', align: 'start' },
{ text: 'نام', value: 'name', sortable: false, width: '200px' }
],
}
}
</script>
i have a Vuetify data table with headers and data field respectively and in the props.item.name i have added a v-icon but i only wanna show that icon only when i hover over that respective field. By default it should not show up.
I have added the Code below with the script and HTML.
And here is a a pen
Any help will be appreciated on how to achieve that.
new Vue({
el: '#app',
data() {
return {
headers: [{
text: 'Dessert (100g serving)',
align: 'left',
sortable: false,
value: 'name'
},
{
text: 'Calories',
value: 'calories'
},
{
text: 'Fat (g)',
value: 'fat'
},
{
text: 'Carbs (g)',
value: 'carbs'
},
{
text: 'Protein (g)',
value: 'protein'
},
{
text: 'Iron (%)',
value: 'iron'
}
],
desserts: [{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%'
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%'
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%'
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%'
},
]
}
}
})
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.18/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.18/dist/vuetify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<v-app id="inspire">
<v-data-table :headers="headers" :items="desserts" class="elevation-1">
<template v-slot:items="props">
<td>{{ props.item.name }}
<v-icon right>cake</v-icon></td>
<td>{{ props.item.calories }}</td>
<td>{{ props.item.fat }}</td>
<td>{{ props.item.carbs }}</td>
<td>{{ props.item.protein }}</td>
<td>{{ props.item.iron }}</td>
</template>
</v-data-table>
</v-app>
</div>
Add a data property called for example c_index (current index) and when you hover over the row you assign the hovered index to c_index and reset it to -1 when the mouse the leaves it:
<tr #mouseover="c_index=props.index" #mouseleave="c_index=-1">
and show that icon conditionally like :
<v-icon right v-show="props.index==c_index">cake</v-icon>
Full Demo
Using a v-hover component, inside the v-slot:item.column_name of a data table, you can pass a prop through its v-slot, and used it like this:
<template v-slot:item.action="{ item }">
<v-hover v-slot:default="{ hover }">
<v-badge
:value="hover"
color="deep-purple accent-4"
content="First Button"
left
transition="slide-x-transition"
>
<v-icon>mdi-fountain-pen-tip</v-icon>
</v-badge>
</v-hover>
</template>
Also you can use the v-hover with the css, but you have to fix the position.
Full Demo
Your best option is CSS
_ On v-icon hover :
.v-data-table .v-icon{visibility:hidden}
.v-data-table .v-icon:hover{visibility:visible}
_ On td container hover
.v-data-table td .v-icon{visibility:hidden}
.v-data-table td:hover .v-icon:hover{visibility:visible}
This will affect all v-icons in your template, to be more precise add a class to the v-icons you want to hide.
...
<v-icon class="hidden" ... />
...
.hidden{visibility:hidden}
.hidden:hover{visibility:visible}
or
...
<td class="hidden" >
<v-icon ...>
...
</td>
...
.hidden .v-icon{visibility:hidden}
.hidden:hover .v-icon{visibility:visible}
I have an assignment that uses Vuetify and I want to render a table of "customer" data. My code worked fine with Vuetify 1.5, but now I am supposed to update to the newest version, which is 2.0.
The problem I'm running into is that my data is recognized by the program, but none of it actually shows up in the table. The exact number of rows are rendered to match my number of records, and Vue DevTools shows that my data is there, but The rendered html is just empty elements. I attached screenshots below to illustrate my point a little better:
The project can be found at: https://github.com/apalmesano2/assign3_frontend.git
Here is a snippet of what my Vue template for the list of customers:
CustomerList.vue
<template>
<main>
<br />
<v-container fluid grid-list-md>
<v-layout column align-left>
<blockquote>
Welcome {{validUserName}}!
<footer>
<small>
<em>—Eagle Financial Services, your Midwest Financial Services Partner.</em>
</small>
</footer>
</blockquote>
</v-layout>
<v-layout column align-center>
<v-flex xs6 sm8 md7>
<v-alert
v-if="showMsg === 'new'"
dismissible
:value="true"
type="success"
>New customer has been added.</v-alert>
<v-alert
v-if="showMsg === 'update'"
dismissible
:value="true"
type="success"
>Customer information has been updated.</v-alert>
<v-alert
v-if="showMsg === 'deleted'"
dismissible
:value="true"
type="success"
>Selected Customer has been deleted.</v-alert>
</v-flex>
</v-layout>
<br />
<v-container fluid grid-list-md fill-height>
<v-layout column>
<v-flex md6>
<v-data-table
:headers="headers"
:items="customers"
hide-default-footer
class="elevation-1"
fixed
style="max-height: 300px; overflow-y: auto"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.pk }}</td>
<td>{{ props.item.cust_number }}</td>
<td>{{ props.item.name }}</td>
<td nowrap="true">{{ props.item.address }}</td>
<td nowrap="true">{{ props.item.city }}</td>
<td nowrap="true">{{ props.item.state }}</td>
<td nowrap="true">{{ props.item.zipcode }}</td>
<td nowrap="true">{{ props.item.email }}</td>
<td nowrap="true">{{ props.item.cell_phone }}</td>
<td nowrap="true">
<v-icon #click="updateCustomer(props.item)">edit</v-icon>
</td>
<td nowrap="true">
<v-icon #click="deleteCustomer(props.item)">delete</v-icon>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-container>
<v-btn class="blue white--text" #click="addNewCustomer">Add Customer</v-btn>
</v-container>
</main>
</template>
And the script, although I don't think there is an issue here because the data is being fetched just fine according to the Vue DevTools:
<script>
import router from "../router";
import { APIService } from "../http/APIService";
const apiService = new APIService();
export default {
name: "CustomerList",
data: () => ({
customers: [],
validUserName: "Guest",
customerSize: 0,
showMsg: "",
headers: [
{ text: "Record Number", sortable: false, align: "left" },
{ text: "Customer Number", align: "left", sortable: false },
{ text: "Name", sortable: false, align: "left" },
{ text: "Address", sortable: false, align: "left" },
{ text: "City", sortable: false, align: "left" },
{ text: "State", sortable: false, align: "left" },
{ text: "ZipCode", sortable: false, align: "left" },
{ text: "Email", sortable: false, align: "left" },
{ text: "Phone", sortable: false, align: "left" },
{ text: "Update", sortable: false, align: "left" },
{ text: "Delete", sortable: false, align: "left" }
]
}),
mounted() {
this.getCustomers();
this.showMessages();
},
methods: {
showMessages() {
console.log(this.$route.params.msg);
if (this.$route.params.msg) {
this.showMsg = this.$route.params.msg;
}
},
getCustomers() {
apiService
.getCustomerList()
.then(response => {
this.customers = response.data.data;
this.customerSize = this.customers.length;
if (
localStorage.getItem("isAuthenticates") &&
JSON.parse(localStorage.getItem("isAuthenticates")) === true
) {
this.validUserName = JSON.parse(localStorage.getItem("log_user"));
}
})
.catch(error => {
if (error.response.status === 401) {
localStorage.removeItem("isAuthenticates");
localStorage.removeItem("log_user");
localStorage.removeItem("token");
router.push("/auth");
}
});
},
addNewCustomer() {
if (
localStorage.getItem("isAuthenticates") &&
JSON.parse(localStorage.getItem("isAuthenticates")) === true
) {
router.push("/customer-create");
} else {
router.push("/auth");
}
},
updateCustomer(customer) {
router.push("/customer-create/" + customer.pk);
},
deleteCustomer(customer) {
apiService
.deleteCustomer(customer.pk)
.then(response => {
if (response.status === 204) {
alert("Customer deleted");
this.showMsg = "deleted";
this.$router.go();
}
})
.catch(error => {
if (error.response.status === 401) {
localStorage.removeItem("isAuthenticates");
localStorage.removeItem("log_user");
localStorage.removeItem("token");
router.push("/auth");
}
});
}
}
};
</script>
I have a hunch I'm doing something wrong with my v-data-table and the template where I'm passing the props in but I can't figure out what's going wrong or how to fix it because even just hardcoded text in the tags won't render in the table.
To access the page where the screenshots are after cloning the project, you would need to log in with the following credentials:
Username: instructor
Password: instructor1a
Thanks to anyone who can help!
I figured out the new syntax after moving to vuetify v2:
<v-data-table
:headers="headers"
:items="stocks"
hide-default-footer
class="elevation-1"
fixed
style="max-height: 300px; overflow-y: auto"
>
<template v-slot:item="props">
<tr>
<td>{{ props.item.customer }}</td>
<td nowrap="true">{{ props.item.symbol }}</td>
<td nowrap="true">{{ props.item.name }}</td>
<td nowrap="true">{{ props.item.shares }}</td>
<td nowrap="true">{{ props.item.purchase_price }}</td>
<td nowrap="true">{{ props.item.purchase_date }}</td>
<td nowrap="true">
<v-icon #click="updateStock(props.item)">edit</v-icon>
</td>
<td nowrap="true">
<v-icon #click="deleteStock(props.item)">delete</v-icon>
</td>
</tr>
</template>
</v-data-table>
I encountered some troubles creating an accordion table. I created an Accordion component and a Table component. While independant from each other it works perfectly fine but I can't get any table appear into accordion.
//js part of accordion component
import Table from "../Table/index.vue"
export default {
name: 'accordion',
components: { Table },
mounted () {
},
data(){
return {
items: [
{ id: "mc", title: "Medical Checkup", text: this.components.Table },
{ id: "ac", title: "Application connected", text:
this.components.Table },
{ id: "p", title: "Programs", text: this.components.Table },
{ id: "pl", title: "Pain list", text: this.components.Table }
]
}
}
}
//html part of accordion component
<div>
<div ref="list" class="list">
<transition-group class="flip-list" name="flip-list" ref="tg1"
tag="div">
<div v-for="(item,index) in items" :key="item.id" class="item">
<slot name="item" :class="{active:item.isOpen}" :item="item"
:index="index">
<v-expansion-panel id="exp1">
<v-expansion-panel-content>
<div slot="header" class="drop-target handle2">
<span>{{item.title}}</span>
</div>
<v-card>
<v-card-text>
<div slot="item">{{Table}}</div>
</v-card-text>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
</slot>
</div>
</transition-group>
</div>
</div>
So, the point is : how can I make it so that a datatable appears into accordion ? Like when you click aon one of the titles and it appears instead of some text ?
Thanks a lot
Resolved!
In case of (if people encounter the same problem as I had), here is the code (html / js).
//html goes here
<div id="app">
<v-app id="inspire">
<v-data-table :headers="mainHeaders"
:items="mainItems"
item-key="title"
hide-actions
expand
class="elevation-1">
<template slot="items" scope="props">
<tr #click="props.expanded = !props.expanded">
<td class="text-xs">{{ props.item.title }}</td>
</tr>
</template>
<template slot="expand" scope="props">
<v-data-table :headers="subHeaders"
:items="subItems"
item-key="pain"
hide-actions
class="elevation-10">
<template slot="items" scope="props">
<td class="text-xs">{{ props.item.pain }}</td>
<td class="text-xs">{{ props.item.type }}</td>
</template>
</v-data-table>
</template>
</v-data-table> </v-app>
</div>
//js goes here
export default {
name: 'accordion-table',
mounted () {
},
data () {
return {
mainHeaders: [
{ text: 'Medical informations', value: 'title' }
],
mainItems: [
{ title: 'Medical Checkup' },
{ title: 'Application connected' },
{ title: 'Programs' },
{ title: 'Pain List' }
],
subHeaders: [
{ text: 'Pain', value: 'pain' },
{ text: 'Type', value: 'type' }
],
subItems: [
{ pain: 'Knee', type: '1' },
{ pain: 'Ankle', type: '2' },
{ pain: 'Back', type: '3' },
{ pain: 'Neck', type: '4' }
]
}
}
}
(I used random values)
Hope it helps some of you