Dynamically insert images into 'v-data-table' - vue.js

<v-data-table
:headers="headers"
:items="items"
:search="search"
hide-default-footer
class="elevation-1"
>
<template #[`item.employee_avatar`]="{ item }">
<v-img
:src="require('#/assets/img/img2.jpg')"
:alt="item.name"
style="width: 100px; height: 100px"
/>
</template>
</v-data-table>
The image with a fixed path is received, but I want to express the image with the image path of each object. I want to automatically follow the imgsrc path value of items.
export default {
data() {
return {
search: '',
loading: true,
headers: [
{
text: 'Avatar',
value: 'employee_avatar',
divider: true,
align: 'center',
sortable: false,
width: '100px',
},
{
text: 'myname',
align: 'center',
sortable: false,
value: 'name',
},
],
items: [
{
name: 'myname',
imgsrc: "#/assets/avatar.png",
},
The code below is the code I tried.
<template #[`item.employee_avatar`]="{ item }">
<v-img
:src="require(item.imgsrc)"
:alt="item.name"
style="width: 100px; height: 100px"
/>
</template>
There will be an error even if I fill out the above.
What's wrong with it? Help me...

You can use v-slot instead of #[item.employee_avatar]:
<template v-slot:item.employee_avatar="{ item }">
<v-img
:src="require(item.imgsrc)"
:alt="item.name"
style="width: 100px; height: 100px"
/>
</template>

Related

vuetity) How to put an image in a v-data-table

<v-data-table
:headers="headers"
:items="items"
:search="search"
:loading="loading"
loading-text="Loading... Please wait"
hide-default-footer
class="elevation-1"
>
<template slot="items">
<td>
<img :src="items.imgsrc" style="width: 50px; height: 50px" />
</td>
</template>
</v-data-table>
Between v-data-table tags
I think I should put in an image with slots, etc., but I don't know at all. I'm asking because I can't find the exact code no matter how hard I look.
The height in the 'v-img' tag seems to work, but the image doesn't come out.
<script>
export default {
data () {
return {
search: '',
headers: [
{
text: 'img',
align: 'start,
filterable: false,
value: 'imgsrc',
type: 'Image',
},
{
text: 'MyName',
align: 'start,
filterable: false,
value: 'name',
},
],
items: [
{
name: 'test1',
imgsrc: '#/assets/img/avatar.png',
},
{
name: 'test2',
imgsrc: '#/assets/img/avatar2.png',
},
],
}
},
}
</script>
Help me
The slot needs to be used like below
<v-data-table
:headers="headers"
:items="items"
:search="search"
:loading="loading"
loading-text="Loading... Please wait"
hide-default-footer
class="elevation-1"
>
<template v-slot:item.imgsrc="{ item }">
<td>
<img :src="require(item.imgsrc)" style="width: 50px; height: 50px">
</td>
</template>
</v-data-table>

Checkbox in a table using Quasar

Im trying to insert a checkbox column using quasar. The way I did, it only appears as the first element of the table, and I want it as the second element. How do I do this?
Example:
export default {
name: 'DespesasGeraisBKOOnline',
data() {
return{
columns: [
{
name: 'acoes',
label: 'Ações',
field: (row) => row.acoes,
sortable: true,
align: 'center',
},
{
name: 'pc',
align: 'center',
label: 'PC ',
sortable: false,
},
{
name: 'criada_em',
label: 'Criada em',
field: (row) => row.criada_em,
sortable: true,
align: 'center',
},
{
name: 'nome',
label: 'Nome',
field: (row) => row.nome,
sortable: true,
align: 'center',
},
}
}
<q-table
:data="data"
:columns="columns"
row-key="id"
selection="multiple"
class="default-table q-mt-xs"
>
<template v-slot:no-data="{}">
<div class="full-width row flex-center no-data-finded q-gutter-sm">
<span>
{{ loading ? 'Carregando...' : 'Nenhuma despesa encontrada.' }}
</span>
</div>
</template>
</q-table>
If you run the code, you can see that the first column is the "checkbox". However, I want this as the second column.
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="text" :props="props">{{ props.row.title }}</q-td>
<q-td key="radio" :props="props"><q-radio v-model="input" :label="props.row.label" /></q-td>
<q-td key="checkbox" :props="props"><q-checkbox v-model="input" :label="props.row.label" /></q-td>
<q-td key="button" :props="props"><q-btn label="btn" #click="method"/></q-td>
</q-tr>
</template>
This is the way i usually define table if i want to insert any form control peacefully within any column

Image not showing in Vuetify data table slot

I am trying to display images in a Vuetify data table column, but the image is not displaying in the desired slot, and only shows the URL of the image, e.g. "9384053.jpg". How do I display an image using slots in Vuetify?
Segment is an array containing image URLs such as 93034.jpg, 9348903.jpg etc. I am trying to display the first image only e.g. Segment[0] with a sample output of 846454.jpg.
<v-card>
<v-card-title>
Animals
<v-spacer></v-spacer>
</v-card-title>
<v-data-table
:headers="headers"
:items="entries"
:items-per-page="12"
class="elevation-3"
:multi-sort="true"
mobile-breakpoint
:search="search"
>
<template v-slot:item.Image="{ item }">
<img :src="require(`${item.Image}`)" style="width: 50px; height: 50px" />
</template>
</v-data-table>
</v-card>
Here is the script file
<script>
import firebase from '../firebaseConfig';
const db = firebase.database().ref('/');
export default {
name: 'Animals',
data: () => ({
search: '',
entries: [],
headers: [
{ text: 'ID', value: 'ID' },
{ text: 'RFID', value: 'RFID' },
{ text: 'Image', value: 'Segment[0]' },
{ text: 'Age', value: 'Age Years' },
{ text: 'Weight', value: 'Weight' },
],
}),
methods: {
readAnimals() {
db.once('value', (snapshot) => {
snapshot.forEach((doc) => {
const dataRetrieve = doc.val();
this.$data.entries.push({
ID: dataRetrieve.ID,
RFID: dataRetrieve.RFID,
'Age Years': dataRetrieve['Age Years']
Weight: dataRetrieve.Weight,
Length_History: dataRetrieve['Length_History'],
Length: dataRetrieve.Length,
Tag: dataRetrieve.Tag,
Head: dataRetrieve.Head,
Segment: dataRetrieve.Segment,
});
});
return this.$data.entries;
}).catch((error) => {
console.log('error getting documents', error);
});
},
},
mounted() {
this.readAnimals();
},
};
</script>
<template v-slot:item.Image="{ item }">
<img :src="item.Image" style="width: 50px; height: 50px" />
</template>
You should bind it this way I think.
This seems to do the trick
<template v-slot:item.Segment[0]="{item}">
<img :src="item.Segment[0]" style="width: 50px; height: 50px" />
</template>
https://imgur.com/a/LX7JKoy

Vue Overlay for specific card

I am using Vue with Vuetify and I used a for loop to render 8 different cards. Each card has its own overlay which shows its own image when clicked, however when I click one card, all of the overlays get set off instead of the overlay for just the specific card. How should I go about doing this? Would I have to add an ID for each card?
<script>
export default {
data: () => ({
arts: [
require("#/assets/art1.jpg"),
require("#/assets/art2.jpg"),
require("#/assets/art3.jpg"),
require("#/assets/art4.jpeg"),
require("#/assets/art5.jpg"),
require("#/assets/art6.jpg"),
require("#/assets/art7.jpg"),
require("#/assets/art8.jpg")
],
absolute: true,
opacity: 1,
overlay: false,
})
};
</script>
<template>
<div style="width: 100%; height: 100%">
<v-container fluid style="height:100%; background-color:#fc8276; width:25%; float:left"></v-container>
<v-container style=" height: 100%; width: 75%; float:right" fluid>
<h1>Portfolio</h1>
<v-card
v-for="art in arts"
class="ma-5"
v-bind:key="art"
style="width: 15em; height: 15em; display:inline-flex"
>
<v-img :src="art" v-on:click="overlay=true"></v-img>
<v-overlay :absolute="absolute" :opacity="opacity" :value="overlay">
{{art}}
</v-overlay>
</v-card>
</v-container>
</div>
</template>
This is untested, but something like this should work... basically restructure your data a bit. Right now you have one overlay data boolean. Whenever you are setting this to true, you are setting it to true for everything that is using that same boolean... in your case all of your overlayables are looking at that same boolean.
Also I would recommend moving your styles into CSS classes, it will make this way more readable...
You need to update your HTML to this:
<template>
<div style="width: 100%; height: 100%">
<v-container fluid style="height:100%; background-color:#fc8276; width:25%; float:left"></v-container>
<v-container style=" height: 100%; width: 75%; float:right" fluid>
<h1>Portfolio</h1>
<v-card
v-for="(art, index) in arts"
class="ma-5"
v-bind:key="index"
style="width: 15em; height: 15em; display:inline-flex"
>
<v-img :src="art" v-on:click="showOverlay(art, index)"></v-img>
<v-overlay :absolute="absolute" :opacity="opacity" :value="art.overlay">
{{art.asset}}
</v-overlay>
</v-card>
</v-container>
</div>
</template>
Then change your data a bit:
data: () => ({
arts: [
{ asset: require("#/assets/art1.jpg"), overlay: false },
{ asset: require("#/assets/art2.jpg"), overlay: false },
{ asset: require("#/assets/art3.jpg"), overlay: false },
{ asset: require("#/assets/art4.jpeg"), overlay: false },
{ asset: require("#/assets/art5.jpg"), overlay: false },
{ asset: require("#/assets/art6.jpg"), overlay: false },
{ asset: require("#/assets/art7.jpg"), overlay: false },
{ asset: require("#/assets/art8.jpg"), overlay: false }
],
absolute: true,
opacity: 1,
})
Then in your methods:
methods: {
showOverlay(art, index) {
this.arts.map((a) => a.overlay = false);
this.arts[index].overlay = true;
}
}
I would make a new component which holds the v-card, so each one would have its own overlay data property. But having it all in one component with arts.length overlay variables works as well

How to target specific vue table element?

I'm setting up a list that fetches from a database and displays a list of orders. onclick of the button, I would like to show the stars-rating div only in the row it was clicked on. How do I make a vue button trigger the appearance of a div only in the row that it is in.
I've tried using v-on:click= function to call another function in js but didn't seem to work. Here both templates are contained in
<div id="wrapper">
<v-toolbar flat color="white">
<v-toolbar-title style="font-family: 'Raleway', sans-serif;">Order
History</v-toolbar-title>
<v-spacer></v-spacer>
<d style="margin-right:20px;color:#a7a7a7;font-family: 'Raleway',
sans-serif;">click on an order for more information</d>
</v-toolbar>
<v-data-table
:headers="headers"
:items="orders"
:expand="expand"
item-key="number"
>
<template v-slot:items="props">
<tr #click="props.expanded = !props.expanded">
<!--trigger using this button--> <td class="text-xs-left" style='font-
weight:400;'><v-btn v-on:click="greet"
class="dark">{{ props.item.review }}</v-btn>
</td>
</tr>
</template>
<template v-slot:expand="props" style="font-
weight:500">
<v-data-table
:items="[props.item]"
:expand="expand"
item-key="name"
hide-actions
>
<template v-slot:headers="props">
</template>
<template v-slot:items="props">
<td width="15%" class="text-xs-left"
style='font-weight:300;'>
<!--trigger this div --> <div class="star-rating"></div>
</td>
</template>
</v-data-table>
</template>
</v-data-table>
</div>
//JS
var v = new Vue({
el: '#app',
methods: {
greet: function () {
$(".stars-rating").hide();
}
},
data() {
return {
expand: true,
headers: [
{
text: 'Order Number',
align: 'left',
sortable: false,
value: 'number',
width: '10%' },
{ text: 'Name/Message', value: 'name',
align: 'left',
width: '15%' },
{ text: 'Date/Start', value: 'date',
align: 'left',
width: '10%' },
{ text: 'Time/End', value: 'time',
align: 'left',
width: '10%' },
{ text: 'Provider/Receipts', value: 'provider',
align: 'left',
width: '10%' },
{ text: 'Amount/Labor', value: 'amount',
align: 'left',
width: '15%' },
{ text: 'Status/Tracking', value: 'status',
align: 'left',
width: '15%' },
{ text: 'Confirmation/Review', value: 'review',
align: 'left',
width: '15%' }],
orders: [],
};
} });
have you tried with
<div class="star-rating" v-if="props.expanded"></div>
First of all, you should remove the #click from your <tr #click="props.expanded = !props.expanded"> element.
In your greet function, you have to change the expand flag, something like:
greet: function () {
this.expand = false
}
As you are already biding the expand state with the v-data-table expand prop, it should work
<v-data-table
:headers="headers"
:items="orders"
:expand="expand"
item-key="number"
>